From 1ba91d5a0e1df7419a561f6dcf16a0839509a5e7 Mon Sep 17 00:00:00 2001
From: k-m_schindler
Date: Wed, 27 Aug 2008 13:28:57 +0000
Subject: Reordering of the directories[1]: moving Game/Code to src
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1302 b956fd51-792f-4845-bead-9b4dfca2ff2c
---
Game/Code/Classes/TextGL.pas | 462 -
Game/Code/Classes/UAudioConverter.pas | 458 -
Game/Code/Classes/UAudioCore_Bass.pas | 123 -
Game/Code/Classes/UAudioCore_Portaudio.pas | 257 -
Game/Code/Classes/UAudioDecoder_Bass.pas | 242 -
Game/Code/Classes/UAudioDecoder_FFmpeg.pas | 1114 ---
Game/Code/Classes/UAudioInput_Bass.pas | 481 -
Game/Code/Classes/UAudioInput_Portaudio.pas | 474 -
Game/Code/Classes/UAudioPlaybackBase.pas | 292 -
Game/Code/Classes/UAudioPlayback_Bass.pas | 731 --
Game/Code/Classes/UAudioPlayback_Portaudio.pas | 361 -
Game/Code/Classes/UAudioPlayback_SDL.pas | 160 -
Game/Code/Classes/UAudioPlayback_SoftMixer.pas | 1132 ---
Game/Code/Classes/UCatCovers.pas | 173 -
Game/Code/Classes/UCommandLine.pas | 339 -
Game/Code/Classes/UCommon.pas | 774 --
Game/Code/Classes/UConfig.pas | 199 -
Game/Code/Classes/UCore.pas | 525 --
Game/Code/Classes/UCoreModule.pas | 128 -
Game/Code/Classes/UCovers.pas | 430 -
Game/Code/Classes/UDLLManager.pas | 253 -
Game/Code/Classes/UDataBase.pas | 533 --
Game/Code/Classes/UDraw.pas | 1390 ---
Game/Code/Classes/UEditorLyrics.pas | 229 -
Game/Code/Classes/UFiles.pas | 150 -
Game/Code/Classes/UGraphic.pas | 760 --
Game/Code/Classes/UGraphicClasses.pas | 673 --
Game/Code/Classes/UHooks.pas | 434 -
Game/Code/Classes/UImage.pas | 993 --
Game/Code/Classes/UIni.pas | 928 --
Game/Code/Classes/UJoystick.pas | 282 -
Game/Code/Classes/ULCD.pas | 304 -
Game/Code/Classes/ULanguage.pas | 240 -
Game/Code/Classes/ULight.pas | 145 -
Game/Code/Classes/ULog.pas | 417 -
Game/Code/Classes/ULyrics.pas | 884 --
Game/Code/Classes/UMain.pas | 1107 ---
Game/Code/Classes/UMediaCore_FFmpeg.pas | 405 -
Game/Code/Classes/UMediaCore_SDL.pas | 38 -
Game/Code/Classes/UMedia_dummy.pas | 243 -
Game/Code/Classes/UModules.pas | 26 -
Game/Code/Classes/UMusic.pas | 1233 ---
Game/Code/Classes/UParty.pas | 630 --
Game/Code/Classes/UPlatform.pas | 165 -
Game/Code/Classes/UPlatformLinux.pas | 160 -
Game/Code/Classes/UPlatformMacOSX.pas | 294 -
Game/Code/Classes/UPlatformWindows.pas | 236 -
Game/Code/Classes/UPlaylist.pas | 490 -
Game/Code/Classes/UPluginInterface.pas | 156 -
Game/Code/Classes/URecord.pas | 766 --
Game/Code/Classes/URingBuffer.pas | 128 -
Game/Code/Classes/UServices.pas | 358 -
Game/Code/Classes/USingNotes.pas | 13 -
Game/Code/Classes/USingScores.pas | 973 --
Game/Code/Classes/USkins.pas | 185 -
Game/Code/Classes/USong.pas | 1027 ---
Game/Code/Classes/USongs.pas | 806 --
Game/Code/Classes/UTextClasses.pas | 60 -
Game/Code/Classes/UTexture.pas | 525 --
Game/Code/Classes/UThemes.pas | 2234 -----
Game/Code/Classes/UTime.pas | 185 -
Game/Code/Classes/UVideo.pas | 828 --
Game/Code/Classes/UVisualizer.pas | 442 -
Game/Code/Classes/UXMLSong.pas | 573 --
Game/Code/Classes/uPluginLoader.pas | 775 --
Game/Code/MacOSX/English.lproj/InfoPlist.strings | Bin 532 -> 0 bytes
.../MacOSX/English.lproj/SDLMain.nib/classes.nib | 19 -
.../Code/MacOSX/English.lproj/SDLMain.nib/info.nib | 21 -
.../MacOSX/English.lproj/SDLMain.nib/objects.nib | Bin 2590 -> 0 bytes
Game/Code/MacOSX/Info.plist | 40 -
Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1 | 1408 ---
.../MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 | 1740 ----
.../MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser | 1414 ---
.../MacOSX/UltraStarDX.xcodeproj/project.pbxproj | 1613 ----
Game/Code/MacOSX/Wrapper/MacResources.pas | 124 -
Game/Code/MacOSX/Wrapper/PseudoThread.pas | 48 -
Game/Code/MacOSX/Wrapper/Windows.pas | 167 -
Game/Code/Makefile.in | 393 -
Game/Code/Menu/UDisplay.pas | 383 -
Game/Code/Menu/UDrawTexture.pas | 105 -
Game/Code/Menu/UMenu.pas | 1432 ---
Game/Code/Menu/UMenuButton.pas | 564 --
Game/Code/Menu/UMenuButtonCollection.pas | 71 -
Game/Code/Menu/UMenuInteract.pas | 16 -
Game/Code/Menu/UMenuSelectSlide.pas | 355 -
Game/Code/Menu/UMenuStatic.pas | 85 -
Game/Code/Menu/UMenuText.pas | 350 -
Game/Code/Screens/UScreenCredits.pas | 1398 ---
Game/Code/Screens/UScreenEdit.pas | 121 -
Game/Code/Screens/UScreenEditConvert.pas | 584 --
Game/Code/Screens/UScreenEditHeader.pas | 380 -
Game/Code/Screens/UScreenEditSub.pas | 1368 ---
Game/Code/Screens/UScreenLevel.pas | 103 -
Game/Code/Screens/UScreenLoading.pas | 57 -
Game/Code/Screens/UScreenMain.pas | 256 -
Game/Code/Screens/UScreenName.pas | 243 -
Game/Code/Screens/UScreenOpen.pas | 173 -
Game/Code/Screens/UScreenOptions.pas | 196 -
Game/Code/Screens/UScreenOptionsAdvanced.pas | 113 -
Game/Code/Screens/UScreenOptionsGame.pas | 117 -
Game/Code/Screens/UScreenOptionsGraphics.pas | 113 -
Game/Code/Screens/UScreenOptionsLyrics.pas | 103 -
Game/Code/Screens/UScreenOptionsRecord.pas | 785 --
Game/Code/Screens/UScreenOptionsSound.pas | 133 -
Game/Code/Screens/UScreenOptionsThemes.pas | 171 -
Game/Code/Screens/UScreenPartyNewRound.pas | 439 -
Game/Code/Screens/UScreenPartyOptions.pas | 279 -
Game/Code/Screens/UScreenPartyPlayer.pas | 340 -
Game/Code/Screens/UScreenPartyScore.pas | 302 -
Game/Code/Screens/UScreenPartyWin.pas | 267 -
Game/Code/Screens/UScreenPopup.pas | 252 -
Game/Code/Screens/UScreenScore.pas | 848 --
Game/Code/Screens/UScreenSing.pas | 934 --
Game/Code/Screens/UScreenSingModi.pas | 707 --
Game/Code/Screens/UScreenSong.pas | 2019 -----
Game/Code/Screens/UScreenSongJumpto.pas | 212 -
Game/Code/Screens/UScreenSongMenu.pas | 641 --
Game/Code/Screens/UScreenStatDetail.pas | 270 -
Game/Code/Screens/UScreenStatMain.pas | 301 -
Game/Code/Screens/UScreenTop5.pas | 175 -
Game/Code/Screens/UScreenWelcome.pas | 122 -
Game/Code/UltraStar-linux.lpi | 82 -
Game/Code/UltraStar.dpr | 294 -
Game/Code/UltraStar.lpi | 598 --
Game/Code/UltraStar.lpr | 19 -
Game/Code/UltraStar.rc | 38 -
Game/Code/UnitTests/switches.inc | 0
Game/Code/UnitTests/test_libraries.lpi | 299 -
Game/Code/UnitTests/test_libraries.lpr | 31 -
Game/Code/UnitTests/testsqllite.pas | 84 -
Game/Code/autogen.sh | 1 -
Game/Code/bamboo-build-lin-laz.bat | 4 -
Game/Code/bamboo-build-lin-laz.sh | 6 -
Game/Code/bamboo-build-win-delphi.bat | 9 -
Game/Code/bamboo-build-win-laz.bat | 3 -
Game/Code/build.bat | 4 -
Game/Code/clean.bat | 7 -
Game/Code/config-darwin.inc | 59 -
Game/Code/config-win.inc | 56 -
Game/Code/config.inc.in | 58 -
Game/Code/configure.ac | 494 -
Game/Code/developer_changelog.txt | 10 -
Game/Code/install-sh | 519 --
Game/Code/lazres-UltraStar.bat | 2 -
Game/Code/lib/FreeImage/FreeBitmap.pas | 1742 ----
Game/Code/lib/FreeImage/FreeImage.pas | 773 --
Game/Code/lib/JEDI-SDL/JEDI-SDL-README.txt | 244 -
Game/Code/lib/JEDI-SDL/OpenGL-Set8087CW.patch | 16 -
Game/Code/lib/JEDI-SDL/OpenGL/Pas/geometry.pas | 1994 ----
Game/Code/lib/JEDI-SDL/OpenGL/Pas/gl.pas | 2301 -----
Game/Code/lib/JEDI-SDL/OpenGL/Pas/glext.pas | 9578 --------------------
Game/Code/lib/JEDI-SDL/OpenGL/Pas/glu.pas | 582 --
Game/Code/lib/JEDI-SDL/OpenGL/Pas/glut.pas | 688 --
Game/Code/lib/JEDI-SDL/OpenGL/Pas/glx.pas | 280 -
Game/Code/lib/JEDI-SDL/SDL/Pas/Readme.txt | 27 -
Game/Code/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc | 438 -
Game/Code/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas | 2688 ------
Game/Code/lib/JEDI-SDL/SDL/Pas/logger.pas | 189 -
Game/Code/lib/JEDI-SDL/SDL/Pas/moduleloader.pas | 320 -
.../JEDI-SDL/SDL/Pas/registryuserpreferences.pas | 229 -
Game/Code/lib/JEDI-SDL/SDL/Pas/sdl.pas | 4332 ---------
Game/Code/lib/JEDI-SDL/SDL/Pas/sdl_cpuinfo.pas | 155 -
.../Code/lib/JEDI-SDL/SDL/Pas/sdlgameinterface.pas | 202 -
Game/Code/lib/JEDI-SDL/SDL/Pas/sdli386utils.pas | 5236 -----------
Game/Code/lib/JEDI-SDL/SDL/Pas/sdlinput.pas | 923 --
Game/Code/lib/JEDI-SDL/SDL/Pas/sdlstreams.pas | 216 -
Game/Code/lib/JEDI-SDL/SDL/Pas/sdlticks.pas | 197 -
Game/Code/lib/JEDI-SDL/SDL/Pas/sdlutils.pas | 4363 ---------
Game/Code/lib/JEDI-SDL/SDL/Pas/sdlwindow.pas | 566 --
Game/Code/lib/JEDI-SDL/SDL/Pas/userpreferences.pas | 159 -
Game/Code/lib/JEDI-SDL/SDL_Image/Pas/sdl_image.pas | 350 -
Game/Code/lib/JEDI-SDL/SDL_ttf/Pas/sdl_ttf.pas | 506 --
.../lib/JEDI-SDL/SDL_ttf/Pas/sdltruetypefont.pas | 565 --
Game/Code/lib/JEDI-SDL/fpc-install.sh | 252 -
Game/Code/lib/JEDI-SDL/jedi-sdl-64bit.patch | 1280 ---
Game/Code/lib/JEDI-SDL/moduleloader-libc.patch | 25 -
Game/Code/lib/SQLite/SQLite3.pas | 255 -
Game/Code/lib/SQLite/SQLiteTable3.pas | 1446 ---
Game/Code/lib/SQLite/example/Sunset.jpg | Bin 71189 -> 0 bytes
Game/Code/lib/SQLite/example/TestSqlite.dpr | 15 -
Game/Code/lib/SQLite/example/TestSqlite.res | Bin 876 -> 0 bytes
Game/Code/lib/SQLite/example/uTestSqlite.dfm | 110 -
Game/Code/lib/SQLite/example/uTestSqlite.pas | 233 -
Game/Code/lib/SQLite/readme.txt | 93 -
Game/Code/lib/bass/bass.chm | Bin 210668 -> 0 bytes
Game/Code/lib/bass/bass.txt | 1658 ----
Game/Code/lib/bass/delphi/bass-macosx.patch | 368 -
Game/Code/lib/bass/delphi/bass.pas | 865 --
Game/Code/lib/ctypes/ctypes.pas | 72 -
Game/Code/lib/ffmpeg/avcodec.pas | 3350 -------
Game/Code/lib/ffmpeg/avformat.pas | 1372 ---
Game/Code/lib/ffmpeg/avio.pas | 538 --
Game/Code/lib/ffmpeg/avutil.pas | 320 -
Game/Code/lib/ffmpeg/mathematics.pas | 81 -
Game/Code/lib/ffmpeg/opt.pas | 198 -
Game/Code/lib/ffmpeg/rational.pas | 153 -
Game/Code/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt | 23 -
Game/Code/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh | 6 -
.../lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh | 23 -
Game/Code/lib/ffmpeg/swscale.pas | 202 -
Game/Code/lib/fft/UFFT.pas | 600 --
Game/Code/lib/libpng/png.pas | 974 --
Game/Code/lib/midi/CIRCBUF.PAS | 183 -
Game/Code/lib/midi/DELPHMCB.PAS | 140 -
Game/Code/lib/midi/MIDIDEFS.PAS | 55 -
Game/Code/lib/midi/MIDITYPE.PAS | 90 -
Game/Code/lib/midi/MidiFile.pas | 970 --
Game/Code/lib/midi/MidiScope.pas | 198 -
Game/Code/lib/midi/Midicons.pas | 47 -
Game/Code/lib/midi/Midiin.pas | 727 --
Game/Code/lib/midi/Midiout.pas | 619 --
Game/Code/lib/midi/demo/MidiTest.dfm | Bin 1872 -> 0 bytes
Game/Code/lib/midi/demo/MidiTest.pas | 249 -
Game/Code/lib/midi/demo/Project1.dpr | 13 -
Game/Code/lib/midi/demo/Project1.res | Bin 876 -> 0 bytes
Game/Code/lib/midi/midiComp.cfg | 35 -
Game/Code/lib/midi/midiComp.dpk | 45 -
Game/Code/lib/midi/midiComp.res | Bin 876 -> 0 bytes
Game/Code/lib/midi/readme.txt | 60 -
Game/Code/lib/other/DirWatch.pas | 345 -
Game/Code/lib/other/WinAllocation.pas | 97 -
Game/Code/lib/portaudio/delphi/portaudio.pas | 1162 ---
Game/Code/lib/portmixer/delphi/portmixer.pas | 151 -
Game/Code/lib/projectM/cwrapper/Makefile.in | 30 -
.../lib/projectM/cwrapper/projectM-cwrapper.cpp | 104 -
.../Code/lib/projectM/cwrapper/projectM-cwrapper.h | 67 -
.../lib/projectM/cwrapper/projectM-cwrapper.sln | 20 -
.../lib/projectM/cwrapper/projectM-cwrapper.vcproj | 208 -
Game/Code/lib/projectM/projectM-0_9.inc | 427 -
Game/Code/lib/projectM/projectM-1_0.inc | 188 -
Game/Code/lib/projectM/projectM.pas | 232 -
Game/Code/lib/requirements.txt | 39 -
Game/Code/lib/samplerate/samplerate.pas | 199 -
Game/Code/lib/zlib/zlib.pas | 215 -
Game/Code/m4/ac_define_dir.m4 | 47 -
Game/Code/m4/fpc.m4 | 176 -
Game/Code/package_debian.sh | 32 -
Game/Code/rccompile-delphi.bat | 1 -
Game/Code/rccompile-fpc.bat | 3 -
Game/Code/switches.inc | 111 -
Game/Code/ultrastardx.control | 19 -
Game/Code/ultrastardx.desktop | 17 -
src/Classes/TextGL.pas | 462 +
src/Classes/UAudioConverter.pas | 458 +
src/Classes/UAudioCore_Bass.pas | 123 +
src/Classes/UAudioCore_Portaudio.pas | 257 +
src/Classes/UAudioDecoder_Bass.pas | 242 +
src/Classes/UAudioDecoder_FFmpeg.pas | 1114 +++
src/Classes/UAudioInput_Bass.pas | 481 +
src/Classes/UAudioInput_Portaudio.pas | 474 +
src/Classes/UAudioPlaybackBase.pas | 292 +
src/Classes/UAudioPlayback_Bass.pas | 731 ++
src/Classes/UAudioPlayback_Portaudio.pas | 361 +
src/Classes/UAudioPlayback_SDL.pas | 160 +
src/Classes/UAudioPlayback_SoftMixer.pas | 1132 +++
src/Classes/UCatCovers.pas | 173 +
src/Classes/UCommandLine.pas | 339 +
src/Classes/UCommon.pas | 774 ++
src/Classes/UConfig.pas | 199 +
src/Classes/UCore.pas | 525 ++
src/Classes/UCoreModule.pas | 128 +
src/Classes/UCovers.pas | 430 +
src/Classes/UDLLManager.pas | 253 +
src/Classes/UDataBase.pas | 533 ++
src/Classes/UDraw.pas | 1390 +++
src/Classes/UEditorLyrics.pas | 229 +
src/Classes/UFiles.pas | 150 +
src/Classes/UGraphic.pas | 760 ++
src/Classes/UGraphicClasses.pas | 673 ++
src/Classes/UHooks.pas | 434 +
src/Classes/UImage.pas | 993 ++
src/Classes/UIni.pas | 928 ++
src/Classes/UJoystick.pas | 282 +
src/Classes/ULCD.pas | 304 +
src/Classes/ULanguage.pas | 240 +
src/Classes/ULight.pas | 145 +
src/Classes/ULog.pas | 417 +
src/Classes/ULyrics.pas | 884 ++
src/Classes/UMain.pas | 1107 +++
src/Classes/UMediaCore_FFmpeg.pas | 405 +
src/Classes/UMediaCore_SDL.pas | 38 +
src/Classes/UMedia_dummy.pas | 243 +
src/Classes/UModules.pas | 26 +
src/Classes/UMusic.pas | 1233 +++
src/Classes/UParty.pas | 630 ++
src/Classes/UPlatform.pas | 165 +
src/Classes/UPlatformLinux.pas | 160 +
src/Classes/UPlatformMacOSX.pas | 294 +
src/Classes/UPlatformWindows.pas | 236 +
src/Classes/UPlaylist.pas | 490 +
src/Classes/UPluginInterface.pas | 156 +
src/Classes/URecord.pas | 766 ++
src/Classes/URingBuffer.pas | 128 +
src/Classes/UServices.pas | 358 +
src/Classes/USingNotes.pas | 13 +
src/Classes/USingScores.pas | 973 ++
src/Classes/USkins.pas | 185 +
src/Classes/USong.pas | 1027 +++
src/Classes/USongs.pas | 806 ++
src/Classes/UTextClasses.pas | 60 +
src/Classes/UTexture.pas | 525 ++
src/Classes/UThemes.pas | 2234 +++++
src/Classes/UTime.pas | 185 +
src/Classes/UVideo.pas | 828 ++
src/Classes/UVisualizer.pas | 442 +
src/Classes/UXMLSong.pas | 573 ++
src/Classes/uPluginLoader.pas | 775 ++
src/MacOSX/English.lproj/InfoPlist.strings | Bin 0 -> 532 bytes
src/MacOSX/English.lproj/SDLMain.nib/classes.nib | 19 +
src/MacOSX/English.lproj/SDLMain.nib/info.nib | 21 +
src/MacOSX/English.lproj/SDLMain.nib/objects.nib | Bin 0 -> 2590 bytes
src/MacOSX/Info.plist | 40 +
src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1 | 1408 +++
src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 | 1740 ++++
src/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser | 1414 +++
src/MacOSX/UltraStarDX.xcodeproj/project.pbxproj | 1613 ++++
src/MacOSX/Wrapper/MacResources.pas | 124 +
src/MacOSX/Wrapper/PseudoThread.pas | 48 +
src/MacOSX/Wrapper/Windows.pas | 167 +
src/Makefile.in | 393 +
src/Menu/UDisplay.pas | 383 +
src/Menu/UDrawTexture.pas | 105 +
src/Menu/UMenu.pas | 1432 +++
src/Menu/UMenuButton.pas | 564 ++
src/Menu/UMenuButtonCollection.pas | 71 +
src/Menu/UMenuInteract.pas | 16 +
src/Menu/UMenuSelectSlide.pas | 355 +
src/Menu/UMenuStatic.pas | 85 +
src/Menu/UMenuText.pas | 350 +
src/Screens/UScreenCredits.pas | 1398 +++
src/Screens/UScreenEdit.pas | 121 +
src/Screens/UScreenEditConvert.pas | 584 ++
src/Screens/UScreenEditHeader.pas | 380 +
src/Screens/UScreenEditSub.pas | 1368 +++
src/Screens/UScreenLevel.pas | 103 +
src/Screens/UScreenLoading.pas | 57 +
src/Screens/UScreenMain.pas | 256 +
src/Screens/UScreenName.pas | 243 +
src/Screens/UScreenOpen.pas | 173 +
src/Screens/UScreenOptions.pas | 196 +
src/Screens/UScreenOptionsAdvanced.pas | 113 +
src/Screens/UScreenOptionsGame.pas | 117 +
src/Screens/UScreenOptionsGraphics.pas | 113 +
src/Screens/UScreenOptionsLyrics.pas | 103 +
src/Screens/UScreenOptionsRecord.pas | 785 ++
src/Screens/UScreenOptionsSound.pas | 133 +
src/Screens/UScreenOptionsThemes.pas | 171 +
src/Screens/UScreenPartyNewRound.pas | 439 +
src/Screens/UScreenPartyOptions.pas | 279 +
src/Screens/UScreenPartyPlayer.pas | 340 +
src/Screens/UScreenPartyScore.pas | 302 +
src/Screens/UScreenPartyWin.pas | 267 +
src/Screens/UScreenPopup.pas | 252 +
src/Screens/UScreenScore.pas | 848 ++
src/Screens/UScreenSing.pas | 934 ++
src/Screens/UScreenSingModi.pas | 707 ++
src/Screens/UScreenSong.pas | 2019 +++++
src/Screens/UScreenSongJumpto.pas | 212 +
src/Screens/UScreenSongMenu.pas | 641 ++
src/Screens/UScreenStatDetail.pas | 270 +
src/Screens/UScreenStatMain.pas | 301 +
src/Screens/UScreenTop5.pas | 175 +
src/Screens/UScreenWelcome.pas | 122 +
src/UltraStar-linux.lpi | 82 +
src/UltraStar.dpr | 294 +
src/UltraStar.lpi | 598 ++
src/UltraStar.lpr | 19 +
src/UltraStar.rc | 38 +
src/UnitTests/switches.inc | 0
src/UnitTests/test_libraries.lpi | 299 +
src/UnitTests/test_libraries.lpr | 31 +
src/UnitTests/testsqllite.pas | 84 +
src/autogen.sh | 1 +
src/bamboo-build-lin-laz.bat | 4 +
src/bamboo-build-lin-laz.sh | 6 +
src/bamboo-build-win-delphi.bat | 9 +
src/bamboo-build-win-laz.bat | 3 +
src/build.bat | 4 +
src/clean.bat | 7 +
src/config-darwin.inc | 59 +
src/config-win.inc | 56 +
src/config.inc.in | 58 +
src/configure.ac | 494 +
src/developer_changelog.txt | 10 +
src/install-sh | 519 ++
src/lazres-UltraStar.bat | 2 +
src/lib/FreeImage/FreeBitmap.pas | 1742 ++++
src/lib/FreeImage/FreeImage.pas | 773 ++
src/lib/JEDI-SDL/JEDI-SDL-README.txt | 244 +
src/lib/JEDI-SDL/OpenGL-Set8087CW.patch | 16 +
src/lib/JEDI-SDL/OpenGL/Pas/geometry.pas | 1994 ++++
src/lib/JEDI-SDL/OpenGL/Pas/gl.pas | 2301 +++++
src/lib/JEDI-SDL/OpenGL/Pas/glext.pas | 9578 ++++++++++++++++++++
src/lib/JEDI-SDL/OpenGL/Pas/glu.pas | 582 ++
src/lib/JEDI-SDL/OpenGL/Pas/glut.pas | 688 ++
src/lib/JEDI-SDL/OpenGL/Pas/glx.pas | 280 +
src/lib/JEDI-SDL/SDL/Pas/Readme.txt | 27 +
src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc | 438 +
src/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas | 2688 ++++++
src/lib/JEDI-SDL/SDL/Pas/logger.pas | 189 +
src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas | 320 +
.../JEDI-SDL/SDL/Pas/registryuserpreferences.pas | 229 +
src/lib/JEDI-SDL/SDL/Pas/sdl.pas | 4332 +++++++++
src/lib/JEDI-SDL/SDL/Pas/sdl_cpuinfo.pas | 155 +
src/lib/JEDI-SDL/SDL/Pas/sdlgameinterface.pas | 202 +
src/lib/JEDI-SDL/SDL/Pas/sdli386utils.pas | 5236 +++++++++++
src/lib/JEDI-SDL/SDL/Pas/sdlinput.pas | 923 ++
src/lib/JEDI-SDL/SDL/Pas/sdlstreams.pas | 216 +
src/lib/JEDI-SDL/SDL/Pas/sdlticks.pas | 197 +
src/lib/JEDI-SDL/SDL/Pas/sdlutils.pas | 4363 +++++++++
src/lib/JEDI-SDL/SDL/Pas/sdlwindow.pas | 566 ++
src/lib/JEDI-SDL/SDL/Pas/userpreferences.pas | 159 +
src/lib/JEDI-SDL/SDL_Image/Pas/sdl_image.pas | 350 +
src/lib/JEDI-SDL/SDL_ttf/Pas/sdl_ttf.pas | 506 ++
src/lib/JEDI-SDL/SDL_ttf/Pas/sdltruetypefont.pas | 565 ++
src/lib/JEDI-SDL/fpc-install.sh | 252 +
src/lib/JEDI-SDL/jedi-sdl-64bit.patch | 1280 +++
src/lib/JEDI-SDL/moduleloader-libc.patch | 25 +
src/lib/SQLite/SQLite3.pas | 255 +
src/lib/SQLite/SQLiteTable3.pas | 1446 +++
src/lib/SQLite/example/Sunset.jpg | Bin 0 -> 71189 bytes
src/lib/SQLite/example/TestSqlite.dpr | 15 +
src/lib/SQLite/example/TestSqlite.res | Bin 0 -> 876 bytes
src/lib/SQLite/example/uTestSqlite.dfm | 110 +
src/lib/SQLite/example/uTestSqlite.pas | 233 +
src/lib/SQLite/readme.txt | 93 +
src/lib/bass/bass.chm | Bin 0 -> 210668 bytes
src/lib/bass/bass.txt | 1658 ++++
src/lib/bass/delphi/bass-macosx.patch | 368 +
src/lib/bass/delphi/bass.pas | 865 ++
src/lib/ctypes/ctypes.pas | 72 +
src/lib/ffmpeg/avcodec.pas | 3350 +++++++
src/lib/ffmpeg/avformat.pas | 1372 +++
src/lib/ffmpeg/avio.pas | 538 ++
src/lib/ffmpeg/avutil.pas | 320 +
src/lib/ffmpeg/mathematics.pas | 81 +
src/lib/ffmpeg/opt.pas | 198 +
src/lib/ffmpeg/rational.pas | 153 +
src/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt | 23 +
src/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh | 6 +
src/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh | 23 +
src/lib/ffmpeg/swscale.pas | 202 +
src/lib/fft/UFFT.pas | 600 ++
src/lib/libpng/png.pas | 974 ++
src/lib/midi/CIRCBUF.PAS | 183 +
src/lib/midi/DELPHMCB.PAS | 140 +
src/lib/midi/MIDIDEFS.PAS | 55 +
src/lib/midi/MIDITYPE.PAS | 90 +
src/lib/midi/MidiFile.pas | 970 ++
src/lib/midi/MidiScope.pas | 198 +
src/lib/midi/Midicons.pas | 47 +
src/lib/midi/Midiin.pas | 727 ++
src/lib/midi/Midiout.pas | 619 ++
src/lib/midi/demo/MidiTest.dfm | Bin 0 -> 1872 bytes
src/lib/midi/demo/MidiTest.pas | 249 +
src/lib/midi/demo/Project1.dpr | 13 +
src/lib/midi/demo/Project1.res | Bin 0 -> 876 bytes
src/lib/midi/midiComp.cfg | 35 +
src/lib/midi/midiComp.dpk | 45 +
src/lib/midi/midiComp.res | Bin 0 -> 876 bytes
src/lib/midi/readme.txt | 60 +
src/lib/other/DirWatch.pas | 345 +
src/lib/other/WinAllocation.pas | 97 +
src/lib/portaudio/delphi/portaudio.pas | 1162 +++
src/lib/portmixer/delphi/portmixer.pas | 151 +
src/lib/projectM/cwrapper/Makefile.in | 30 +
src/lib/projectM/cwrapper/projectM-cwrapper.cpp | 104 +
src/lib/projectM/cwrapper/projectM-cwrapper.h | 67 +
src/lib/projectM/cwrapper/projectM-cwrapper.sln | 20 +
src/lib/projectM/cwrapper/projectM-cwrapper.vcproj | 208 +
src/lib/projectM/projectM-0_9.inc | 427 +
src/lib/projectM/projectM-1_0.inc | 188 +
src/lib/projectM/projectM.pas | 232 +
src/lib/requirements.txt | 39 +
src/lib/samplerate/samplerate.pas | 199 +
src/lib/zlib/zlib.pas | 215 +
src/m4/ac_define_dir.m4 | 47 +
src/m4/fpc.m4 | 176 +
src/package_debian.sh | 32 +
src/rccompile-delphi.bat | 1 +
src/rccompile-fpc.bat | 3 +
src/switches.inc | 111 +
src/ultrastardx.control | 19 +
src/ultrastardx.desktop | 17 +
484 files changed, 121770 insertions(+), 121770 deletions(-)
delete mode 100644 Game/Code/Classes/TextGL.pas
delete mode 100644 Game/Code/Classes/UAudioConverter.pas
delete mode 100644 Game/Code/Classes/UAudioCore_Bass.pas
delete mode 100644 Game/Code/Classes/UAudioCore_Portaudio.pas
delete mode 100644 Game/Code/Classes/UAudioDecoder_Bass.pas
delete mode 100644 Game/Code/Classes/UAudioDecoder_FFmpeg.pas
delete mode 100644 Game/Code/Classes/UAudioInput_Bass.pas
delete mode 100644 Game/Code/Classes/UAudioInput_Portaudio.pas
delete mode 100644 Game/Code/Classes/UAudioPlaybackBase.pas
delete mode 100644 Game/Code/Classes/UAudioPlayback_Bass.pas
delete mode 100644 Game/Code/Classes/UAudioPlayback_Portaudio.pas
delete mode 100644 Game/Code/Classes/UAudioPlayback_SDL.pas
delete mode 100644 Game/Code/Classes/UAudioPlayback_SoftMixer.pas
delete mode 100644 Game/Code/Classes/UCatCovers.pas
delete mode 100644 Game/Code/Classes/UCommandLine.pas
delete mode 100644 Game/Code/Classes/UCommon.pas
delete mode 100644 Game/Code/Classes/UConfig.pas
delete mode 100644 Game/Code/Classes/UCore.pas
delete mode 100644 Game/Code/Classes/UCoreModule.pas
delete mode 100644 Game/Code/Classes/UCovers.pas
delete mode 100644 Game/Code/Classes/UDLLManager.pas
delete mode 100644 Game/Code/Classes/UDataBase.pas
delete mode 100644 Game/Code/Classes/UDraw.pas
delete mode 100644 Game/Code/Classes/UEditorLyrics.pas
delete mode 100644 Game/Code/Classes/UFiles.pas
delete mode 100644 Game/Code/Classes/UGraphic.pas
delete mode 100644 Game/Code/Classes/UGraphicClasses.pas
delete mode 100644 Game/Code/Classes/UHooks.pas
delete mode 100644 Game/Code/Classes/UImage.pas
delete mode 100644 Game/Code/Classes/UIni.pas
delete mode 100644 Game/Code/Classes/UJoystick.pas
delete mode 100644 Game/Code/Classes/ULCD.pas
delete mode 100644 Game/Code/Classes/ULanguage.pas
delete mode 100644 Game/Code/Classes/ULight.pas
delete mode 100644 Game/Code/Classes/ULog.pas
delete mode 100644 Game/Code/Classes/ULyrics.pas
delete mode 100644 Game/Code/Classes/UMain.pas
delete mode 100644 Game/Code/Classes/UMediaCore_FFmpeg.pas
delete mode 100644 Game/Code/Classes/UMediaCore_SDL.pas
delete mode 100644 Game/Code/Classes/UMedia_dummy.pas
delete mode 100644 Game/Code/Classes/UModules.pas
delete mode 100644 Game/Code/Classes/UMusic.pas
delete mode 100644 Game/Code/Classes/UParty.pas
delete mode 100644 Game/Code/Classes/UPlatform.pas
delete mode 100644 Game/Code/Classes/UPlatformLinux.pas
delete mode 100644 Game/Code/Classes/UPlatformMacOSX.pas
delete mode 100644 Game/Code/Classes/UPlatformWindows.pas
delete mode 100644 Game/Code/Classes/UPlaylist.pas
delete mode 100644 Game/Code/Classes/UPluginInterface.pas
delete mode 100644 Game/Code/Classes/URecord.pas
delete mode 100644 Game/Code/Classes/URingBuffer.pas
delete mode 100644 Game/Code/Classes/UServices.pas
delete mode 100644 Game/Code/Classes/USingNotes.pas
delete mode 100644 Game/Code/Classes/USingScores.pas
delete mode 100644 Game/Code/Classes/USkins.pas
delete mode 100644 Game/Code/Classes/USong.pas
delete mode 100644 Game/Code/Classes/USongs.pas
delete mode 100644 Game/Code/Classes/UTextClasses.pas
delete mode 100644 Game/Code/Classes/UTexture.pas
delete mode 100644 Game/Code/Classes/UThemes.pas
delete mode 100644 Game/Code/Classes/UTime.pas
delete mode 100644 Game/Code/Classes/UVideo.pas
delete mode 100644 Game/Code/Classes/UVisualizer.pas
delete mode 100644 Game/Code/Classes/UXMLSong.pas
delete mode 100644 Game/Code/Classes/uPluginLoader.pas
delete mode 100755 Game/Code/MacOSX/English.lproj/InfoPlist.strings
delete mode 100644 Game/Code/MacOSX/English.lproj/SDLMain.nib/classes.nib
delete mode 100644 Game/Code/MacOSX/English.lproj/SDLMain.nib/info.nib
delete mode 100644 Game/Code/MacOSX/English.lproj/SDLMain.nib/objects.nib
delete mode 100644 Game/Code/MacOSX/Info.plist
delete mode 100644 Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
delete mode 100644 Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
delete mode 100644 Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
delete mode 100644 Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
delete mode 100644 Game/Code/MacOSX/Wrapper/MacResources.pas
delete mode 100644 Game/Code/MacOSX/Wrapper/PseudoThread.pas
delete mode 100644 Game/Code/MacOSX/Wrapper/Windows.pas
delete mode 100644 Game/Code/Makefile.in
delete mode 100644 Game/Code/Menu/UDisplay.pas
delete mode 100644 Game/Code/Menu/UDrawTexture.pas
delete mode 100644 Game/Code/Menu/UMenu.pas
delete mode 100644 Game/Code/Menu/UMenuButton.pas
delete mode 100644 Game/Code/Menu/UMenuButtonCollection.pas
delete mode 100644 Game/Code/Menu/UMenuInteract.pas
delete mode 100644 Game/Code/Menu/UMenuSelectSlide.pas
delete mode 100644 Game/Code/Menu/UMenuStatic.pas
delete mode 100644 Game/Code/Menu/UMenuText.pas
delete mode 100644 Game/Code/Screens/UScreenCredits.pas
delete mode 100644 Game/Code/Screens/UScreenEdit.pas
delete mode 100644 Game/Code/Screens/UScreenEditConvert.pas
delete mode 100644 Game/Code/Screens/UScreenEditHeader.pas
delete mode 100644 Game/Code/Screens/UScreenEditSub.pas
delete mode 100644 Game/Code/Screens/UScreenLevel.pas
delete mode 100644 Game/Code/Screens/UScreenLoading.pas
delete mode 100644 Game/Code/Screens/UScreenMain.pas
delete mode 100644 Game/Code/Screens/UScreenName.pas
delete mode 100644 Game/Code/Screens/UScreenOpen.pas
delete mode 100644 Game/Code/Screens/UScreenOptions.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsAdvanced.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsGame.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsGraphics.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsLyrics.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsRecord.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsSound.pas
delete mode 100644 Game/Code/Screens/UScreenOptionsThemes.pas
delete mode 100644 Game/Code/Screens/UScreenPartyNewRound.pas
delete mode 100644 Game/Code/Screens/UScreenPartyOptions.pas
delete mode 100644 Game/Code/Screens/UScreenPartyPlayer.pas
delete mode 100644 Game/Code/Screens/UScreenPartyScore.pas
delete mode 100644 Game/Code/Screens/UScreenPartyWin.pas
delete mode 100644 Game/Code/Screens/UScreenPopup.pas
delete mode 100644 Game/Code/Screens/UScreenScore.pas
delete mode 100644 Game/Code/Screens/UScreenSing.pas
delete mode 100644 Game/Code/Screens/UScreenSingModi.pas
delete mode 100644 Game/Code/Screens/UScreenSong.pas
delete mode 100644 Game/Code/Screens/UScreenSongJumpto.pas
delete mode 100644 Game/Code/Screens/UScreenSongMenu.pas
delete mode 100644 Game/Code/Screens/UScreenStatDetail.pas
delete mode 100644 Game/Code/Screens/UScreenStatMain.pas
delete mode 100644 Game/Code/Screens/UScreenTop5.pas
delete mode 100644 Game/Code/Screens/UScreenWelcome.pas
delete mode 100644 Game/Code/UltraStar-linux.lpi
delete mode 100644 Game/Code/UltraStar.dpr
delete mode 100644 Game/Code/UltraStar.lpi
delete mode 100644 Game/Code/UltraStar.lpr
delete mode 100644 Game/Code/UltraStar.rc
delete mode 100644 Game/Code/UnitTests/switches.inc
delete mode 100644 Game/Code/UnitTests/test_libraries.lpi
delete mode 100644 Game/Code/UnitTests/test_libraries.lpr
delete mode 100644 Game/Code/UnitTests/testsqllite.pas
delete mode 100755 Game/Code/autogen.sh
delete mode 100644 Game/Code/bamboo-build-lin-laz.bat
delete mode 100644 Game/Code/bamboo-build-lin-laz.sh
delete mode 100644 Game/Code/bamboo-build-win-delphi.bat
delete mode 100644 Game/Code/bamboo-build-win-laz.bat
delete mode 100644 Game/Code/build.bat
delete mode 100644 Game/Code/clean.bat
delete mode 100644 Game/Code/config-darwin.inc
delete mode 100644 Game/Code/config-win.inc
delete mode 100644 Game/Code/config.inc.in
delete mode 100644 Game/Code/configure.ac
delete mode 100644 Game/Code/developer_changelog.txt
delete mode 100755 Game/Code/install-sh
delete mode 100644 Game/Code/lazres-UltraStar.bat
delete mode 100644 Game/Code/lib/FreeImage/FreeBitmap.pas
delete mode 100644 Game/Code/lib/FreeImage/FreeImage.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/JEDI-SDL-README.txt
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL-Set8087CW.patch
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/gl.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/glext.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/glu.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/glut.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/OpenGL/Pas/glx.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/Readme.txt
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/logger.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/moduleloader.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/registryuserpreferences.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdl.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdl_cpuinfo.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlgameinterface.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdli386utils.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlinput.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlstreams.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlticks.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlutils.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/sdlwindow.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL/Pas/userpreferences.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL_Image/Pas/sdl_image.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL_ttf/Pas/sdl_ttf.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/SDL_ttf/Pas/sdltruetypefont.pas
delete mode 100644 Game/Code/lib/JEDI-SDL/fpc-install.sh
delete mode 100644 Game/Code/lib/JEDI-SDL/jedi-sdl-64bit.patch
delete mode 100644 Game/Code/lib/JEDI-SDL/moduleloader-libc.patch
delete mode 100644 Game/Code/lib/SQLite/SQLite3.pas
delete mode 100644 Game/Code/lib/SQLite/SQLiteTable3.pas
delete mode 100644 Game/Code/lib/SQLite/example/Sunset.jpg
delete mode 100644 Game/Code/lib/SQLite/example/TestSqlite.dpr
delete mode 100644 Game/Code/lib/SQLite/example/TestSqlite.res
delete mode 100644 Game/Code/lib/SQLite/example/uTestSqlite.dfm
delete mode 100644 Game/Code/lib/SQLite/example/uTestSqlite.pas
delete mode 100644 Game/Code/lib/SQLite/readme.txt
delete mode 100644 Game/Code/lib/bass/bass.chm
delete mode 100644 Game/Code/lib/bass/bass.txt
delete mode 100644 Game/Code/lib/bass/delphi/bass-macosx.patch
delete mode 100644 Game/Code/lib/bass/delphi/bass.pas
delete mode 100644 Game/Code/lib/ctypes/ctypes.pas
delete mode 100644 Game/Code/lib/ffmpeg/avcodec.pas
delete mode 100644 Game/Code/lib/ffmpeg/avformat.pas
delete mode 100644 Game/Code/lib/ffmpeg/avio.pas
delete mode 100644 Game/Code/lib/ffmpeg/avutil.pas
delete mode 100644 Game/Code/lib/ffmpeg/mathematics.pas
delete mode 100644 Game/Code/lib/ffmpeg/opt.pas
delete mode 100644 Game/Code/lib/ffmpeg/rational.pas
delete mode 100644 Game/Code/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt
delete mode 100755 Game/Code/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh
delete mode 100755 Game/Code/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh
delete mode 100644 Game/Code/lib/ffmpeg/swscale.pas
delete mode 100644 Game/Code/lib/fft/UFFT.pas
delete mode 100644 Game/Code/lib/libpng/png.pas
delete mode 100644 Game/Code/lib/midi/CIRCBUF.PAS
delete mode 100644 Game/Code/lib/midi/DELPHMCB.PAS
delete mode 100644 Game/Code/lib/midi/MIDIDEFS.PAS
delete mode 100644 Game/Code/lib/midi/MIDITYPE.PAS
delete mode 100644 Game/Code/lib/midi/MidiFile.pas
delete mode 100644 Game/Code/lib/midi/MidiScope.pas
delete mode 100644 Game/Code/lib/midi/Midicons.pas
delete mode 100644 Game/Code/lib/midi/Midiin.pas
delete mode 100644 Game/Code/lib/midi/Midiout.pas
delete mode 100644 Game/Code/lib/midi/demo/MidiTest.dfm
delete mode 100644 Game/Code/lib/midi/demo/MidiTest.pas
delete mode 100644 Game/Code/lib/midi/demo/Project1.dpr
delete mode 100644 Game/Code/lib/midi/demo/Project1.res
delete mode 100644 Game/Code/lib/midi/midiComp.cfg
delete mode 100644 Game/Code/lib/midi/midiComp.dpk
delete mode 100644 Game/Code/lib/midi/midiComp.res
delete mode 100644 Game/Code/lib/midi/readme.txt
delete mode 100644 Game/Code/lib/other/DirWatch.pas
delete mode 100644 Game/Code/lib/other/WinAllocation.pas
delete mode 100644 Game/Code/lib/portaudio/delphi/portaudio.pas
delete mode 100644 Game/Code/lib/portmixer/delphi/portmixer.pas
delete mode 100644 Game/Code/lib/projectM/cwrapper/Makefile.in
delete mode 100644 Game/Code/lib/projectM/cwrapper/projectM-cwrapper.cpp
delete mode 100644 Game/Code/lib/projectM/cwrapper/projectM-cwrapper.h
delete mode 100644 Game/Code/lib/projectM/cwrapper/projectM-cwrapper.sln
delete mode 100644 Game/Code/lib/projectM/cwrapper/projectM-cwrapper.vcproj
delete mode 100644 Game/Code/lib/projectM/projectM-0_9.inc
delete mode 100644 Game/Code/lib/projectM/projectM-1_0.inc
delete mode 100644 Game/Code/lib/projectM/projectM.pas
delete mode 100644 Game/Code/lib/requirements.txt
delete mode 100644 Game/Code/lib/samplerate/samplerate.pas
delete mode 100644 Game/Code/lib/zlib/zlib.pas
delete mode 100644 Game/Code/m4/ac_define_dir.m4
delete mode 100644 Game/Code/m4/fpc.m4
delete mode 100644 Game/Code/package_debian.sh
delete mode 100644 Game/Code/rccompile-delphi.bat
delete mode 100644 Game/Code/rccompile-fpc.bat
delete mode 100644 Game/Code/switches.inc
delete mode 100644 Game/Code/ultrastardx.control
delete mode 100644 Game/Code/ultrastardx.desktop
create mode 100644 src/Classes/TextGL.pas
create mode 100644 src/Classes/UAudioConverter.pas
create mode 100644 src/Classes/UAudioCore_Bass.pas
create mode 100644 src/Classes/UAudioCore_Portaudio.pas
create mode 100644 src/Classes/UAudioDecoder_Bass.pas
create mode 100644 src/Classes/UAudioDecoder_FFmpeg.pas
create mode 100644 src/Classes/UAudioInput_Bass.pas
create mode 100644 src/Classes/UAudioInput_Portaudio.pas
create mode 100644 src/Classes/UAudioPlaybackBase.pas
create mode 100644 src/Classes/UAudioPlayback_Bass.pas
create mode 100644 src/Classes/UAudioPlayback_Portaudio.pas
create mode 100644 src/Classes/UAudioPlayback_SDL.pas
create mode 100644 src/Classes/UAudioPlayback_SoftMixer.pas
create mode 100644 src/Classes/UCatCovers.pas
create mode 100644 src/Classes/UCommandLine.pas
create mode 100644 src/Classes/UCommon.pas
create mode 100644 src/Classes/UConfig.pas
create mode 100644 src/Classes/UCore.pas
create mode 100644 src/Classes/UCoreModule.pas
create mode 100644 src/Classes/UCovers.pas
create mode 100644 src/Classes/UDLLManager.pas
create mode 100644 src/Classes/UDataBase.pas
create mode 100644 src/Classes/UDraw.pas
create mode 100644 src/Classes/UEditorLyrics.pas
create mode 100644 src/Classes/UFiles.pas
create mode 100644 src/Classes/UGraphic.pas
create mode 100644 src/Classes/UGraphicClasses.pas
create mode 100644 src/Classes/UHooks.pas
create mode 100644 src/Classes/UImage.pas
create mode 100644 src/Classes/UIni.pas
create mode 100644 src/Classes/UJoystick.pas
create mode 100644 src/Classes/ULCD.pas
create mode 100644 src/Classes/ULanguage.pas
create mode 100644 src/Classes/ULight.pas
create mode 100644 src/Classes/ULog.pas
create mode 100644 src/Classes/ULyrics.pas
create mode 100644 src/Classes/UMain.pas
create mode 100644 src/Classes/UMediaCore_FFmpeg.pas
create mode 100644 src/Classes/UMediaCore_SDL.pas
create mode 100644 src/Classes/UMedia_dummy.pas
create mode 100644 src/Classes/UModules.pas
create mode 100644 src/Classes/UMusic.pas
create mode 100644 src/Classes/UParty.pas
create mode 100644 src/Classes/UPlatform.pas
create mode 100644 src/Classes/UPlatformLinux.pas
create mode 100644 src/Classes/UPlatformMacOSX.pas
create mode 100644 src/Classes/UPlatformWindows.pas
create mode 100644 src/Classes/UPlaylist.pas
create mode 100644 src/Classes/UPluginInterface.pas
create mode 100644 src/Classes/URecord.pas
create mode 100644 src/Classes/URingBuffer.pas
create mode 100644 src/Classes/UServices.pas
create mode 100644 src/Classes/USingNotes.pas
create mode 100644 src/Classes/USingScores.pas
create mode 100644 src/Classes/USkins.pas
create mode 100644 src/Classes/USong.pas
create mode 100644 src/Classes/USongs.pas
create mode 100644 src/Classes/UTextClasses.pas
create mode 100644 src/Classes/UTexture.pas
create mode 100644 src/Classes/UThemes.pas
create mode 100644 src/Classes/UTime.pas
create mode 100644 src/Classes/UVideo.pas
create mode 100644 src/Classes/UVisualizer.pas
create mode 100644 src/Classes/UXMLSong.pas
create mode 100644 src/Classes/uPluginLoader.pas
create mode 100755 src/MacOSX/English.lproj/InfoPlist.strings
create mode 100644 src/MacOSX/English.lproj/SDLMain.nib/classes.nib
create mode 100644 src/MacOSX/English.lproj/SDLMain.nib/info.nib
create mode 100644 src/MacOSX/English.lproj/SDLMain.nib/objects.nib
create mode 100644 src/MacOSX/Info.plist
create mode 100644 src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
create mode 100644 src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
create mode 100644 src/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
create mode 100644 src/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
create mode 100644 src/MacOSX/Wrapper/MacResources.pas
create mode 100644 src/MacOSX/Wrapper/PseudoThread.pas
create mode 100644 src/MacOSX/Wrapper/Windows.pas
create mode 100644 src/Makefile.in
create mode 100644 src/Menu/UDisplay.pas
create mode 100644 src/Menu/UDrawTexture.pas
create mode 100644 src/Menu/UMenu.pas
create mode 100644 src/Menu/UMenuButton.pas
create mode 100644 src/Menu/UMenuButtonCollection.pas
create mode 100644 src/Menu/UMenuInteract.pas
create mode 100644 src/Menu/UMenuSelectSlide.pas
create mode 100644 src/Menu/UMenuStatic.pas
create mode 100644 src/Menu/UMenuText.pas
create mode 100644 src/Screens/UScreenCredits.pas
create mode 100644 src/Screens/UScreenEdit.pas
create mode 100644 src/Screens/UScreenEditConvert.pas
create mode 100644 src/Screens/UScreenEditHeader.pas
create mode 100644 src/Screens/UScreenEditSub.pas
create mode 100644 src/Screens/UScreenLevel.pas
create mode 100644 src/Screens/UScreenLoading.pas
create mode 100644 src/Screens/UScreenMain.pas
create mode 100644 src/Screens/UScreenName.pas
create mode 100644 src/Screens/UScreenOpen.pas
create mode 100644 src/Screens/UScreenOptions.pas
create mode 100644 src/Screens/UScreenOptionsAdvanced.pas
create mode 100644 src/Screens/UScreenOptionsGame.pas
create mode 100644 src/Screens/UScreenOptionsGraphics.pas
create mode 100644 src/Screens/UScreenOptionsLyrics.pas
create mode 100644 src/Screens/UScreenOptionsRecord.pas
create mode 100644 src/Screens/UScreenOptionsSound.pas
create mode 100644 src/Screens/UScreenOptionsThemes.pas
create mode 100644 src/Screens/UScreenPartyNewRound.pas
create mode 100644 src/Screens/UScreenPartyOptions.pas
create mode 100644 src/Screens/UScreenPartyPlayer.pas
create mode 100644 src/Screens/UScreenPartyScore.pas
create mode 100644 src/Screens/UScreenPartyWin.pas
create mode 100644 src/Screens/UScreenPopup.pas
create mode 100644 src/Screens/UScreenScore.pas
create mode 100644 src/Screens/UScreenSing.pas
create mode 100644 src/Screens/UScreenSingModi.pas
create mode 100644 src/Screens/UScreenSong.pas
create mode 100644 src/Screens/UScreenSongJumpto.pas
create mode 100644 src/Screens/UScreenSongMenu.pas
create mode 100644 src/Screens/UScreenStatDetail.pas
create mode 100644 src/Screens/UScreenStatMain.pas
create mode 100644 src/Screens/UScreenTop5.pas
create mode 100644 src/Screens/UScreenWelcome.pas
create mode 100644 src/UltraStar-linux.lpi
create mode 100644 src/UltraStar.dpr
create mode 100644 src/UltraStar.lpi
create mode 100644 src/UltraStar.lpr
create mode 100644 src/UltraStar.rc
create mode 100644 src/UnitTests/switches.inc
create mode 100644 src/UnitTests/test_libraries.lpi
create mode 100644 src/UnitTests/test_libraries.lpr
create mode 100644 src/UnitTests/testsqllite.pas
create mode 100755 src/autogen.sh
create mode 100644 src/bamboo-build-lin-laz.bat
create mode 100644 src/bamboo-build-lin-laz.sh
create mode 100644 src/bamboo-build-win-delphi.bat
create mode 100644 src/bamboo-build-win-laz.bat
create mode 100644 src/build.bat
create mode 100644 src/clean.bat
create mode 100644 src/config-darwin.inc
create mode 100644 src/config-win.inc
create mode 100644 src/config.inc.in
create mode 100644 src/configure.ac
create mode 100644 src/developer_changelog.txt
create mode 100755 src/install-sh
create mode 100644 src/lazres-UltraStar.bat
create mode 100644 src/lib/FreeImage/FreeBitmap.pas
create mode 100644 src/lib/FreeImage/FreeImage.pas
create mode 100644 src/lib/JEDI-SDL/JEDI-SDL-README.txt
create mode 100644 src/lib/JEDI-SDL/OpenGL-Set8087CW.patch
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/gl.pas
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/glext.pas
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/glu.pas
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/glut.pas
create mode 100644 src/lib/JEDI-SDL/OpenGL/Pas/glx.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/Readme.txt
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/logger.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/registryuserpreferences.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdl.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdl_cpuinfo.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlgameinterface.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdli386utils.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlinput.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlstreams.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlticks.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlutils.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/sdlwindow.pas
create mode 100644 src/lib/JEDI-SDL/SDL/Pas/userpreferences.pas
create mode 100644 src/lib/JEDI-SDL/SDL_Image/Pas/sdl_image.pas
create mode 100644 src/lib/JEDI-SDL/SDL_ttf/Pas/sdl_ttf.pas
create mode 100644 src/lib/JEDI-SDL/SDL_ttf/Pas/sdltruetypefont.pas
create mode 100644 src/lib/JEDI-SDL/fpc-install.sh
create mode 100644 src/lib/JEDI-SDL/jedi-sdl-64bit.patch
create mode 100644 src/lib/JEDI-SDL/moduleloader-libc.patch
create mode 100644 src/lib/SQLite/SQLite3.pas
create mode 100644 src/lib/SQLite/SQLiteTable3.pas
create mode 100644 src/lib/SQLite/example/Sunset.jpg
create mode 100644 src/lib/SQLite/example/TestSqlite.dpr
create mode 100644 src/lib/SQLite/example/TestSqlite.res
create mode 100644 src/lib/SQLite/example/uTestSqlite.dfm
create mode 100644 src/lib/SQLite/example/uTestSqlite.pas
create mode 100644 src/lib/SQLite/readme.txt
create mode 100644 src/lib/bass/bass.chm
create mode 100644 src/lib/bass/bass.txt
create mode 100644 src/lib/bass/delphi/bass-macosx.patch
create mode 100644 src/lib/bass/delphi/bass.pas
create mode 100644 src/lib/ctypes/ctypes.pas
create mode 100644 src/lib/ffmpeg/avcodec.pas
create mode 100644 src/lib/ffmpeg/avformat.pas
create mode 100644 src/lib/ffmpeg/avio.pas
create mode 100644 src/lib/ffmpeg/avutil.pas
create mode 100644 src/lib/ffmpeg/mathematics.pas
create mode 100644 src/lib/ffmpeg/opt.pas
create mode 100644 src/lib/ffmpeg/rational.pas
create mode 100644 src/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt
create mode 100755 src/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh
create mode 100755 src/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh
create mode 100644 src/lib/ffmpeg/swscale.pas
create mode 100644 src/lib/fft/UFFT.pas
create mode 100644 src/lib/libpng/png.pas
create mode 100644 src/lib/midi/CIRCBUF.PAS
create mode 100644 src/lib/midi/DELPHMCB.PAS
create mode 100644 src/lib/midi/MIDIDEFS.PAS
create mode 100644 src/lib/midi/MIDITYPE.PAS
create mode 100644 src/lib/midi/MidiFile.pas
create mode 100644 src/lib/midi/MidiScope.pas
create mode 100644 src/lib/midi/Midicons.pas
create mode 100644 src/lib/midi/Midiin.pas
create mode 100644 src/lib/midi/Midiout.pas
create mode 100644 src/lib/midi/demo/MidiTest.dfm
create mode 100644 src/lib/midi/demo/MidiTest.pas
create mode 100644 src/lib/midi/demo/Project1.dpr
create mode 100644 src/lib/midi/demo/Project1.res
create mode 100644 src/lib/midi/midiComp.cfg
create mode 100644 src/lib/midi/midiComp.dpk
create mode 100644 src/lib/midi/midiComp.res
create mode 100644 src/lib/midi/readme.txt
create mode 100644 src/lib/other/DirWatch.pas
create mode 100644 src/lib/other/WinAllocation.pas
create mode 100644 src/lib/portaudio/delphi/portaudio.pas
create mode 100644 src/lib/portmixer/delphi/portmixer.pas
create mode 100644 src/lib/projectM/cwrapper/Makefile.in
create mode 100644 src/lib/projectM/cwrapper/projectM-cwrapper.cpp
create mode 100644 src/lib/projectM/cwrapper/projectM-cwrapper.h
create mode 100644 src/lib/projectM/cwrapper/projectM-cwrapper.sln
create mode 100644 src/lib/projectM/cwrapper/projectM-cwrapper.vcproj
create mode 100644 src/lib/projectM/projectM-0_9.inc
create mode 100644 src/lib/projectM/projectM-1_0.inc
create mode 100644 src/lib/projectM/projectM.pas
create mode 100644 src/lib/requirements.txt
create mode 100644 src/lib/samplerate/samplerate.pas
create mode 100644 src/lib/zlib/zlib.pas
create mode 100644 src/m4/ac_define_dir.m4
create mode 100644 src/m4/fpc.m4
create mode 100644 src/package_debian.sh
create mode 100644 src/rccompile-delphi.bat
create mode 100644 src/rccompile-fpc.bat
create mode 100644 src/switches.inc
create mode 100644 src/ultrastardx.control
create mode 100644 src/ultrastardx.desktop
diff --git a/Game/Code/Classes/TextGL.pas b/Game/Code/Classes/TextGL.pas
deleted file mode 100644
index f7b3ac95..00000000
--- a/Game/Code/Classes/TextGL.pas
+++ /dev/null
@@ -1,462 +0,0 @@
-unit TextGL;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- gl,
- SDL,
- UTexture,
- Classes,
-// SDL_ttf,
- ULog;
-
-procedure BuildFont; // build our bitmap font
-procedure KillFont; // delete the font
-function glTextWidth(text: PChar): real; // returns text width
-procedure glPrintLetter(letter: char);
-procedure glPrint(text: pchar); // custom GL "Print" routine
-procedure SetFontPos(X, Y: real); // sets X and Y
-procedure SetFontZ(Z: real); // sets Z
-procedure SetFontSize(Size: real);
-procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc)
-procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts)
-procedure SetFontAspectW(Aspect: real);
-procedure SetFontReflection(Enable:boolean;Spacing: real); // enables/disables text reflection
-procedure SetFontBlend(Enable: boolean); // enables/disables blending
-
-//function NextPowerOfTwo(Value: integer): integer;
-// Checks if the ttf exists, if yes then a SDL_ttf is returned
-//function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
-// Does the renderstuff, color is in $ffeecc style
-//function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal):PSDL_Surface;
-
-type
- TTextGL = record
- X: real;
- Y: real;
- Z: real;
- Text: string;
- Size: real;
- ColR: real;
- ColG: real;
- ColB: real;
- end;
-
- PFont = ^TFont;
- TFont = record
- Tex: TTexture;
- Width: array[0..255] of byte;
- AspectW: real;
- Centered: boolean;
- Outline: real;
- Italic: boolean;
- Reflection: boolean;
- ReflectionSpacing: real;
- Blend: boolean;
- end;
-
-
-var
- Fonts: array of TFont;
- ActFont: integer;
-
-
-implementation
-
-uses
- UMain,
- UCommon,
- SysUtils,
- UGraphic;
-
-var
- // Colours for the reflection
- TempColor: array[0..3] of GLfloat;
-
-procedure LoadBitmapFontInfo(aID : integer; const aType, aResourceName: string);
-var
- stream: TStream;
-begin
- stream := GetResourceStream(aResourceName, aType);
- if (not assigned(stream)) then
- begin
- Log.LogError('Unknown font['+ inttostr(aID) +': '+aType+']', 'loadfont');
- Exit;
- end;
- try
- stream.Read(Fonts[ aID ].Width, 256);
- except
- Log.LogError('Error while reading font['+ inttostr(aID) +': '+aType+']', 'loadfont');
- end;
- stream.Free;
-end;
-
-// Builds bitmap fonts
-procedure BuildFont;
-var
- Count: integer;
-begin
- ActFont := 0;
-
- SetLength(Fonts, 5);
- Fonts[0].Tex := Texture.LoadTexture(true, 'Font', TEXTURE_TYPE_TRANSPARENT, 0);
- Fonts[0].Tex.H := 30;
- Fonts[0].AspectW := 0.9;
- Fonts[0].Outline := 0;
-
- Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', TEXTURE_TYPE_TRANSPARENT, 0);
- Fonts[1].Tex.H := 30;
- Fonts[1].AspectW := 1;
- Fonts[1].Outline := 0;
-
- Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', TEXTURE_TYPE_TRANSPARENT, 0);
- Fonts[2].Tex.H := 30;
- Fonts[2].AspectW := 0.95;
- Fonts[2].Outline := 5;
-
- Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', TEXTURE_TYPE_TRANSPARENT, 0);
- Fonts[3].Tex.H := 30;
- Fonts[3].AspectW := 0.95;
- Fonts[3].Outline := 4;
-
-{ Fonts[4].Tex := Texture.LoadTexture('FontO', TEXTURE_TYPE_TRANSPARENT, 0); // for score screen
- Fonts[4].Tex.H := 30;
- Fonts[4].AspectW := 0.95;
- Fonts[4].Done := -1;
- Fonts[4].Outline := 5;}
-
- // load font info
- LoadBitmapFontInfo( 0, 'FNT', 'Font');
- LoadBitmapFontInfo( 1, 'FNT', 'FontB');
- LoadBitmapFontInfo( 2, 'FNT', 'FontO');
- LoadBitmapFontInfo( 3, 'FNT', 'FontO2');
-
- for Count := 0 to 255 do
- Fonts[1].Width[Count] := Fonts[1].Width[Count] div 2;
-
- for Count := 0 to 255 do
- Fonts[2].Width[Count] := Fonts[2].Width[Count] div 2 + 2;
-
- for Count := 0 to 255 do
- Fonts[3].Width[Count] := Fonts[3].Width[Count] + 1;
-
-{ for Count := 0 to 255 do
- Fonts[4].Width[Count] := Fonts[4].Width[Count] div 2 + 2;}
-
- // enable blending by default
- for Count := 0 to High(Fonts) do
- Fonts[Count].Blend := true;
-end;
-
-// Deletes the font
-procedure KillFont;
-begin
- // delete all characters
- //glDeleteLists(..., 256);
-end;
-
-function glTextWidth(text: pchar): real;
-var
- Letter: char;
- i: integer;
-begin
- Result := 0;
- for i := 0 to Length(text) -1 do
- begin
- Letter := Text[i];
- Result := Result + Fonts[ActFont].Width[Ord(Letter)] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- end;
-end;
-
-procedure glPrintLetter(Letter: char);
-var
- TexX, TexY: real;
- TexR, TexB: real;
- TexHeight: real;
- FWidth: real;
- PL, PT: real;
- PR, PB: real;
- XItal: real; // X shift for italic type letter
- ReflectionSpacing: real; // Distance of the reflection
- Font: PFont;
- Tex: PTexture;
-begin
- Font := @Fonts[ActFont];
- Tex := @Font.Tex;
-
- FWidth := Font.Width[Ord(Letter)];
-
- Tex.W := FWidth * (Tex.H/30) * Font.AspectW;
-
- // set texture positions
- TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Font.Outline/1024;
- TexY := (ord(Letter) div 16) * 1/16 + 2/1024;
- TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Font.Outline/1024;
- TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
-
- TexHeight := TexB - TexY;
-
- // set vector positions
- PL := Tex.X - Font.Outline * (Tex.H/30) * Font.AspectW /2;
- PT := Tex.Y;
- PR := PL + Tex.W + Font.Outline * (Tex.H/30) * Font.AspectW;
- PB := PT + Tex.H;
-
- if (not Font.Italic) then
- XItal := 0
- else
- XItal := 12;
-
- if (Font.Blend) then
- begin
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- end;
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, Tex.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
- glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
- glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
- glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT);
- glEnd;
-
- // Reflection
- // Yes it would make sense to put this in an extra procedure,
- // but this works, doesn't take much lines, and is almost lightweight
- if Font.Reflection then
- begin
- ReflectionSpacing := Font.ReflectionSpacing + Tex.H/2;
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBegin(GL_QUADS);
- glColor4f(TempColor[0], TempColor[1], TempColor[2], 0);
- glTexCoord2f(TexX, TexY + TexHeight/2);
- glVertex3f(PL, PB + ReflectionSpacing - Tex.H/2, Tex.z);
-
- glColor4f(TempColor[0], TempColor[1], TempColor[2], Tex.Alpha-0.3);
- glTexCoord2f(TexX, TexB );
- glVertex3f(PL + XItal, PT + ReflectionSpacing, Tex.z);
-
- glTexCoord2f(TexR, TexB );
- glVertex3f(PR + XItal, PT + ReflectionSpacing, Tex.z);
-
- glColor4f(TempColor[0], TempColor[1], TempColor[2], 0);
- glTexCoord2f(TexR, TexY + TexHeight/2);
- glVertex3f(PR, PB + ReflectionSpacing - Tex.H/2, Tex.z);
- glEnd;
-
- glDisable(GL_DEPTH_TEST);
- end; // reflection
-
- glDisable(GL_TEXTURE_2D);
- if (Font.Blend) then
- glDisable(GL_BLEND);
-
- Tex.X := Tex.X + Tex.W;
-
- //write the colour back
- glColor4fv(@TempColor);
-end;
-
-// Custom GL "Print" Routine
-procedure glPrint(Text: PChar);
-var
- Pos: integer;
-begin
- // if there is no text do nothing
- if ((Text = nil) or (Text = '')) then
- Exit;
-
- //Save the actual color and alpha (for reflection)
- glGetFloatv(GL_CURRENT_COLOR, @TempColor);
-
- for Pos := 0 to Length(Text) - 1 do
- begin
- glPrintLetter(Text[Pos]);
- end;
-end;
-
-procedure SetFontPos(X, Y: real);
-begin
- Fonts[ActFont].Tex.X := X;
- Fonts[ActFont].Tex.Y := Y;
-end;
-
-procedure SetFontZ(Z: real);
-begin
- Fonts[ActFont].Tex.Z := Z;
-end;
-
-procedure SetFontSize(Size: real);
-begin
- Fonts[ActFont].Tex.H := 30 * (Size/10);
-end;
-
-procedure SetFontStyle(Style: integer);
-begin
- ActFont := Style;
-end;
-
-procedure SetFontItalic(Enable: boolean);
-begin
- Fonts[ActFont].Italic := Enable;
-end;
-
-procedure SetFontAspectW(Aspect: real);
-begin
- Fonts[ActFont].AspectW := Aspect;
-end;
-
-procedure SetFontReflection(Enable: boolean; Spacing: real);
-begin
- Fonts[ActFont].Reflection := Enable;
- Fonts[ActFont].ReflectionSpacing := Spacing;
-end;
-
-procedure SetFontBlend(Enable: boolean);
-begin
- Fonts[ActFont].Blend := Enable;
-end;
-
-
-
-
-(*
- I uncommented this, because it was some kind of after hour hack together with blindy
-it's actually just a prove of concept, as it's having some flaws
-- instead nice and clean ttf code should be placed here :)
-
-{$IFDEF FPC}
- {$ASMMODE Intel}
-{$ENDIF}
-
-function NextPowerOfTwo(Value: integer): integer;
-begin
- Result:= 1;
-{$IF Defined(CPUX86_64)}
- asm
- mov rcx, -1
- bsr rcx, Value
- inc rcx
- shl Result, cl
- end;
-{$ELSEIF Defined(CPU386) or Defined(CPUI386)}
- asm
- mov ecx, -1
- bsr ecx, Value
- inc ecx
- shl Result, cl
- end;
-{$ELSE}
- while (Result <= Value) do
- Result := 2 * Result;
-{$IFEND}
-end;
-
-function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
-begin
- if (FileExists(FileName)) then
- begin
- Result := TTF_OpenFont( FileName, PointSize );
- end
- else
- begin
- Log.LogStatus('ERROR Could not find font in ' + FileName , '');
- ShowMessage( 'ERROR Could not find font in ' + FileName );
- Result := nil;
- end;
-end;
-
-function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal): PSDL_Surface;
-var
- clr : TSDL_color;
-begin
- clr.r := ((Color and $ff0000) shr 16 ) div 255;
- clr.g := ((Color and $ff00 ) shr 8 ) div 255;
- clr.b := ( Color and $ff ) div 255 ;
-
- result := TTF_RenderText_Blended( font, text, cLr);
-end;
-
-procedure printrandomtext();
-var
- stext,intermediary : PSDL_surface;
- clrFg, clrBG : TSDL_color;
- texture : Gluint;
- font : PTTF_Font;
- w,h : integer;
-begin
-
- font := LoadFont('fonts\comicbd.ttf', 42);
-
- clrFg.r := 255;
- clrFg.g := 255;
- clrFg.b := 255;
- clrFg.unused := 255;
-
- clrBg.r := 255;
- clrbg.g := 0;
- clrbg.b := 255;
- clrbg.unused := 0;
-
- sText := RenderText(font, 'katzeeeeeee', $fe198e);
- //sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG);
-
- // Convert the rendered text to a known format
- w := nextpoweroftwo(sText.w);
- h := nextpoweroftwo(sText.h);
-
- intermediary := SDL_CreateRGBSurface(0, w, h, 32,
- $000000ff, $0000ff00, $00ff0000, $ff000000);
-
- SDL_SetAlpha(intermediary, 0, 255);
- SDL_SetAlpha(sText, 0, 255);
- SDL_BlitSurface(sText, nil, intermediary, nil);
-
- glGenTextures(1, @texture);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary.pixels);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, texture);
- glColor4f(1, 0, 1, 1);
-
- glbegin(gl_quads);
- glTexCoord2f(0, 0); glVertex2f(200 , 300 );
- glTexCoord2f(0, sText.h/h); glVertex2f(200 , 300 + sText.h);
- glTexCoord2f(sText.w/w, sText.h/h); glVertex2f(200 + sText.w, 300 + sText.h);
- glTexCoord2f(sText.w/w, 0); glVertex2f(200 + sText.w, 300 );
- glEnd;
- glfinish();
- glDisable(GL_BLEND);
- gldisable(gl_texture_2d);
-
- SDL_FreeSurface(sText);
- SDL_FreeSurface(intermediary);
- glDeleteTextures(1, @texture);
- TTF_CloseFont(font);
-
-end;
-*)
-
-
-end.
diff --git a/Game/Code/Classes/UAudioConverter.pas b/Game/Code/Classes/UAudioConverter.pas
deleted file mode 100644
index 5647f27b..00000000
--- a/Game/Code/Classes/UAudioConverter.pas
+++ /dev/null
@@ -1,458 +0,0 @@
-unit UAudioConverter;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMusic,
- ULog,
- ctypes,
- {$IFDEF UseSRCResample}
- samplerate,
- {$ENDIF}
- {$IFDEF UseFFmpegResample}
- avcodec,
- {$ENDIF}
- UMediaCore_SDL,
- sdl,
- SysUtils,
- Math;
-
-type
- {*
- * Notes:
- * - 44.1kHz to 48kHz conversion or vice versa is not supported
- * by SDL 1.2 (will be introduced in 1.3).
- * No conversion takes place in this cases.
- * This is because SDL just converts differences in powers of 2.
- * So the result might not be that accurate.
- * This IS audible (voice to high/low) and it needs good synchronization
- * with the video or the lyrics timer.
- * - float<->int16 conversion is not supported (will be part of 1.3) and
- * SDL (<1.3) is not capable of handling floats at all.
- * -> Using FFmpeg or libsamplerate for resampling is preferred.
- * Use SDL for channel and format conversion only.
- *}
- TAudioConverter_SDL = class(TAudioConverter)
- private
- cvt: TSDL_AudioCVT;
- public
- function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
- destructor Destroy(); override;
-
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
- function GetOutputBufferSize(InputSize: integer): integer; override;
- function GetRatio(): double; override;
- end;
-
- {$IFDEF UseFFmpegResample}
- // Note: FFmpeg seems to be using "kaiser windowed sinc" for resampling, so
- // the quality should be good.
- TAudioConverter_FFmpeg = class(TAudioConverter)
- private
- // TODO: use SDL for multi-channel->stereo and format conversion
- ResampleContext: PReSampleContext;
- Ratio: double;
- public
- function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
- destructor Destroy(); override;
-
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
- function GetOutputBufferSize(InputSize: integer): integer; override;
- function GetRatio(): double; override;
- end;
- {$ENDIF}
-
- {$IFDEF UseSRCResample}
- TAudioConverter_SRC = class(TAudioConverter)
- private
- ConverterState: PSRC_STATE;
- ConversionData: SRC_DATA;
- FormatConverter: TAudioConverter;
- public
- function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
- destructor Destroy(); override;
-
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
- function GetOutputBufferSize(InputSize: integer): integer; override;
- function GetRatio(): double; override;
- end;
-
- // Note: SRC (=libsamplerate) provides several converters with different quality
- // speed trade-offs. The SINC-types are slow but offer best quality.
- // The SRC_SINC_* converters are too slow for realtime conversion,
- // (SRC_SINC_FASTEST is approx. ten times slower than SRC_LINEAR) resulting
- // in audible clicks and pops.
- // SRC_LINEAR is very fast and should have a better quality than SRC_ZERO_ORDER_HOLD
- // because it interpolates the samples. Normal "non-audiophile" users should not
- // be able to hear a difference between the SINC_* ones and LINEAR. Especially
- // if people sing along with the song.
- // But FFmpeg might offer a better quality/speed ratio than SRC_LINEAR.
- const
- SRC_CONVERTER_TYPE = SRC_LINEAR;
- {$ENDIF}
-
-implementation
-
-function TAudioConverter_SDL.Init(srcFormatInfo: TAudioFormatInfo; dstFormatInfo: TAudioFormatInfo): boolean;
-var
- srcFormat: UInt16;
- dstFormat: UInt16;
-begin
- inherited Init(SrcFormatInfo, DstFormatInfo);
-
- Result := false;
-
- if (not ConvertAudioFormatToSDL(srcFormatInfo.Format, srcFormat) or
- not ConvertAudioFormatToSDL(dstFormatInfo.Format, dstFormat)) then
- begin
- Log.LogError('Audio-format not supported by SDL', 'TSoftMixerPlaybackStream.InitFormatConversion');
- Exit;
- end;
-
- if (SDL_BuildAudioCVT(@cvt,
- srcFormat, srcFormatInfo.Channels, Round(srcFormatInfo.SampleRate),
- dstFormat, dstFormatInfo.Channels, Round(dstFormatInfo.SampleRate)) = -1) then
- begin
- Log.LogError(SDL_GetError(), 'TSoftMixerPlaybackStream.InitFormatConversion');
- Exit;
- end;
-
- Result := true;
-end;
-
-destructor TAudioConverter_SDL.Destroy();
-begin
- // nothing to be done here
- inherited;
-end;
-
-(*
- * Returns the size of the output buffer. This might be bigger than the actual
- * size of resampled audio data.
- *)
-function TAudioConverter_SDL.GetOutputBufferSize(InputSize: integer): integer;
-begin
- // Note: len_ratio must not be used here. Even if the len_ratio is 1.0, len_mult might be 2.
- // Example: 44.1kHz/mono to 22.05kHz/stereo -> len_ratio=1, len_mult=2
- Result := InputSize * cvt.len_mult;
-end;
-
-function TAudioConverter_SDL.GetRatio(): double;
-begin
- Result := cvt.len_ratio;
-end;
-
-function TAudioConverter_SDL.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
-begin
- Result := -1;
-
- if (InputSize <= 0) then
- begin
- // avoid div-by-zero problems
- if (InputSize = 0) then
- Result := 0;
- Exit;
- end;
-
- // OutputBuffer is always bigger than or equal to InputBuffer
- Move(InputBuffer[0], OutputBuffer[0], InputSize);
- cvt.buf := PUint8(OutputBuffer);
- cvt.len := InputSize;
- if (SDL_ConvertAudio(@cvt) = -1) then
- Exit;
-
- Result := cvt.len_cvt;
-end;
-
-
-{$IFDEF UseFFmpegResample}
-
-function TAudioConverter_FFmpeg.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
-begin
- inherited Init(SrcFormatInfo, DstFormatInfo);
-
- Result := false;
-
- // Note: ffmpeg does not support resampling for more than 2 input channels
-
- if (srcFormatInfo.Format <> asfS16) then
- begin
- Log.LogError('Unsupported format', 'TAudioConverter_FFmpeg.Init');
- Exit;
- end;
-
- // TODO: use SDL here
- if (srcFormatInfo.Format <> dstFormatInfo.Format) then
- begin
- Log.LogError('Incompatible formats', 'TAudioConverter_FFmpeg.Init');
- Exit;
- end;
-
- ResampleContext := audio_resample_init(
- dstFormatInfo.Channels, srcFormatInfo.Channels,
- Round(dstFormatInfo.SampleRate), Round(srcFormatInfo.SampleRate));
- if (ResampleContext = nil) then
- begin
- Log.LogError('audio_resample_init() failed', 'TAudioConverter_FFmpeg.Init');
- Exit;
- end;
-
- // calculate ratio
- Ratio := (dstFormatInfo.Channels / srcFormatInfo.Channels) *
- (dstFormatInfo.SampleRate / srcFormatInfo.SampleRate);
-
- Result := true;
-end;
-
-destructor TAudioConverter_FFmpeg.Destroy();
-begin
- if (ResampleContext <> nil) then
- audio_resample_close(ResampleContext);
- inherited;
-end;
-
-function TAudioConverter_FFmpeg.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
-var
- InputSampleCount: integer;
- OutputSampleCount: integer;
-begin
- Result := -1;
-
- if (InputSize <= 0) then
- begin
- // avoid div-by-zero in audio_resample()
- if (InputSize = 0) then
- Result := 0;
- Exit;
- end;
-
- InputSampleCount := InputSize div SrcFormatInfo.FrameSize;
- OutputSampleCount := audio_resample(
- ResampleContext, PSmallInt(OutputBuffer), PSmallInt(InputBuffer),
- InputSampleCount);
- if (OutputSampleCount = -1) then
- begin
- Log.LogError('audio_resample() failed', 'TAudioConverter_FFmpeg.Convert');
- Exit;
- end;
- Result := OutputSampleCount * DstFormatInfo.FrameSize;
-end;
-
-function TAudioConverter_FFmpeg.GetOutputBufferSize(InputSize: integer): integer;
-begin
- Result := Ceil(InputSize * GetRatio());
-end;
-
-function TAudioConverter_FFmpeg.GetRatio(): double;
-begin
- Result := Ratio;
-end;
-
-{$ENDIF}
-
-
-{$IFDEF UseSRCResample}
-
-function TAudioConverter_SRC.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
-var
- error: integer;
- TempSrcFormatInfo: TAudioFormatInfo;
- TempDstFormatInfo: TAudioFormatInfo;
-begin
- inherited Init(SrcFormatInfo, DstFormatInfo);
-
- Result := false;
-
- FormatConverter := nil;
-
- // SRC does not handle channel or format conversion
- if ((SrcFormatInfo.Channels <> DstFormatInfo.Channels) or
- not (SrcFormatInfo.Format in [asfS16, asfFloat])) then
- begin
- // SDL can not convert to float, so we have to convert to SInt16 first
- TempSrcFormatInfo := TAudioFormatInfo.Create(
- SrcFormatInfo.Channels, SrcFormatInfo.SampleRate, SrcFormatInfo.Format);
- TempDstFormatInfo := TAudioFormatInfo.Create(
- DstFormatInfo.Channels, SrcFormatInfo.SampleRate, asfS16);
-
- // init format/channel conversion
- FormatConverter := TAudioConverter_SDL.Create();
- if (not FormatConverter.Init(TempSrcFormatInfo, TempDstFormatInfo)) then
- begin
- Log.LogError('Unsupported input format', 'TAudioConverter_SRC.Init');
- FormatConverter.Free;
- // exit after the format-info is freed
- end;
-
- // this info was copied so we do not need it anymore
- TempSrcFormatInfo.Free;
- TempDstFormatInfo.Free;
-
- // leave if the format is not supported
- if (not assigned(FormatConverter)) then
- Exit;
-
- // adjust our copy of the input audio-format for SRC conversion
- Self.SrcFormatInfo.Channels := DstFormatInfo.Channels;
- Self.SrcFormatInfo.Format := asfS16;
- end;
-
- if ((DstFormatInfo.Format <> asfS16) and
- (DstFormatInfo.Format <> asfFloat)) then
- begin
- Log.LogError('Unsupported output format', 'TAudioConverter_SRC.Init');
- Exit;
- end;
-
- ConversionData.src_ratio := DstFormatInfo.SampleRate / SrcFormatInfo.SampleRate;
- if (src_is_valid_ratio(ConversionData.src_ratio) = 0) then
- begin
- Log.LogError('Invalid samplerate ratio', 'TAudioConverter_SRC.Init');
- Exit;
- end;
-
- ConverterState := src_new(SRC_CONVERTER_TYPE, DstFormatInfo.Channels, @error);
- if (ConverterState = nil) then
- begin
- Log.LogError('src_new() failed: ' + src_strerror(error), 'TAudioConverter_SRC.Init');
- Exit;
- end;
-
- Result := true;
-end;
-
-destructor TAudioConverter_SRC.Destroy();
-begin
- if (ConverterState <> nil) then
- src_delete(ConverterState);
- FormatConverter.Free;
- inherited;
-end;
-
-function TAudioConverter_SRC.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
-var
- FloatInputBuffer: PSingle;
- FloatOutputBuffer: PSingle;
- TempBuffer: PChar;
- TempSize: integer;
- NumSamples: integer;
- OutputSize: integer;
- error: integer;
-begin
- Result := -1;
-
- TempBuffer := nil;
-
- // format conversion with external converter (to correct number of channels and format)
- if (assigned(FormatConverter)) then
- begin
- TempSize := FormatConverter.GetOutputBufferSize(InputSize);
- GetMem(TempBuffer, TempSize);
- InputSize := FormatConverter.Convert(InputBuffer, TempBuffer, InputSize);
- InputBuffer := TempBuffer;
- end;
-
- if (InputSize <= 0) then
- begin
- // avoid div-by-zero problems
- if (InputSize = 0) then
- Result := 0;
- if (TempBuffer <> nil) then
- FreeMem(TempBuffer);
- Exit;
- end;
-
- if (SrcFormatInfo.Format = asfFloat) then
- begin
- FloatInputBuffer := PSingle(InputBuffer);
- end else begin
- NumSamples := InputSize div AudioSampleSize[SrcFormatInfo.Format];
- GetMem(FloatInputBuffer, NumSamples * SizeOf(Single));
- src_short_to_float_array(PCshort(InputBuffer), PCfloat(FloatInputBuffer), NumSamples);
- end;
-
- // calculate approx. output size
- OutputSize := Ceil(InputSize * ConversionData.src_ratio);
-
- if (DstFormatInfo.Format = asfFloat) then
- begin
- FloatOutputBuffer := PSingle(OutputBuffer);
- end else begin
- NumSamples := OutputSize div AudioSampleSize[DstFormatInfo.Format];
- GetMem(FloatOutputBuffer, NumSamples * SizeOf(Single));
- end;
-
- with ConversionData do
- begin
- data_in := PCFloat(FloatInputBuffer);
- input_frames := InputSize div SrcFormatInfo.FrameSize;
- data_out := PCFloat(FloatOutputBuffer);
- output_frames := OutputSize div DstFormatInfo.FrameSize;
- // TODO: set this to 1 at end of file-playback
- end_of_input := 0;
- end;
-
- error := src_process(ConverterState, @ConversionData);
- if (error <> 0) then
- begin
- Log.LogError(src_strerror(error), 'TAudioConverter_SRC.Convert');
- if (SrcFormatInfo.Format <> asfFloat) then
- FreeMem(FloatInputBuffer);
- if (DstFormatInfo.Format <> asfFloat) then
- FreeMem(FloatOutputBuffer);
- if (TempBuffer <> nil) then
- FreeMem(TempBuffer);
- Exit;
- end;
-
- if (SrcFormatInfo.Format <> asfFloat) then
- FreeMem(FloatInputBuffer);
-
- if (DstFormatInfo.Format <> asfFloat) then
- begin
- NumSamples := ConversionData.output_frames_gen * DstFormatInfo.Channels;
- src_float_to_short_array(PCfloat(FloatOutputBuffer), PCshort(OutputBuffer), NumSamples);
- FreeMem(FloatOutputBuffer);
- end;
-
- // free format conversion buffer if used
- if (TempBuffer <> nil) then
- FreeMem(TempBuffer);
-
- if (assigned(FormatConverter)) then
- InputSize := ConversionData.input_frames_used * FormatConverter.SrcFormatInfo.FrameSize
- else
- InputSize := ConversionData.input_frames_used * SrcFormatInfo.FrameSize;
-
- // set result to output size according to SRC
- Result := ConversionData.output_frames_gen * DstFormatInfo.FrameSize;
-end;
-
-function TAudioConverter_SRC.GetOutputBufferSize(InputSize: integer): integer;
-begin
- Result := Ceil(InputSize * GetRatio());
-end;
-
-function TAudioConverter_SRC.GetRatio(): double;
-begin
- // if we need additional channel/format conversion, use this ratio
- if (assigned(FormatConverter)) then
- Result := FormatConverter.GetRatio()
- else
- Result := 1.0;
-
- // now the SRC ratio (Note: the format might change from SInt16 to float)
- Result := Result *
- ConversionData.src_ratio *
- (DstFormatInfo.FrameSize / SrcFormatInfo.FrameSize);
-end;
-
-{$ENDIF}
-
-end.
\ No newline at end of file
diff --git a/Game/Code/Classes/UAudioCore_Bass.pas b/Game/Code/Classes/UAudioCore_Bass.pas
deleted file mode 100644
index beb2db16..00000000
--- a/Game/Code/Classes/UAudioCore_Bass.pas
+++ /dev/null
@@ -1,123 +0,0 @@
-unit UAudioCore_Bass;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Classes,
- SysUtils,
- UMusic,
- bass; // (Note: DWORD is defined here)
-
-type
- TAudioCore_Bass = class
- public
- constructor Create();
- class function GetInstance(): TAudioCore_Bass;
- function ErrorGetString(): string; overload;
- function ErrorGetString(errCode: integer): string; overload;
- function ConvertAudioFormatToBASSFlags(Format: TAudioSampleFormat; out Flags: DWORD): boolean;
- function ConvertBASSFlagsToAudioFormat(Flags: DWORD; out Format: TAudioSampleFormat): boolean;
- end;
-
-implementation
-
-uses
- UMain,
- ULog;
-
-var
- Instance: TAudioCore_Bass;
-
-constructor TAudioCore_Bass.Create();
-begin
- inherited;
-end;
-
-class function TAudioCore_Bass.GetInstance(): TAudioCore_Bass;
-begin
- if (not Assigned(Instance)) then
- Instance := TAudioCore_Bass.Create();
- Result := Instance;
-end;
-
-function TAudioCore_Bass.ErrorGetString(): string;
-begin
- Result := ErrorGetString(BASS_ErrorGetCode());
-end;
-
-function TAudioCore_Bass.ErrorGetString(errCode: integer): string;
-begin
- case errCode of
- BASS_OK: result := 'No error';
- BASS_ERROR_MEM: result := 'Insufficient memory';
- BASS_ERROR_FILEOPEN: result := 'File could not be opened';
- BASS_ERROR_DRIVER: result := 'Device driver not available';
- BASS_ERROR_BUFLOST: result := 'Buffer lost';
- BASS_ERROR_HANDLE: result := 'Invalid Handle';
- BASS_ERROR_FORMAT: result := 'Sample-Format not supported';
- BASS_ERROR_POSITION: result := 'Illegal position';
- BASS_ERROR_INIT: result := 'BASS_Init has not been successfully called';
- BASS_ERROR_START: result := 'Paused/stopped';
- BASS_ERROR_ALREADY: result := 'Already created/used';
- BASS_ERROR_NOCHAN: result := 'No free channels';
- BASS_ERROR_ILLTYPE: result := 'Type is invalid';
- BASS_ERROR_ILLPARAM: result := 'Illegal parameter';
- BASS_ERROR_NO3D: result := 'No 3D support';
- BASS_ERROR_NOEAX: result := 'No EAX support';
- BASS_ERROR_DEVICE: result := 'Invalid device number';
- BASS_ERROR_NOPLAY: result := 'Channel not playing';
- BASS_ERROR_FREQ: result := 'Freq out of range';
- BASS_ERROR_NOTFILE: result := 'Not a file stream';
- BASS_ERROR_NOHW: result := 'No hardware support';
- BASS_ERROR_EMPTY: result := 'Is empty';
- BASS_ERROR_NONET: result := 'Network unavailable';
- BASS_ERROR_CREATE: result := 'Creation error';
- BASS_ERROR_NOFX: result := 'DX8 effects unavailable';
- BASS_ERROR_NOTAVAIL: result := 'Not available';
- BASS_ERROR_DECODE: result := 'Is a decoding channel';
- BASS_ERROR_DX: result := 'Insufficient version of DirectX';
- BASS_ERROR_TIMEOUT: result := 'Timeout';
- BASS_ERROR_FILEFORM: result := 'File-Format not recognised/supported';
- BASS_ERROR_SPEAKER: result := 'Requested speaker(s) not support';
- BASS_ERROR_VERSION: result := 'Version error';
- BASS_ERROR_CODEC: result := 'Codec not available/supported';
- BASS_ERROR_ENDED: result := 'The channel/file has ended';
- BASS_ERROR_UNKNOWN: result := 'Unknown error';
- else result := 'Unknown error';
- end;
-end;
-
-function TAudioCore_Bass.ConvertAudioFormatToBASSFlags(Format: TAudioSampleFormat; out Flags: DWORD): boolean;
-begin
- case Format of
- asfS16: Flags := 0;
- asfFloat: Flags := BASS_SAMPLE_FLOAT;
- asfU8: Flags := BASS_SAMPLE_8BITS;
- else begin
- Result := false;
- Exit;
- end;
- end;
-
- Result := true;
-end;
-
-function TAudioCore_Bass.ConvertBASSFlagsToAudioFormat(Flags: DWORD; out Format: TAudioSampleFormat): boolean;
-begin
- if ((Flags and BASS_SAMPLE_FLOAT) <> 0) then
- Format := asfFloat
- else if ((Flags and BASS_SAMPLE_8BITS) <> 0) then
- Format := asfU8
- else
- Format := asfS16;
-
- Result := true;
-end;
-
-end.
diff --git a/Game/Code/Classes/UAudioCore_Portaudio.pas b/Game/Code/Classes/UAudioCore_Portaudio.pas
deleted file mode 100644
index bcc8a001..00000000
--- a/Game/Code/Classes/UAudioCore_Portaudio.pas
+++ /dev/null
@@ -1,257 +0,0 @@
-unit UAudioCore_Portaudio;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I ../switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- portaudio;
-
-type
- TAudioCore_Portaudio = class
- public
- constructor Create();
- class function GetInstance(): TAudioCore_Portaudio;
- function GetPreferredApiIndex(): TPaHostApiIndex;
- function TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: Double): boolean;
- end;
-
-implementation
-
-uses
- ULog;
-
-{*
- * The default API used by Portaudio is the least common denominator
- * and might lack efficiency. In addition it might not even work.
- * We use an array named ApiPreferenceOrder with which we define the order of
- * preferred APIs to use. The first API-type in the list is tried first.
- * If it is not available the next one is tried and so on ...
- * If none of the preferred APIs was found the default API (detected by
- * portaudio) is used.
- *
- * Pascal does not permit zero-length static arrays, so you must use paDefaultApi
- * as an array's only member if you do not have any preferences.
- * You can also append paDefaultApi to a non-zero length preferences array but
- * this is optional because the default API is always used as a fallback.
- *}
-const
- paDefaultApi = -1;
-const
- ApiPreferenceOrder:
-{$IF Defined(MSWINDOWS)}
- // Note1: Portmixer has no mixer support for paASIO and paWASAPI at the moment
- // Note2: Windows Default-API is MME, but DirectSound is faster
- array[0..0] of TPaHostApiTypeId = ( paDirectSound );
-{$ELSEIF Defined(LINUX)}
- // Note: Portmixer has no mixer support for JACK at the moment
- array[0..2] of TPaHostApiTypeId = ( paALSA, paJACK, paOSS );
-{$ELSEIF Defined(DARWIN)}
- array[0..0] of TPaHostApiTypeId = ( paDefaultApi ); // paCoreAudio
-{$ELSE}
- array[0..0] of TPaHostApiTypeId = ( paDefaultApi );
-{$IFEND}
-
-
-{ TAudioInput_Portaudio }
-
-var
- Instance: TAudioCore_Portaudio;
-
-constructor TAudioCore_Portaudio.Create();
-begin
- inherited;
-end;
-
-class function TAudioCore_Portaudio.GetInstance(): TAudioCore_Portaudio;
-begin
- if not assigned(Instance) then
- Instance := TAudioCore_Portaudio.Create();
- Result := Instance;
-end;
-
-function TAudioCore_Portaudio.GetPreferredApiIndex(): TPaHostApiIndex;
-var
- i: integer;
- apiIndex: TPaHostApiIndex;
- apiInfo: PPaHostApiInfo;
-begin
- result := -1;
-
- // select preferred sound-API
- for i:= 0 to High(ApiPreferenceOrder) do
- begin
- if(ApiPreferenceOrder[i] <> paDefaultApi) then
- begin
- // check if API is available
- apiIndex := Pa_HostApiTypeIdToHostApiIndex(ApiPreferenceOrder[i]);
- if(apiIndex >= 0) then
- begin
- // we found an API but we must check if it works
- // (on linux portaudio might detect OSS but does not provide
- // any devices if ALSA is enabled)
- apiInfo := Pa_GetHostApiInfo(apiIndex);
- if (apiInfo^.deviceCount > 0) then
- begin
- Result := apiIndex;
- break;
- end;
- end;
- end;
- end;
-
- // None of the preferred APIs is available -> use default
- if(result < 0) then
- begin
- result := Pa_GetDefaultHostApi();
- end;
-end;
-
-{*
- * Portaudio test callback used by TestDevice().
- *}
-function TestCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl;
-begin
- // this callback is called only once
- result := paAbort;
-end;
-
-(*
- * Tests if the callback works. Some devices can be opened without
- * an error but the callback is never called. Calling Pa_StopStream() on such
- * a stream freezes USDX then. Probably because the callback-thread is deadlocked
- * due to some bug in portaudio. The blocking Pa_ReadStream() and Pa_WriteStream()
- * block forever too and though can't be used for testing.
- *
- * To avoid freezing Pa_AbortStream (or Pa_CloseStream which calls Pa_AbortStream)
- * can be used to force the stream to stop. But for some reason this stops debugging
- * in gdb with a "no process found" message.
- *
- * Because freezing devices are non-working devices we test the devices here to
- * be able to exclude them from the device-selection list.
- *
- * Portaudio does not provide any test to check this error case (probably because
- * it should not even occur). So we have to open the device, start the stream and
- * check if the callback is called (the stream is stopped if the callback is called
- * for the first time, so we can poll until the stream is stopped).
- *
- * Another error that occurs is that some devices (even the default device) might
- * work at the beginning but stop after a few calls (maybe 50) of the callback.
- * For me this problem occurs with the default output-device. The "dmix" or "front"
- * device must be selected instead. Another problem is that (due to a bug in
- * portaudio or ALSA) the "front" device is not detected every time portaudio
- * is started. Sometimes it needs two or more restarts.
- *
- * There is no reasonable way to test for these errors. For the first error-case
- * we could test if the callback is called 50 times but this can take a second
- * for each device and it can fail in the 51st or even 100th callback call then.
- *
- * The second error-case cannot be tested at all. How should we now that one
- * device is missing if portaudio is not even able to detect it.
- * We could start and terminate Portaudio for several times and see if the device
- * count changes but this is ugly.
- *
- * Conclusion: We are not able to autodetect a working device with
- * portaudio (at least not with the newest v19_20071207) at the moment.
- * So we have to provide the possibility to manually select an output device
- * in the UltraStar options if we want to use portaudio instead of SDL.
- *)
-function TAudioCore_Portaudio.TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: Double): boolean;
-var
- stream: PPaStream;
- err: TPaError;
- cbWorks: boolean;
- cbPolls: integer;
- i: integer;
-const
- altSampleRates: array[0..1] of Double = (44100, 48000); // alternative sample-rates
-begin
- Result := false;
-
- if (sampleRate <= 0) then
- sampleRate := 44100;
-
- // check if device supports our input-format
- err := Pa_IsFormatSupported(inParams, outParams, sampleRate);
- if(err <> paNoError) then
- begin
- // we cannot fix the error -> exit
- if (err <> paInvalidSampleRate) then
- Exit;
-
- // try alternative sample-rates to the detected one
- sampleRate := 0;
- for i := 0 to High(altSampleRates) do
- begin
- // do not check the detected sample-rate twice
- if (altSampleRates[i] = sampleRate) then
- continue;
- // check alternative
- err := Pa_IsFormatSupported(inParams, outParams, altSampleRates[i]);
- if (err = paNoError) then
- begin
- // sample-rate works
- sampleRate := altSampleRates[i];
- break;
- end;
- end;
- // no working sample-rate found
- if (sampleRate = 0) then
- Exit;
- end;
-
- // FIXME: for some reason gdb stops after a call of Pa_AbortStream()
- // which is implicitely called by Pa_CloseStream().
- // gdb's stops with the message: "ptrace: no process found".
- // Probably because the callback-thread is killed what confuses gdb.
- {$IF Defined(Debug) and Defined(Linux)}
- cbWorks := true;
- {$ELSE}
- // open device for testing
- err := Pa_OpenStream(stream, inParams, outParams, sampleRate,
- paFramesPerBufferUnspecified,
- paNoFlag, @TestCallback, nil);
- if(err <> paNoError) then
- begin
- exit;
- end;
-
- // start the callback
- err := Pa_StartStream(stream);
- if(err <> paNoError) then
- begin
- Pa_CloseStream(stream);
- exit;
- end;
-
- cbWorks := false;
- // check if the callback was called (poll for max. 200ms)
- for cbPolls := 1 to 20 do
- begin
- // if the test-callback was called it should be aborted now
- if (Pa_IsStreamActive(stream) = 0) then
- begin
- cbWorks := true;
- break;
- end;
- // not yet aborted, wait and try (poll) again
- Pa_Sleep(10);
- end;
-
- // finally abort the stream
- Pa_CloseStream(stream);
- {$IFEND}
-
- Result := cbWorks;
-end;
-
-end.
diff --git a/Game/Code/Classes/UAudioDecoder_Bass.pas b/Game/Code/Classes/UAudioDecoder_Bass.pas
deleted file mode 100644
index dba1fde4..00000000
--- a/Game/Code/Classes/UAudioDecoder_Bass.pas
+++ /dev/null
@@ -1,242 +0,0 @@
-unit UAudioDecoder_Bass;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-implementation
-
-uses
- Classes,
- SysUtils,
- UMain,
- UMusic,
- UAudioCore_Bass,
- ULog,
- bass;
-
-type
- TBassDecodeStream = class(TAudioDecodeStream)
- private
- Handle: HSTREAM;
- FormatInfo : TAudioFormatInfo;
- Error: boolean;
- public
- constructor Create(Handle: HSTREAM);
- destructor Destroy(); override;
-
- procedure Close(); override;
-
- function GetLength(): real; override;
- function GetAudioFormatInfo(): TAudioFormatInfo; override;
- function GetPosition: real; override;
- procedure SetPosition(Time: real); override;
- function GetLoop(): boolean; override;
- procedure SetLoop(Enabled: boolean); override;
- function IsEOF(): boolean; override;
- function IsError(): boolean; override;
-
- function ReadData(Buffer: PChar; BufSize: integer): integer; override;
- end;
-
-type
- TAudioDecoder_Bass = class( TInterfacedObject, IAudioDecoder )
- public
- function GetName: string;
-
- function InitializeDecoder(): boolean;
- function FinalizeDecoder(): boolean;
- function Open(const Filename: string): TAudioDecodeStream;
- end;
-
-var
- BassCore: TAudioCore_Bass;
-
-
-{ TBassDecodeStream }
-
-constructor TBassDecodeStream.Create(Handle: HSTREAM);
-var
- ChannelInfo: BASS_CHANNELINFO;
- Format: TAudioSampleFormat;
-begin
- inherited Create();
- Self.Handle := Handle;
-
- // setup format info
- if (not BASS_ChannelGetInfo(Handle, ChannelInfo)) then
- begin
- raise Exception.Create('Failed to open decode-stream');
- end;
- BassCore.ConvertBASSFlagsToAudioFormat(ChannelInfo.flags, Format);
- FormatInfo := TAudioFormatInfo.Create(ChannelInfo.chans, ChannelInfo.freq, format);
-
- Error := false;
-end;
-
-destructor TBassDecodeStream.Destroy();
-begin
- Close();
- inherited;
-end;
-
-procedure TBassDecodeStream.Close();
-begin
- if (Handle <> 0) then
- begin
- BASS_StreamFree(Handle);
- Handle := 0;
- end;
- PerformOnClose();
- FreeAndNil(FormatInfo);
- Error := false;
-end;
-
-function TBassDecodeStream.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- Result := FormatInfo;
-end;
-
-function TBassDecodeStream.GetLength(): real;
-var
- bytes: QWORD;
-begin
- bytes := BASS_ChannelGetLength(Handle, BASS_POS_BYTE);
- Result := BASS_ChannelBytes2Seconds(Handle, bytes);
-end;
-
-function TBassDecodeStream.GetPosition: real;
-var
- bytes: QWORD;
-begin
- bytes := BASS_ChannelGetPosition(Handle, BASS_POS_BYTE);
- Result := BASS_ChannelBytes2Seconds(Handle, bytes);
-end;
-
-procedure TBassDecodeStream.SetPosition(Time: real);
-var
- bytes: QWORD;
-begin
- bytes := BASS_ChannelSeconds2Bytes(Handle, Time);
- BASS_ChannelSetPosition(Handle, bytes, BASS_POS_BYTE);
-end;
-
-function TBassDecodeStream.GetLoop(): boolean;
-var
- flags: DWORD;
-begin
- // retrieve channel flags
- flags := BASS_ChannelFlags(Handle, 0, 0);
- if (flags = DWORD(-1)) then
- begin
- Log.LogError('BASS_ChannelFlags: ' + BassCore.ErrorGetString(), 'TBassDecodeStream.GetLoop');
- Result := false;
- Exit;
- end;
- Result := (flags and BASS_SAMPLE_LOOP) <> 0;
-end;
-
-procedure TBassDecodeStream.SetLoop(Enabled: boolean);
-var
- flags: DWORD;
-begin
- // set/unset loop-flag
- if (Enabled) then
- flags := BASS_SAMPLE_LOOP
- else
- flags := 0;
-
- // set new flag-bits
- if (BASS_ChannelFlags(Handle, flags, BASS_SAMPLE_LOOP) = DWORD(-1)) then
- begin
- Log.LogError('BASS_ChannelFlags: ' + BassCore.ErrorGetString(), 'TBassDecodeStream.SetLoop');
- Exit;
- end;
-end;
-
-function TBassDecodeStream.IsEOF(): boolean;
-begin
- Result := (BASS_ChannelIsActive(Handle) = BASS_ACTIVE_STOPPED);
-end;
-
-function TBassDecodeStream.IsError(): boolean;
-begin
- Result := Error;
-end;
-
-function TBassDecodeStream.ReadData(Buffer: PChar; BufSize: integer): integer;
-begin
- Result := BASS_ChannelGetData(Handle, Buffer, BufSize);
- // check error state (do not handle EOF as error)
- if ((Result = -1) and (BASS_ErrorGetCode() <> BASS_ERROR_ENDED)) then
- Error := true
- else
- Error := false;
-end;
-
-
-{ TAudioDecoder_Bass }
-
-function TAudioDecoder_Bass.GetName: String;
-begin
- result := 'BASS_Decoder';
-end;
-
-function TAudioDecoder_Bass.InitializeDecoder(): boolean;
-begin
- BassCore := TAudioCore_Bass.GetInstance();
- Result := true;
-end;
-
-function TAudioDecoder_Bass.FinalizeDecoder(): boolean;
-begin
- Result := true;
-end;
-
-function TAudioDecoder_Bass.Open(const Filename: string): TAudioDecodeStream;
-var
- Stream: HSTREAM;
- ChannelInfo: BASS_CHANNELINFO;
- FileExt: string;
-begin
- Result := nil;
-
- // check if BASS was initialized
- // in case the decoder is not used with BASS playback, init the NO_SOUND device
- if ((integer(BASS_GetDevice) = -1) and (BASS_ErrorGetCode() = BASS_ERROR_INIT)) then
- BASS_Init(0, 44100, 0, 0, nil);
-
- // TODO: use BASS_STREAM_PRESCAN for accurate seeking in VBR-files?
- // disadvantage: seeking will slow down.
- Stream := BASS_StreamCreateFile(False, PChar(Filename), 0, 0, BASS_STREAM_DECODE);
- if (Stream = 0) then
- begin
- //Log.LogError(BassCore.ErrorGetString(), 'TAudioDecoder_Bass.Open');
- Exit;
- end;
-
- // check if BASS opened some erroneously recognized file-formats
- if BASS_ChannelGetInfo(Stream, channelInfo) then
- begin
- fileExt := ExtractFileExt(Filename);
- // BASS opens FLV-files (maybe others too) although it cannot handle them.
- // Setting BASS_CONFIG_VERIFY to the max. value (100000) does not help.
- if ((fileExt = '.flv') and (channelInfo.ctype = BASS_CTYPE_STREAM_MP1)) then
- begin
- BASS_StreamFree(Stream);
- Exit;
- end;
- end;
-
- Result := TBassDecodeStream.Create(Stream);
-end;
-
-
-initialization
- MediaManager.Add(TAudioDecoder_Bass.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioDecoder_FFmpeg.pas b/Game/Code/Classes/UAudioDecoder_FFmpeg.pas
deleted file mode 100644
index d9b4c93c..00000000
--- a/Game/Code/Classes/UAudioDecoder_FFmpeg.pas
+++ /dev/null
@@ -1,1114 +0,0 @@
-unit UAudioDecoder_FFmpeg;
-
-(*******************************************************************************
- *
- * This unit is primarily based upon -
- * http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html
- *
- * and tutorial03.c
- *
- * http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
- *
- *******************************************************************************)
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-// show FFmpeg specific debug output
-{.$DEFINE DebugFFmpegDecode}
-
-// FFmpeg is very verbose and shows a bunch of errors.
-// Those errors (they can be considered as warnings by us) can be ignored
-// as they do not give any useful information.
-// There is no solution to fix this except for turning them off.
-{.$DEFINE EnableFFmpegErrorOutput}
-
-implementation
-
-uses
- Classes,
- SysUtils,
- Math,
- UMusic,
- UIni,
- UMain,
- avcodec,
- avformat,
- avutil,
- avio,
- mathematics, // used for av_rescale_q
- rational,
- UMediaCore_FFmpeg,
- SDL,
- ULog,
- UCommon,
- UConfig;
-
-const
- MAX_AUDIOQ_SIZE = (5 * 16 * 1024);
-
-const
- // TODO: The factor 3/2 might not be necessary as we do not need extra
- // space for synchronizing as in the tutorial.
- AUDIO_BUFFER_SIZE = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) div 2;
-
-type
- TFFmpegDecodeStream = class(TAudioDecodeStream)
- private
- StateLock: PSDL_Mutex;
-
- EOFState: boolean; // end-of-stream flag (locked by StateLock)
- ErrorState: boolean; // error flag (locked by StateLock)
-
- QuitRequest: boolean; // (locked by StateLock)
- ParserIdleCond: PSDL_Cond;
-
- // parser pause/resume data
- ParserLocked: boolean;
- ParserPauseRequestCount: integer;
- ParserUnlockedCond: PSDL_Cond;
- ParserResumeCond: PSDL_Cond;
-
- SeekRequest: boolean; // (locked by StateLock)
- SeekFlags: integer; // (locked by StateLock)
- SeekPos: double; // stream position to seek for (in secs) (locked by StateLock)
- SeekFlush: boolean; // true if the buffers should be flushed after seeking (locked by StateLock)
- SeekFinishedCond: PSDL_Cond;
-
- Loop: boolean; // (locked by StateLock)
-
- ParseThread: PSDL_Thread;
- PacketQueue: TPacketQueue;
-
- FormatInfo: TAudioFormatInfo;
-
- // FFmpeg specific data
- FormatCtx: PAVFormatContext;
- CodecCtx: PAVCodecContext;
- Codec: PAVCodec;
-
- AudioStreamIndex: integer;
- AudioStream: PAVStream;
- AudioStreamPos: double; // stream position in seconds (locked by DecoderLock)
-
- // decoder pause/resume data
- DecoderLocked: boolean;
- DecoderPauseRequestCount: integer;
- DecoderUnlockedCond: PSDL_Cond;
- DecoderResumeCond: PSDL_Cond;
-
- // state-vars for DecodeFrame (locked by DecoderLock)
- AudioPaket: TAVPacket;
- AudioPaketData: PChar;
- AudioPaketSize: integer;
- AudioPaketSilence: integer; // number of bytes of silence to return
-
- // state-vars for AudioCallback (locked by DecoderLock)
- AudioBufferPos: integer;
- AudioBufferSize: integer;
- AudioBuffer: PChar;
-
- Filename: string;
-
- procedure SetPositionIntern(Time: real; Flush: boolean; Blocking: boolean);
- procedure SetEOF(State: boolean); {$IFDEF HasInline}inline;{$ENDIF}
- procedure SetError(State: boolean); {$IFDEF HasInline}inline;{$ENDIF}
- function IsSeeking(): boolean;
- function IsQuit(): boolean;
-
- procedure Reset();
-
- procedure Parse();
- function ParseLoop(): boolean;
- procedure PauseParser();
- procedure ResumeParser();
-
- function DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
- procedure FlushCodecBuffers();
- procedure PauseDecoder();
- procedure ResumeDecoder();
- public
- constructor Create();
- destructor Destroy(); override;
-
- function Open(const Filename: string): boolean;
- procedure Close(); override;
-
- function GetLength(): real; override;
- function GetAudioFormatInfo(): TAudioFormatInfo; override;
- function GetPosition: real; override;
- procedure SetPosition(Time: real); override;
- function GetLoop(): boolean; override;
- procedure SetLoop(Enabled: boolean); override;
- function IsEOF(): boolean; override;
- function IsError(): boolean; override;
-
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
- end;
-
-type
- TAudioDecoder_FFmpeg = class( TInterfacedObject, IAudioDecoder )
- public
- function GetName: string;
-
- function InitializeDecoder(): boolean;
- function FinalizeDecoder(): boolean;
- function Open(const Filename: string): TAudioDecodeStream;
- end;
-
-var
- FFmpegCore: TMediaCore_FFmpeg;
-
-function ParseThreadMain(Data: Pointer): integer; cdecl; forward;
-
-
-{ TFFmpegDecodeStream }
-
-constructor TFFmpegDecodeStream.Create();
-begin
- inherited Create();
-
- StateLock := SDL_CreateMutex();
- ParserUnlockedCond := SDL_CreateCond();
- ParserResumeCond := SDL_CreateCond();
- ParserIdleCond := SDL_CreateCond();
- SeekFinishedCond := SDL_CreateCond();
- DecoderUnlockedCond := SDL_CreateCond();
- DecoderResumeCond := SDL_CreateCond();
-
- // according to the documentation of avcodec_decode_audio(2), sample-data
- // should be aligned on a 16 byte boundary. Otherwise internal calls
- // (e.g. to SSE or Altivec operations) might fail or lack performance on some
- // CPUs. Although GetMem() in Delphi and FPC seems to use a 16 byte or higher
- // alignment for buffers of this size (alignment depends on the size of the
- // requested buffer), we will set the alignment explicitly as the minimum
- // alignment used by Delphi and FPC is on an 8 byte boundary.
- //
- // Note: AudioBuffer was previously defined as a field of type TAudioBuffer
- // (array[0..AUDIO_BUFFER_SIZE-1] of byte) and hence statically allocated.
- // Fields of records are aligned different to memory allocated with GetMem(),
- // aligning depending on the type but will be at least 2 bytes.
- // AudioBuffer was not aligned to a 16 byte boundary. The {$ALIGN x} directive
- // was not applicable as Delphi in contrast to FPC provides at most 8 byte
- // alignment ({$ALIGN 16} is not supported) by this directive.
- AudioBuffer := GetAlignedMem(AUDIO_BUFFER_SIZE, 16);
-
- Reset();
-end;
-
-procedure TFFmpegDecodeStream.Reset();
-begin
- ParseThread := nil;
-
- EOFState := false;
- ErrorState := false;
- Loop := false;
- QuitRequest := false;
-
- AudioPaketData := nil;
- AudioPaketSize := 0;
- AudioPaketSilence := 0;
-
- AudioBufferPos := 0;
- AudioBufferSize := 0;
-
- ParserLocked := false;
- ParserPauseRequestCount := 0;
- DecoderLocked := false;
- DecoderPauseRequestCount := 0;
-
- FillChar(AudioPaket, SizeOf(TAVPacket), 0);
-end;
-
-{*
- * Frees the decode-stream data.
- *}
-destructor TFFmpegDecodeStream.Destroy();
-begin
- Close();
-
- SDL_DestroyMutex(StateLock);
- SDL_DestroyCond(ParserUnlockedCond);
- SDL_DestroyCond(ParserResumeCond);
- SDL_DestroyCond(ParserIdleCond);
- SDL_DestroyCond(SeekFinishedCond);
- SDL_DestroyCond(DecoderUnlockedCond);
- SDL_DestroyCond(DecoderResumeCond);
-
- FreeAlignedMem(AudioBuffer);
-
- inherited;
-end;
-
-function TFFmpegDecodeStream.Open(const Filename: string): boolean;
-var
- SampleFormat: TAudioSampleFormat;
- AVResult: integer;
-begin
- Result := false;
-
- Close();
- Reset();
-
- if (not FileExists(Filename)) then
- begin
- Log.LogError('Audio-file does not exist: "' + Filename + '"', 'UAudio_FFmpeg');
- Exit;
- end;
-
- Self.Filename := Filename;
-
- // open audio file
- if (av_open_input_file(FormatCtx, PChar(Filename), nil, 0, nil) <> 0) then
- begin
- Log.LogError('av_open_input_file failed: "' + Filename + '"', 'UAudio_FFmpeg');
- Exit;
- end;
-
- // generate PTS values if they do not exist
- FormatCtx^.flags := FormatCtx^.flags or AVFMT_FLAG_GENPTS;
-
- // retrieve stream information
- if (av_find_stream_info(FormatCtx) < 0) then
- begin
- Log.LogError('av_find_stream_info failed: "' + Filename + '"', 'UAudio_FFmpeg');
- Close();
- Exit;
- end;
-
- // FIXME: hack used by ffplay. Maybe should not use url_feof() to test for the end
- FormatCtx^.pb.eof_reached := 0;
-
- {$IFDEF DebugFFmpegDecode}
- dump_format(FormatCtx, 0, pchar(Filename), 0);
- {$ENDIF}
-
- AudioStreamIndex := FFmpegCore.FindAudioStreamIndex(FormatCtx);
- if (AudioStreamIndex < 0) then
- begin
- Log.LogError('FindAudioStreamIndex: No Audio-stream found "' + Filename + '"', 'UAudio_FFmpeg');
- Close();
- Exit;
- end;
-
- //Log.LogStatus('AudioStreamIndex is: '+ inttostr(ffmpegStreamID), 'UAudio_FFmpeg');
-
- AudioStream := FormatCtx.streams[AudioStreamIndex];
- CodecCtx := AudioStream^.codec;
-
- // TODO: should we use this or not? Should we allow 5.1 channel audio?
- (*
- {$IF LIBAVCODEC_VERSION >= 51042000}
- if (CodecCtx^.channels > 0) then
- CodecCtx^.request_channels := Min(2, CodecCtx^.channels)
- else
- CodecCtx^.request_channels := 2;
- {$IFEND}
- *)
-
- Codec := avcodec_find_decoder(CodecCtx^.codec_id);
- if (Codec = nil) then
- begin
- Log.LogError('Unsupported codec!', 'UAudio_FFmpeg');
- CodecCtx := nil;
- Close();
- Exit;
- end;
-
- // set debug options
- CodecCtx^.debug_mv := 0;
- CodecCtx^.debug := 0;
-
- // detect bug-workarounds automatically
- CodecCtx^.workaround_bugs := FF_BUG_AUTODETECT;
- // error resilience strategy (careful/compliant/agressive/very_aggressive)
- //CodecCtx^.error_resilience := FF_ER_CAREFUL; //FF_ER_COMPLIANT;
- // allow non spec compliant speedup tricks.
- //CodecCtx^.flags2 := CodecCtx^.flags2 or CODEC_FLAG2_FAST;
-
- // Note: avcodec_open() and avcodec_close() are not thread-safe and will
- // fail if called concurrently by different threads.
- FFmpegCore.LockAVCodec();
- try
- AVResult := avcodec_open(CodecCtx, Codec);
- finally
- FFmpegCore.UnlockAVCodec();
- end;
- if (AVResult < 0) then
- begin
- Log.LogError('avcodec_open failed!', 'UAudio_FFmpeg');
- Close();
- Exit;
- end;
-
- // now initialize the audio-format
-
- if (not FFmpegCore.ConvertFFmpegToAudioFormat(CodecCtx^.sample_fmt, SampleFormat)) then
- begin
- // try standard format
- SampleFormat := asfS16;
- end;
-
- FormatInfo := TAudioFormatInfo.Create(
- CodecCtx^.channels,
- CodecCtx^.sample_rate,
- SampleFormat
- );
-
-
- PacketQueue := TPacketQueue.Create();
-
- // finally start the decode thread
- ParseThread := SDL_CreateThread(@ParseThreadMain, Self);
-
- Result := true;
-end;
-
-procedure TFFmpegDecodeStream.Close();
-var
- ThreadResult: integer;
-begin
- // wake threads waiting for packet-queue data
- // Note: normally, there are no waiting threads. If there were waiting
- // ones, they would block the audio-callback thread.
- if (assigned(PacketQueue)) then
- PacketQueue.Abort();
-
- // send quit request (to parse-thread etc)
- SDL_mutexP(StateLock);
- QuitRequest := true;
- SDL_CondBroadcast(ParserIdleCond);
- SDL_mutexV(StateLock);
-
- // abort parse-thread
- if (ParseThread <> nil) then
- begin
- // and wait until it terminates
- SDL_WaitThread(ParseThread, ThreadResult);
- ParseThread := nil;
- end;
-
- // Close the codec
- if (CodecCtx <> nil) then
- begin
- // avcodec_close() is not thread-safe
- FFmpegCore.LockAVCodec();
- try
- avcodec_close(CodecCtx);
- finally
- FFmpegCore.UnlockAVCodec();
- end;
- CodecCtx := nil;
- end;
-
- // Close the video file
- if (FormatCtx <> nil) then
- begin
- av_close_input_file(FormatCtx);
- FormatCtx := nil;
- end;
-
- PerformOnClose();
-
- FreeAndNil(PacketQueue);
- FreeAndNil(FormatInfo);
-end;
-
-function TFFmpegDecodeStream.GetLength(): real;
-begin
- // do not forget to consider the start_time value here
- Result := (FormatCtx^.start_time + FormatCtx^.duration) / AV_TIME_BASE;
-end;
-
-function TFFmpegDecodeStream.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- Result := FormatInfo;
-end;
-
-function TFFmpegDecodeStream.IsEOF(): boolean;
-begin
- SDL_mutexP(StateLock);
- Result := EOFState;
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.SetEOF(State: boolean);
-begin
- SDL_mutexP(StateLock);
- EOFState := State;
- SDL_mutexV(StateLock);
-end;
-
-function TFFmpegDecodeStream.IsError(): boolean;
-begin
- SDL_mutexP(StateLock);
- Result := ErrorState;
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.SetError(State: boolean);
-begin
- SDL_mutexP(StateLock);
- ErrorState := State;
- SDL_mutexV(StateLock);
-end;
-
-function TFFmpegDecodeStream.IsSeeking(): boolean;
-begin
- SDL_mutexP(StateLock);
- Result := SeekRequest;
- SDL_mutexV(StateLock);
-end;
-
-function TFFmpegDecodeStream.IsQuit(): boolean;
-begin
- SDL_mutexP(StateLock);
- Result := QuitRequest;
- SDL_mutexV(StateLock);
-end;
-
-function TFFmpegDecodeStream.GetPosition(): real;
-var
- BufferSizeSec: double;
-begin
- PauseDecoder();
-
- // ReadData() does not return all of the buffer retrieved by DecodeFrame().
- // Determine the size of the unused part of the decode-buffer.
- BufferSizeSec := (AudioBufferSize - AudioBufferPos) /
- FormatInfo.BytesPerSec;
-
- // subtract the size of unused buffer-data from the audio clock.
- Result := AudioStreamPos - BufferSizeSec;
-
- ResumeDecoder();
-end;
-
-procedure TFFmpegDecodeStream.SetPosition(Time: real);
-begin
- SetPositionIntern(Time, true, true);
-end;
-
-function TFFmpegDecodeStream.GetLoop(): boolean;
-begin
- SDL_mutexP(StateLock);
- Result := Loop;
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.SetLoop(Enabled: boolean);
-begin
- SDL_mutexP(StateLock);
- Loop := Enabled;
- SDL_mutexV(StateLock);
-end;
-
-
-(********************************************
- * Parser section
- ********************************************)
-
-procedure TFFmpegDecodeStream.PauseParser();
-begin
- if (SDL_ThreadID() = ParseThread.threadid) then
- Exit;
-
- SDL_mutexP(StateLock);
- Inc(ParserPauseRequestCount);
- while (ParserLocked) do
- SDL_CondWait(ParserUnlockedCond, StateLock);
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.ResumeParser();
-begin
- if (SDL_ThreadID() = ParseThread.threadid) then
- Exit;
-
- SDL_mutexP(StateLock);
- Dec(ParserPauseRequestCount);
- SDL_CondSignal(ParserResumeCond);
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.SetPositionIntern(Time: real; Flush: boolean; Blocking: boolean);
-begin
- // - Pause the parser first to prevent it from putting obsolete packages
- // into the queue after the queue was flushed and before seeking is done.
- // Otherwise we will hear fragments of old data, if the stream was seeked
- // in stopped mode and resumed afterwards (applies to non-blocking mode only).
- // - Pause the decoder to avoid race-condition that might occur otherwise.
- // - Last lock the state lock because we are manipulating some shared state-vars.
- PauseParser();
- PauseDecoder();
- SDL_mutexP(StateLock);
-
- // configure seek parameters
- SeekPos := Time;
- SeekFlush := Flush;
- SeekFlags := AVSEEK_FLAG_ANY;
- SeekRequest := true;
-
- // Note: the BACKWARD-flag seeks to the first position <= the position
- // searched for. Otherwise e.g. position 0 might not be seeked correct.
- // For some reason ffmpeg sometimes doesn't use position 0 but the key-frame
- // following. In streams with few key-frames (like many flv-files) the next
- // key-frame after 0 might be 5secs ahead.
- if (Time < AudioStreamPos) then
- SeekFlags := SeekFlags or AVSEEK_FLAG_BACKWARD;
-
- EOFState := false;
- ErrorState := false;
-
- // send a reuse signal in case the parser was stopped (e.g. because of an EOF)
- SDL_CondSignal(ParserIdleCond);
-
- SDL_mutexV(StateLock);
- ResumeDecoder();
- ResumeParser();
-
- // in blocking mode, wait until seeking is done
- if (Blocking) then
- begin
- SDL_mutexP(StateLock);
- while (SeekRequest) do
- SDL_CondWait(SeekFinishedCond, StateLock);
- SDL_mutexV(StateLock);
- end;
-end;
-
-function ParseThreadMain(Data: Pointer): integer; cdecl;
-var
- Stream: TFFmpegDecodeStream;
-begin
- Stream := TFFmpegDecodeStream(Data);
- if (Stream <> nil) then
- Stream.Parse();
- Result := 0;
-end;
-
-procedure TFFmpegDecodeStream.Parse();
-begin
- // reuse thread as long as the stream is not terminated
- while (ParseLoop()) do
- begin
- // wait for reuse or destruction of stream
- SDL_mutexP(StateLock);
- while (not (SeekRequest or QuitRequest)) do
- SDL_CondWait(ParserIdleCond, StateLock);
- SDL_mutexV(StateLock);
- end;
-end;
-
-(**
- * Parser main loop.
- * Will not return until parsing of the stream is finished.
- * Reasons for the parser to return are:
- * - the end-of-file is reached
- * - an error occured
- * - the stream was quited (received a quit-request)
- * Returns true if the stream can be resumed or false if the stream has to
- * be terminated.
- *)
-function TFFmpegDecodeStream.ParseLoop(): boolean;
-var
- Packet: TAVPacket;
- StatusPacket: PAVPacket;
- SeekTarget: int64;
- ByteIOCtx: PByteIOContext;
- ErrorCode: integer;
- StartSilence: double; // duration of silence at start of stream
- StartSilencePtr: PDouble; // pointer for the EMPTY status packet
-
- // Note: pthreads wakes threads waiting on a mutex in the order of their
- // priority and not in FIFO order. SDL does not provide any option to
- // control priorities. This might (and already did) starve threads waiting
- // on the mutex (e.g. SetPosition) making usdx look like it was froozen.
- // Instead of simply locking the critical section we set a ParserLocked flag
- // instead and give priority to the threads requesting the parser to pause.
- procedure LockParser();
- begin
- SDL_mutexP(StateLock);
- while (ParserPauseRequestCount > 0) do
- SDL_CondWait(ParserResumeCond, StateLock);
- ParserLocked := true;
- SDL_mutexV(StateLock);
- end;
-
- procedure UnlockParser();
- begin
- SDL_mutexP(StateLock);
- ParserLocked := false;
- SDL_CondBroadcast(ParserUnlockedCond);
- SDL_mutexV(StateLock);
- end;
-
-begin
- Result := true;
-
- while (true) do
- begin
- LockParser();
- try
-
- if (IsQuit()) then
- begin
- Result := false;
- Exit;
- end;
-
- // handle seek-request (Note: no need to lock SeekRequest here)
- if (SeekRequest) then
- begin
- // first try: seek on the audio stream
- SeekTarget := Round(SeekPos / av_q2d(AudioStream^.time_base));
- StartSilence := 0;
- if (SeekTarget < AudioStream^.start_time) then
- StartSilence := (AudioStream^.start_time - SeekTarget) * av_q2d(AudioStream^.time_base);
- ErrorCode := av_seek_frame(FormatCtx, AudioStreamIndex, SeekTarget, SeekFlags);
-
- if (ErrorCode < 0) then
- begin
- // second try: seek on the default stream (necessary for flv-videos and some ogg-files)
- SeekTarget := Round(SeekPos * AV_TIME_BASE);
- StartSilence := 0;
- if (SeekTarget < FormatCtx^.start_time) then
- StartSilence := (FormatCtx^.start_time - SeekTarget) / AV_TIME_BASE;
- ErrorCode := av_seek_frame(FormatCtx, -1, SeekTarget, SeekFlags);
- end;
-
- // pause decoder and lock state (keep the lock-order to avoid deadlocks).
- // Note that the decoder does not block in the packet-queue in seeking state,
- // so locking the decoder here does not cause a dead-lock.
- PauseDecoder();
- SDL_mutexP(StateLock);
- try
- if (ErrorCode < 0) then
- begin
- // seeking failed
- ErrorState := true;
- Log.LogStatus('Seek Error in "'+FormatCtx^.filename+'"', 'UAudioDecoder_FFmpeg');
- end
- else
- begin
- if (SeekFlush) then
- begin
- // flush queue (we will send a Flush-Packet when seeking is finished)
- PacketQueue.Flush();
-
- // flush the decode buffers
- AudioBufferSize := 0;
- AudioBufferPos := 0;
- AudioPaketSize := 0;
- AudioPaketSilence := 0;
- FlushCodecBuffers();
-
- // Set preliminary stream position. The position will be set to
- // the correct value as soon as the first packet is decoded.
- AudioStreamPos := SeekPos;
- end
- else
- begin
- // request avcodec buffer flush
- PacketQueue.PutStatus(PKT_STATUS_FLAG_FLUSH, nil);
- end;
-
- // fill the gap between position 0 and start_time with silence
- // but not if we are in loop mode
- if ((StartSilence > 0) and (not Loop)) then
- begin
- GetMem(StartSilencePtr, SizeOf(StartSilence));
- StartSilencePtr^ := StartSilence;
- PacketQueue.PutStatus(PKT_STATUS_FLAG_EMPTY, StartSilencePtr);
- end;
- end;
-
- SeekRequest := false;
- SDL_CondBroadcast(SeekFinishedCond);
- finally
- SDL_mutexV(StateLock);
- ResumeDecoder();
- end;
- end;
-
- if (PacketQueue.GetSize() > MAX_AUDIOQ_SIZE) then
- begin
- SDL_Delay(10);
- Continue;
- end;
-
- if (av_read_frame(FormatCtx, Packet) < 0) then
- begin
- // failed to read a frame, check reason
- {$IF (LIBAVFORMAT_VERSION_MAJOR >= 52)}
- ByteIOCtx := FormatCtx^.pb;
- {$ELSE}
- ByteIOCtx := @FormatCtx^.pb;
- {$IFEND}
-
- // check for end-of-file (eof is not an error)
- if (url_feof(ByteIOCtx) <> 0) then
- begin
- if (GetLoop()) then
- begin
- // rewind stream (but do not flush)
- SetPositionIntern(0, false, false);
- Continue;
- end
- else
- begin
- // signal end-of-file
- PacketQueue.PutStatus(PKT_STATUS_FLAG_EOF, nil);
- Exit;
- end;
- end;
-
- // check for errors
- if (url_ferror(ByteIOCtx) <> 0) then
- begin
- // an error occured -> abort and wait for repositioning or termination
- PacketQueue.PutStatus(PKT_STATUS_FLAG_ERROR, nil);
- Exit;
- end;
-
- // no error -> wait for user input
- SDL_Delay(100);
- Continue;
- end;
-
- if (Packet.stream_index = AudioStreamIndex) then
- PacketQueue.Put(@Packet)
- else
- av_free_packet(@Packet);
-
- finally
- UnlockParser();
- end;
- end;
-end;
-
-
-(********************************************
- * Decoder section
- ********************************************)
-
-procedure TFFmpegDecodeStream.PauseDecoder();
-begin
- SDL_mutexP(StateLock);
- Inc(DecoderPauseRequestCount);
- while (DecoderLocked) do
- SDL_CondWait(DecoderUnlockedCond, StateLock);
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.ResumeDecoder();
-begin
- SDL_mutexP(StateLock);
- Dec(DecoderPauseRequestCount);
- SDL_CondSignal(DecoderResumeCond);
- SDL_mutexV(StateLock);
-end;
-
-procedure TFFmpegDecodeStream.FlushCodecBuffers();
-begin
- // if no flush operation is specified, avcodec_flush_buffers will not do anything.
- if (@CodecCtx.codec.flush <> nil) then
- begin
- // flush buffers used by avcodec_decode_audio, etc.
- avcodec_flush_buffers(CodecCtx);
- end
- else
- begin
- // we need a Workaround to avoid plopping noise with ogg-vorbis and
- // mp3 (in older versions of FFmpeg).
- // We will just reopen the codec.
- FFmpegCore.LockAVCodec();
- try
- avcodec_close(CodecCtx);
- avcodec_open(CodecCtx, Codec);
- finally
- FFmpegCore.UnlockAVCodec();
- end;
- end;
-end;
-
-function TFFmpegDecodeStream.DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
-var
- PaketDecodedSize: integer; // size of packet data used for decoding
- DataSize: integer; // size of output data decoded by FFmpeg
- BlockQueue: boolean;
- SilenceDuration: double;
- {$IFDEF DebugFFmpegDecode}
- TmpPos: double;
- {$ENDIF}
-begin
- Result := -1;
-
- if (EOF) then
- Exit;
-
- while(true) do
- begin
- // for titles with start_time > 0 we have to generate silence
- // until we reach the pts of the first data packet.
- if (AudioPaketSilence > 0) then
- begin
- DataSize := Min(AudioPaketSilence, BufferSize);
- FillChar(Buffer[0], DataSize, 0);
- Dec(AudioPaketSilence, DataSize);
- AudioStreamPos := AudioStreamPos + DataSize / FormatInfo.BytesPerSec;
- Result := DataSize;
- Exit;
- end;
-
- // read packet data
- while (AudioPaketSize > 0) do
- begin
- DataSize := BufferSize;
-
- {$IF LIBAVCODEC_VERSION >= 51030000} // 51.30.0
- PaketDecodedSize := avcodec_decode_audio2(CodecCtx, PSmallint(Buffer),
- DataSize, AudioPaketData, AudioPaketSize);
- {$ELSE}
- PaketDecodedSize := avcodec_decode_audio(CodecCtx, PSmallint(Buffer),
- DataSize, AudioPaketData, AudioPaketSize);
- {$IFEND}
-
- if(PaketDecodedSize < 0) then
- begin
- // if error, skip frame
- {$IFDEF DebugFFmpegDecode}
- DebugWriteln('Skip audio frame');
- {$ENDIF}
- AudioPaketSize := 0;
- Break;
- end;
-
- Inc(AudioPaketData, PaketDecodedSize);
- Dec(AudioPaketSize, PaketDecodedSize);
-
- // check if avcodec_decode_audio returned data, otherwise fetch more frames
- if (DataSize <= 0) then
- Continue;
-
- // update stream position by the amount of fetched data
- AudioStreamPos := AudioStreamPos + DataSize / FormatInfo.BytesPerSec;
-
- // we have data, return it and come back for more later
- Result := DataSize;
- Exit;
- end;
-
- // free old packet data
- if (AudioPaket.data <> nil) then
- av_free_packet(@AudioPaket);
-
- // do not block queue on seeking (to avoid deadlocks on the DecoderLock)
- if (IsSeeking()) then
- BlockQueue := false
- else
- BlockQueue := true;
-
- // request a new packet and block if none available.
- // If this fails, the queue was aborted.
- if (PacketQueue.Get(AudioPaket, BlockQueue) <= 0) then
- Exit;
-
- // handle Status-packet
- if (PChar(AudioPaket.data) = STATUS_PACKET) then
- begin
- AudioPaket.data := nil;
- AudioPaketData := nil;
- AudioPaketSize := 0;
-
- case (AudioPaket.flags) of
- PKT_STATUS_FLAG_FLUSH:
- begin
- // just used if SetPositionIntern was called without the flush flag.
- FlushCodecBuffers;
- end;
- PKT_STATUS_FLAG_EOF: // end-of-file
- begin
- // ignore EOF while seeking
- if (not IsSeeking()) then
- SetEOF(true);
- // buffer contains no data -> result = -1
- Exit;
- end;
- PKT_STATUS_FLAG_ERROR:
- begin
- SetError(true);
- Log.LogStatus('I/O Error', 'TFFmpegDecodeStream.DecodeFrame');
- Exit;
- end;
- PKT_STATUS_FLAG_EMPTY:
- begin
- SilenceDuration := PDouble(PacketQueue.GetStatusInfo(AudioPaket))^;
- AudioPaketSilence := Round(SilenceDuration * FormatInfo.SampleRate) * FormatInfo.FrameSize;
- PacketQueue.FreeStatusInfo(AudioPaket);
- end
- else
- begin
- Log.LogStatus('Unknown status', 'TFFmpegDecodeStream.DecodeFrame');
- end;
- end;
-
- Continue;
- end;
-
- AudioPaketData := PChar(AudioPaket.data);
- AudioPaketSize := AudioPaket.size;
-
- // if available, update the stream position to the presentation time of this package
- if(AudioPaket.pts <> AV_NOPTS_VALUE) then
- begin
- {$IFDEF DebugFFmpegDecode}
- TmpPos := AudioStreamPos;
- {$ENDIF}
- AudioStreamPos := av_q2d(AudioStream^.time_base) * AudioPaket.pts;
- {$IFDEF DebugFFmpegDecode}
- DebugWriteln('Timestamp: ' + floattostrf(AudioStreamPos, ffFixed, 15, 3) + ' ' +
- '(Calc: ' + floattostrf(TmpPos, ffFixed, 15, 3) + '), ' +
- 'Diff: ' + floattostrf(AudioStreamPos-TmpPos, ffFixed, 15, 3));
- {$ENDIF}
- end;
- end;
-end;
-
-function TFFmpegDecodeStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-var
- CopyByteCount: integer; // number of bytes to copy
- RemainByteCount: integer; // number of bytes left (remain) to read
- BufferPos: integer;
-
- // prioritize pause requests
- procedure LockDecoder();
- begin
- SDL_mutexP(StateLock);
- while (DecoderPauseRequestCount > 0) do
- SDL_CondWait(DecoderResumeCond, StateLock);
- DecoderLocked := true;
- SDL_mutexV(StateLock);
- end;
-
- procedure UnlockDecoder();
- begin
- SDL_mutexP(StateLock);
- DecoderLocked := false;
- SDL_CondBroadcast(DecoderUnlockedCond);
- SDL_mutexV(StateLock);
- end;
-
-begin
- Result := -1;
-
- // set number of bytes to copy to the output buffer
- BufferPos := 0;
-
- LockDecoder();
- try
- // leave if end-of-file is reached
- if (EOF) then
- Exit;
-
- // copy data to output buffer
- while (BufferPos < BufferSize) do
- begin
- // check if we need more data
- if (AudioBufferPos >= AudioBufferSize) then
- begin
- AudioBufferPos := 0;
-
- // we have already sent all our data; get more
- AudioBufferSize := DecodeFrame(AudioBuffer, AUDIO_BUFFER_SIZE);
-
- // check for errors or EOF
- if(AudioBufferSize < 0) then
- begin
- Result := BufferPos;
- Exit;
- end;
- end;
-
- // calc number of new bytes in the decode-buffer
- CopyByteCount := AudioBufferSize - AudioBufferPos;
- // resize copy-count if more bytes available than needed (remaining bytes are used the next time)
- RemainByteCount := BufferSize - BufferPos;
- if (CopyByteCount > RemainByteCount) then
- CopyByteCount := RemainByteCount;
-
- Move(AudioBuffer[AudioBufferPos], Buffer[BufferPos], CopyByteCount);
-
- Inc(BufferPos, CopyByteCount);
- Inc(AudioBufferPos, CopyByteCount);
- end;
- finally
- UnlockDecoder();
- end;
-
- Result := BufferSize;
-end;
-
-
-{ TAudioDecoder_FFmpeg }
-
-function TAudioDecoder_FFmpeg.GetName: String;
-begin
- Result := 'FFmpeg_Decoder';
-end;
-
-function TAudioDecoder_FFmpeg.InitializeDecoder: boolean;
-begin
- //Log.LogStatus('InitializeDecoder', 'UAudioDecoder_FFmpeg');
- FFmpegCore := TMediaCore_FFmpeg.GetInstance();
- av_register_all();
-
- // Do not show uninformative error messages by default.
- // FFmpeg prints all error-infos on the console by default what
- // is very confusing as the playback of the files is correct.
- // We consider these errors to be internal to FFMpeg. They can be fixed
- // by the FFmpeg guys only and do not provide any useful information in
- // respect to USDX.
- {$IFNDEF EnableFFmpegErrorOutput}
- {$IF LIBAVUTIL_VERSION_MAJOR >= 50}
- av_log_set_level(AV_LOG_FATAL);
- {$ELSE}
- // FATAL and ERROR share one log-level, so we have to use QUIET
- av_log_set_level(AV_LOG_QUIET);
- {$IFEND}
- {$ENDIF}
-
- Result := true;
-end;
-
-function TAudioDecoder_FFmpeg.FinalizeDecoder(): boolean;
-begin
- Result := true;
-end;
-
-function TAudioDecoder_FFmpeg.Open(const Filename: string): TAudioDecodeStream;
-var
- Stream: TFFmpegDecodeStream;
-begin
- Result := nil;
-
- Stream := TFFmpegDecodeStream.Create();
- if (not Stream.Open(Filename)) then
- begin
- Stream.Free;
- Exit;
- end;
-
- Result := Stream;
-end;
-
-
-initialization
- MediaManager.Add(TAudioDecoder_FFmpeg.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioInput_Bass.pas b/Game/Code/Classes/UAudioInput_Bass.pas
deleted file mode 100644
index 65a4704d..00000000
--- a/Game/Code/Classes/UAudioInput_Bass.pas
+++ /dev/null
@@ -1,481 +0,0 @@
-unit UAudioInput_Bass;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- URecord,
- UMusic;
-
-implementation
-
-uses
- UMain,
- UIni,
- ULog,
- UAudioCore_Bass,
- UCommon, // (Note: for MakeLong on non-windows platforms)
- {$IFDEF MSWINDOWS}
- Windows, // (Note: for MakeLong)
- {$ENDIF}
- bass; // (Note: DWORD is redefined here -> insert after Windows-unit)
-
-type
- TAudioInput_Bass = class(TAudioInputBase)
- private
- function EnumDevices(): boolean;
- public
- function GetName: String; override;
- function InitializeRecord: boolean; override;
- function FinalizeRecord: boolean; override;
- end;
-
- TBassInputDevice = class(TAudioInputDevice)
- private
- RecordStream: HSTREAM;
- BassDeviceID: DWORD; // DeviceID used by BASS
- SingleIn: boolean;
-
- function SetInputSource(SourceIndex: integer): boolean;
- function GetInputSource(): integer;
- public
- function Open(): boolean;
- function Close(): boolean;
- function Start(): boolean; override;
- function Stop(): boolean; override;
-
- function GetVolume(): single; override;
- procedure SetVolume(Volume: single); override;
- end;
-
-var
- BassCore: TAudioCore_Bass;
-
-
-{ 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; inputDevice: Pointer): boolean; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-begin
- AudioInputProcessor.HandleMicrophoneData(buffer, len, inputDevice);
- Result := true;
-end;
-
-
-{ TBassInputDevice }
-
-function TBassInputDevice.GetInputSource(): integer;
-var
- SourceCnt: integer;
- i: integer;
- flags: DWORD;
-begin
- // get input-source config (subtract virtual device to get BASS indices)
- SourceCnt := Length(Source)-1;
-
- // find source
- Result := -1;
- for i := 0 to SourceCnt-1 do
- begin
- // get input settings
- flags := BASS_RecordGetInput(i, PSingle(nil)^);
- if (flags = DWORD(-1)) then
- begin
- Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.GetInputSource');
- Exit;
- end;
-
- // check if current source is selected
- if ((flags and BASS_INPUT_OFF) = 0) then
- begin
- // selected source found
- Result := i;
- Exit;
- end;
- end;
-end;
-
-function TBassInputDevice.SetInputSource(SourceIndex: integer): boolean;
-var
- SourceCnt: integer;
- i: integer;
- flags: DWORD;
-begin
- Result := false;
-
- // check for invalid source index
- if (SourceIndex < 0) then
- Exit;
-
- // get input-source config (subtract virtual device to get BASS indices)
- SourceCnt := Length(Source)-1;
-
- // turn on selected source (turns off the others for single-in devices)
- if (not BASS_RecordSetInput(SourceIndex, BASS_INPUT_ON, -1)) then
- begin
- Log.LogError('BASS_RecordSetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Start');
- Exit;
- end;
-
- // turn off all other sources (not needed for single-in devices)
- if (not SingleIn) then
- begin
- for i := 0 to SourceCnt-1 do
- begin
- if (i = SourceIndex) then
- continue;
- // get input settings
- flags := BASS_RecordGetInput(i, PSingle(nil)^);
- if (flags = DWORD(-1)) then
- begin
- Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.GetInputSource');
- Exit;
- end;
- // deselect source if selected
- if ((flags and BASS_INPUT_OFF) = 0) then
- BASS_RecordSetInput(i, BASS_INPUT_OFF, -1);
- end;
- end;
-
- Result := true;
-end;
-
-function TBassInputDevice.Open(): boolean;
-var
- FormatFlags: DWORD;
- SourceIndex: integer;
-const
- latency = 20; // 20ms callback period (= latency)
-begin
- Result := false;
-
- if (not BASS_RecordInit(BassDeviceID)) then
- begin
- Log.LogError('BASS_RecordInit['+Name+']: ' +
- BassCore.ErrorGetString(), 'TBassInputDevice.Open');
- Exit;
- end;
-
- if (not BassCore.ConvertAudioFormatToBASSFlags(AudioFormat.Format, FormatFlags)) then
- begin
- Log.LogError('Unhandled sample-format', 'TBassInputDevice.Open');
- Exit;
- end;
-
- // start capturing in paused state
- RecordStream := BASS_RecordStart(Round(AudioFormat.SampleRate), AudioFormat.Channels,
- MakeLong(FormatFlags or BASS_RECORD_PAUSE, latency),
- @MicrophoneCallback, Self);
- if (RecordStream = 0) then
- begin
- Log.LogError('BASS_RecordStart: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Open');
- BASS_RecordFree;
- Exit;
- end;
-
- // save current source selection and select new source
- SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
- if (SourceIndex = -1) then
- begin
- // nothing to do if default source is used
- SourceRestore := -1;
- end
- else
- begin
- // store current source-index and select new source
- SourceRestore := GetInputSource();
- SetInputSource(SourceIndex);
- end;
-
- Result := true;
-end;
-
-{* Start input-capturing on this device. *}
-function TBassInputDevice.Start(): boolean;
-begin
- Result := false;
-
- // recording already started -> stop first
- if (RecordStream <> 0) then
- Stop();
-
- // TODO: Do not open the device here (takes too much time).
- if not Open() then
- Exit;
-
- if (not BASS_ChannelPlay(RecordStream, true)) then
- begin
- Log.LogError('BASS_ChannelPlay: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Start');
- Exit;
- end;
-
- Result := true;
-end;
-
-{* Stop input-capturing on this device. *}
-function TBassInputDevice.Stop(): boolean;
-begin
- Result := false;
-
- if (RecordStream = 0) then
- Exit;
- if (not BASS_RecordSetDevice(BassDeviceID)) then
- Exit;
-
- if (not BASS_ChannelStop(RecordStream)) then
- begin
- Log.LogError('BASS_ChannelStop: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Stop');
- end;
-
- // TODO: Do not close the device here (takes too much time).
- Result := Close();
-end;
-
-function TBassInputDevice.Close(): boolean;
-begin
- // restore source selection
- if (SourceRestore >= 0) then
- begin
- SetInputSource(SourceRestore);
- end;
-
- // free data
- if (not BASS_RecordFree()) then
- begin
- Log.LogError('BASS_RecordFree: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Close');
- Result := false;
- end
- else
- begin
- Result := true;
- end;
-
- RecordStream := 0;
-end;
-
-function TBassInputDevice.GetVolume(): single;
-var
- SourceIndex: integer;
- lVolume: Single;
-begin
- Result := 0;
-
- SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
- if (SourceIndex = -1) then
- begin
- // if default source used find selected source
- SourceIndex := GetInputSource();
- if (SourceIndex = -1) then
- Exit;
- end;
-
- if (BASS_RecordGetInput(SourceIndex, lVolume) = DWORD(-1)) then
- begin
- Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString() , 'TBassInputDevice.GetVolume');
- Exit;
- end;
- Result := lVolume;
-end;
-
-procedure TBassInputDevice.SetVolume(Volume: single);
-var
- SourceIndex: integer;
-begin
- SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
- if (SourceIndex = -1) then
- begin
- // if default source used find selected source
- SourceIndex := GetInputSource();
- if (SourceIndex = -1) then
- Exit;
- end;
-
- // clip volume to valid range
- if (Volume > 1.0) then
- Volume := 1.0
- else if (Volume < 0) then
- Volume := 0;
-
- if (not BASS_RecordSetInput(SourceIndex, 0, Volume)) then
- begin
- Log.LogError('BASS_RecordSetInput: ' + BassCore.ErrorGetString() , 'TBassInputDevice.SetVolume');
- end;
-end;
-
-
-{ TAudioInput_Bass }
-
-function TAudioInput_Bass.GetName: String;
-begin
- result := 'BASS_Input';
-end;
-
-function TAudioInput_Bass.EnumDevices(): boolean;
-var
- Descr: PChar;
- SourceName: PChar;
- Flags: integer;
- BassDeviceID: integer;
- BassDevice: TBassInputDevice;
- DeviceIndex: integer;
- DeviceInfo: BASS_DEVICEINFO;
- SourceIndex: integer;
- RecordInfo: BASS_RECORDINFO;
- SelectedSourceIndex: integer;
-begin
- result := false;
-
- DeviceIndex := 0;
- BassDeviceID := 0;
- SetLength(AudioInputProcessor.DeviceList, 0);
-
- // checks for recording devices and puts them into an array
- while true do
- begin
- if (not BASS_RecordGetDeviceInfo(BassDeviceID, DeviceInfo)) then
- break;
-
- // try to initialize 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.DeviceList, DeviceIndex+1);
-
- // TODO: free object on termination
- BassDevice := TBassInputDevice.Create();
- AudioInputProcessor.DeviceList[DeviceIndex] := BassDevice;
-
- Descr := DeviceInfo.name;
-
- BassDevice.BassDeviceID := BassDeviceID;
- BassDevice.Name := UnifyDeviceName(Descr, DeviceIndex);
-
- // zero info-struct as some fields might not be set (e.g. freq is just set on Vista and MacOSX)
- FillChar(RecordInfo, SizeOf(RecordInfo), 0);
- // retrieve recording device info
- BASS_RecordGetInfo(RecordInfo);
-
- // 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.
- // FIXME: does BASS use LSB/MSB or system integer values for 16bit?
- 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;
-
- // get info if multiple input-sources can be selected at once
- BassDevice.SingleIn := RecordInfo.singlein;
-
- // init list for capture buffers per channel
- SetLength(BassDevice.CaptureChannel, BassDevice.AudioFormat.Channels);
-
- BassDevice.MicSource := -1;
- BassDevice.SourceRestore := -1;
-
- // add a virtual default source (will not change mixer-settings)
- SetLength(BassDevice.Source, 1);
- BassDevice.Source[0].Name := DEFAULT_SOURCE_NAME;
-
- // add real input sources
- SourceIndex := 1;
-
- // process each input
- while true do
- begin
- SourceName := BASS_RecordGetInputName(SourceIndex-1);
-
- {$IFDEF DARWIN}
- // Under MacOSX the SingStar Mics have an empty InputName.
- // So, we have to add a hard coded Workaround for this problem
- // FIXME: - Do we need this anymore? Doesn't the (new) default source already solve this problem?
- // - Normally a nil return value of BASS_RecordGetInputName() means end-of-list, so maybe
- // BASS is not able to detect any mic-sources (the default source will work then).
- // - Does BASS_RecordGetInfo() return true or false? If it returns true in this case
- // we could use this value to check if the device exists.
- // Please check that, eddie.
- // If it returns false, then the source is not detected and it does not make sense to add a second
- // fake device here.
- // What about BASS_RecordGetInput()? Does it return a value <> -1?
- // - Does it even work at all with this fake source-index, now that input switching works?
- // This info was not used before (sources were never switched), so it did not matter what source-index was used.
- // But now BASS_RecordSetInput() will probably fail.
- if ((SourceName = nil) and (SourceIndex = 1) and (Pos('USBMIC Serial#', Descr) > 0)) then
- SourceName := 'Microphone'
- {$ENDIF}
-
- if (SourceName = nil) then
- break;
-
- SetLength(BassDevice.Source, Length(BassDevice.Source)+1);
- BassDevice.Source[SourceIndex].Name := SourceName;
-
- // get input-source info
- Flags := BASS_RecordGetInput(SourceIndex, PSingle(nil)^);
- if (Flags <> -1) then
- begin
- // is the current source a mic-source?
- if ((Flags and BASS_INPUT_TYPE_MIC) <> 0) then
- BassDevice.MicSource := SourceIndex;
- end;
-
- Inc(SourceIndex);
- end;
-
- // FIXME: this call hangs in FPC (windows) every 2nd time USDX is called.
- // Maybe because the sound-device was not released properly?
- BASS_RecordFree;
-
- Inc(DeviceIndex);
- end;
-
- Inc(BassDeviceID);
- end;
-
- result := true;
-end;
-
-function TAudioInput_Bass.InitializeRecord(): boolean;
-begin
- BassCore := TAudioCore_Bass.GetInstance();
- Result := EnumDevices();
-end;
-
-function TAudioInput_Bass.FinalizeRecord(): boolean;
-begin
- CaptureStop;
- Result := inherited FinalizeRecord;
-end;
-
-
-initialization
- MediaManager.Add(TAudioInput_Bass.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioInput_Portaudio.pas b/Game/Code/Classes/UAudioInput_Portaudio.pas
deleted file mode 100644
index 9a1c3e99..00000000
--- a/Game/Code/Classes/UAudioInput_Portaudio.pas
+++ /dev/null
@@ -1,474 +0,0 @@
-unit UAudioInput_Portaudio;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I ../switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- UMusic;
-
-implementation
-
-uses
- {$IFDEF UsePortmixer}
- portmixer,
- {$ENDIF}
- portaudio,
- UAudioCore_Portaudio,
- URecord,
- UIni,
- ULog,
- UMain;
-
-type
- TAudioInput_Portaudio = class(TAudioInputBase)
- private
- AudioCore: TAudioCore_Portaudio;
- function EnumDevices(): boolean;
- public
- function GetName: String; override;
- function InitializeRecord: boolean; override;
- function FinalizeRecord: boolean; override;
- end;
-
- TPortaudioInputDevice = class(TAudioInputDevice)
- private
- RecordStream: PPaStream;
- {$IFDEF UsePortmixer}
- Mixer: PPxMixer;
- {$ENDIF}
- PaDeviceIndex: TPaDeviceIndex;
- public
- function Open(): boolean;
- function Close(): boolean;
- function Start(): boolean; override;
- function Stop(): boolean; override;
-
- function GetVolume(): single; override;
- procedure SetVolume(Volume: single); override;
- end;
-
-function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl; forward;
-
-function MicrophoneTestCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl; forward;
-
-
-{ TPortaudioInputDevice }
-
-function TPortaudioInputDevice.Open(): boolean;
-var
- Error: TPaError;
- inputParams: TPaStreamParameters;
- deviceInfo: PPaDeviceInfo;
- SourceIndex: integer;
-begin
- Result := false;
-
- // get input latency info
- deviceInfo := Pa_GetDeviceInfo(PaDeviceIndex);
-
- // set input stream parameters
- with inputParams do
- begin
- device := PaDeviceIndex;
- channelCount := AudioFormat.Channels;
- sampleFormat := paInt16;
- suggestedLatency := deviceInfo^.defaultLowInputLatency;
- hostApiSpecificStreamInfo := nil;
- end;
-
- //Log.LogStatus(deviceInfo^.name, 'Portaudio');
- //Log.LogStatus(floattostr(deviceInfo^.defaultLowInputLatency), 'Portaudio');
-
- // open input stream
- Error := Pa_OpenStream(RecordStream, @inputParams, nil,
- AudioFormat.SampleRate,
- paFramesPerBufferUnspecified, paNoFlag,
- @MicrophoneCallback, Pointer(Self));
- if(Error <> paNoError) then
- begin
- Log.LogError('Error opening stream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Open');
- Exit;
- end;
-
- {$IFDEF UsePortmixer}
- // open default mixer
- Mixer := Px_OpenMixer(RecordStream, 0);
- if (Mixer = nil) then
- begin
- Log.LogError('Error opening mixer: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Open');
- end
- else
- begin
- // save current source selection and select new source
- SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
- if (SourceIndex = -1) then
- begin
- // nothing to do if default source is used
- SourceRestore := -1;
- end
- else
- begin
- // store current source-index and select new source
- SourceRestore := Px_GetCurrentInputSource(Mixer); // -1 in error case
- Px_SetCurrentInputSource(Mixer, SourceIndex);
- end;
- end;
- {$ENDIF}
-
- Result := true;
-end;
-
-function TPortaudioInputDevice.Start(): boolean;
-var
- Error: TPaError;
-begin
- Result := false;
-
- // recording already started -> stop first
- if (RecordStream <> nil) then
- Stop();
-
- // TODO: Do not open the device here (takes too much time).
- if (not Open()) then
- Exit;
-
- // start capture
- Error := Pa_StartStream(RecordStream);
- if(Error <> paNoError) then
- begin
- Log.LogError('Error starting stream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Start');
- Close();
- RecordStream := nil;
- Exit;
- end;
-
- Result := true;
-end;
-
-function TPortaudioInputDevice.Stop(): boolean;
-var
- Error: TPaError;
-begin
- Result := false;
-
- if (RecordStream = nil) then
- Exit;
-
- // Note: do NOT call Pa_StopStream here!
- // It gets stuck on devices with non-working callback as Pa_StopStream
- // waits until all buffers have been handled (which never occurs in that case).
- Error := Pa_AbortStream(RecordStream);
- if (Error <> paNoError) then
- begin
- Log.LogError('Pa_AbortStream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Stop');
- end;
-
- Result := Close();
-end;
-
-function TPortaudioInputDevice.Close(): boolean;
-var
- Error: TPaError;
-begin
- {$IFDEF UsePortmixer}
- if (Mixer <> nil) then
- begin
- // restore source selection
- if (SourceRestore >= 0) then
- begin
- Px_SetCurrentInputSource(Mixer, SourceRestore);
- end;
-
- // close mixer
- Px_CloseMixer(Mixer);
- Mixer := nil;
- end;
- {$ENDIF}
-
- Error := Pa_CloseStream(RecordStream);
- if (Error <> paNoError) then
- begin
- Log.LogError('Pa_CloseStream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Close');
- Result := false;
- end
- else
- begin
- Result := true;
- end;
-
- RecordStream := nil;
-end;
-
-function TPortaudioInputDevice.GetVolume(): single;
-begin
- Result := 0;
- {$IFDEF UsePortmixer}
- if (Mixer <> nil) then
- Result := Px_GetInputVolume(Mixer);
- {$ENDIF}
-end;
-
-procedure TPortaudioInputDevice.SetVolume(Volume: single);
-begin
- {$IFDEF UsePortmixer}
- if (Mixer <> nil) then
- begin
- // clip to valid range
- if (Volume > 1.0) then
- Volume := 1.0
- else if (Volume < 0) then
- Volume := 0;
- Px_SetInputVolume(Mixer, Volume);
- end;
- {$ENDIF}
-end;
-
-
-{ TAudioInput_Portaudio }
-
-function TAudioInput_Portaudio.GetName: String;
-begin
- result := 'Portaudio';
-end;
-
-function TAudioInput_Portaudio.EnumDevices(): boolean;
-var
- i: integer;
- paApiIndex: TPaHostApiIndex;
- paApiInfo: PPaHostApiInfo;
- deviceName: string;
- deviceIndex: TPaDeviceIndex;
- deviceInfo: PPaDeviceInfo;
- channelCnt: integer;
- SC: integer; // soundcard
- err: TPaError;
- errMsg: string;
- paDevice: TPortaudioInputDevice;
- inputParams: TPaStreamParameters;
- stream: PPaStream;
- streamInfo: PPaStreamInfo;
- sampleRate: double;
- latency: TPaTime;
- {$IFDEF UsePortmixer}
- mixer: PPxMixer;
- sourceCnt: integer;
- sourceIndex: integer;
- sourceName: string;
- {$ENDIF}
- cbPolls: integer;
- cbWorks: boolean;
-begin
- Result := false;
-
- // choose the best available Audio-API
- paApiIndex := AudioCore.GetPreferredApiIndex();
- if(paApiIndex = -1) then
- begin
- Log.LogError('No working Audio-API found', 'TAudioInput_Portaudio.EnumDevices');
- Exit;
- end;
-
- paApiInfo := Pa_GetHostApiInfo(paApiIndex);
-
- SC := 0;
-
- // init array-size to max. input-devices count
- SetLength(AudioInputProcessor.DeviceList, paApiInfo^.deviceCount);
- for i:= 0 to High(AudioInputProcessor.DeviceList) do
- begin
- // convert API-specific device-index to global index
- deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
- deviceInfo := Pa_GetDeviceInfo(deviceIndex);
-
- channelCnt := deviceInfo^.maxInputChannels;
-
- // current device is no input device -> skip
- if (channelCnt <= 0) then
- continue;
-
- // portaudio returns a channel-count of 128 for some devices
- // (e.g. the "default"-device), so we have to detect those
- // fantasy channel counts.
- if (channelCnt > 8) then
- channelCnt := 2;
-
- paDevice := TPortaudioInputDevice.Create();
- AudioInputProcessor.DeviceList[SC] := paDevice;
-
- // retrieve device-name
- deviceName := deviceInfo^.name;
- paDevice.Name := deviceName;
- paDevice.PaDeviceIndex := deviceIndex;
-
- sampleRate := deviceInfo^.defaultSampleRate;
-
- // on vista and xp the defaultLowInputLatency may be set to 0 but it works.
- // TODO: correct too low latencies (what is a too low latency, maybe < 10ms?)
- latency := deviceInfo^.defaultLowInputLatency;
-
- // setup desired input parameters
- // TODO: retry with input-latency set to 20ms (defaultLowInputLatency might
- // not be set correctly in OSS)
- with inputParams do
- begin
- device := deviceIndex;
- channelCount := channelCnt;
- sampleFormat := paInt16;
- suggestedLatency := latency;
- hostApiSpecificStreamInfo := nil;
- end;
-
- // check souncard and adjust sample-rate
- if (not AudioCore.TestDevice(@inputParams, nil, sampleRate)) then
- begin
- // ignore device if it does not work
- Log.LogError('Device "'+paDevice.Name+'" does not work',
- 'TAudioInput_Portaudio.EnumDevices');
- paDevice.Free();
- continue;
- end;
-
- // open device for further info
- err := Pa_OpenStream(stream, @inputParams, nil, sampleRate,
- paFramesPerBufferUnspecified, paNoFlag, @MicrophoneTestCallback, nil);
- if(err <> paNoError) then
- begin
- // unable to open device -> skip
- errMsg := Pa_GetErrorText(err);
- Log.LogError('Device error: "'+ deviceName +'" ('+ errMsg +')',
- 'TAudioInput_Portaudio.EnumDevices');
- paDevice.Free();
- continue;
- end;
-
- // adjust sample-rate (might be changed by portaudio)
- streamInfo := Pa_GetStreamInfo(stream);
- if (streamInfo <> nil) then
- begin
- if (sampleRate <> streamInfo^.sampleRate) then
- begin
- Log.LogStatus('Portaudio changed Samplerate from ' + FloatToStr(sampleRate) +
- ' to ' + FloatToStr(streamInfo^.sampleRate),
- 'TAudioInput_Portaudio.InitializeRecord');
- sampleRate := streamInfo^.sampleRate;
- end;
- end;
-
- // create audio-format info and resize capture-buffer array
- paDevice.AudioFormat := TAudioFormatInfo.Create(
- channelCnt,
- sampleRate,
- asfS16
- );
- SetLength(paDevice.CaptureChannel, paDevice.AudioFormat.Channels);
-
- Log.LogStatus('InputDevice "'+paDevice.Name+'"@' +
- IntToStr(paDevice.AudioFormat.Channels)+'x'+
- FloatToStr(paDevice.AudioFormat.SampleRate)+'Hz ('+
- FloatTostr(inputParams.suggestedLatency)+'sec)' ,
- 'Portaudio.EnumDevices');
-
- // portaudio does not provide a source-type check
- paDevice.MicSource := -1;
- paDevice.SourceRestore := -1;
-
- // add a virtual default source (will not change mixer-settings)
- SetLength(paDevice.Source, 1);
- paDevice.Source[0].Name := DEFAULT_SOURCE_NAME;
-
- {$IFDEF UsePortmixer}
- // use default mixer
- mixer := Px_OpenMixer(stream, 0);
-
- // get input count
- sourceCnt := Px_GetNumInputSources(mixer);
- SetLength(paDevice.Source, sourceCnt+1);
-
- // get input names
- for sourceIndex := 1 to sourceCnt do
- begin
- sourceName := Px_GetInputSourceName(mixer, sourceIndex-1);
- paDevice.Source[sourceIndex].Name := sourceName;
- end;
-
- Px_CloseMixer(mixer);
- {$ENDIF}
-
- // close test-stream
- Pa_CloseStream(stream);
-
- Inc(SC);
- end;
-
- // adjust size to actual input-device count
- SetLength(AudioInputProcessor.DeviceList, SC);
-
- Log.LogStatus('#Input-Devices: ' + inttostr(SC), 'Portaudio');
-
- Result := true;
-end;
-
-function TAudioInput_Portaudio.InitializeRecord(): boolean;
-var
- err: TPaError;
-begin
- AudioCore := TAudioCore_Portaudio.GetInstance();
-
- // initialize portaudio
- err := Pa_Initialize();
- if(err <> paNoError) then
- begin
- Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord');
- Result := false;
- Exit;
- end;
-
- Result := EnumDevices();
-end;
-
-function TAudioInput_Portaudio.FinalizeRecord: boolean;
-begin
- CaptureStop;
- Pa_Terminate();
- Result := inherited FinalizeRecord();
-end;
-
-{*
- * Portaudio input capture callback.
- *}
-function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl;
-begin
- AudioInputProcessor.HandleMicrophoneData(input, frameCount*4, inputDevice);
- result := paContinue;
-end;
-
-{*
- * Portaudio test capture callback.
- *}
-function MicrophoneTestCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl;
-begin
- // this callback is called only once
- result := paAbort;
-end;
-
-
-initialization
- MediaManager.add(TAudioInput_Portaudio.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioPlaybackBase.pas b/Game/Code/Classes/UAudioPlaybackBase.pas
deleted file mode 100644
index 2337d43f..00000000
--- a/Game/Code/Classes/UAudioPlaybackBase.pas
+++ /dev/null
@@ -1,292 +0,0 @@
-unit UAudioPlaybackBase;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMusic;
-
-type
- TAudioPlaybackBase = class(TInterfacedObject, IAudioPlayback)
- protected
- OutputDeviceList: TAudioOutputDeviceList;
- MusicStream: TAudioPlaybackStream;
- function CreatePlaybackStream(): TAudioPlaybackStream; virtual; abstract;
- procedure ClearOutputDeviceList();
- function GetLatency(): double; virtual; abstract;
-
- // open sound or music stream (used by Open() and OpenSound())
- function OpenStream(const Filename: string): TAudioPlaybackStream;
- function OpenDecodeStream(const Filename: string): TAudioDecodeStream;
- public
- function GetName: string; virtual; abstract;
-
- function Open(const Filename: string): boolean; // true if succeed
- procedure Close;
-
- procedure Play;
- procedure Pause;
- procedure Stop;
- procedure FadeIn(Time: real; TargetVolume: single);
-
- procedure SetSyncSource(SyncSource: TSyncSource);
-
- procedure SetPosition(Time: real);
- function GetPosition: real;
-
- function InitializePlayback: boolean; virtual; abstract;
- function FinalizePlayback: boolean; virtual;
-
- //function SetOutputDevice(Device: TAudioOutputDevice): boolean;
- function GetOutputDeviceList(): TAudioOutputDeviceList;
-
- procedure SetAppVolume(Volume: single); virtual; abstract;
- procedure SetVolume(Volume: single);
- procedure SetLoop(Enabled: boolean);
-
- procedure Rewind;
- function Finished: boolean;
- function Length: real;
-
- // Sounds
- function OpenSound(const Filename: string): TAudioPlaybackStream;
- procedure PlaySound(Stream: TAudioPlaybackStream);
- procedure StopSound(Stream: TAudioPlaybackStream);
-
- // Equalizer
- procedure GetFFTData(var Data: TFFTData);
-
- // Interface for Visualizer
- function GetPCMData(var Data: TPCMData): Cardinal;
-
- function CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; virtual; abstract;
- end;
-
-
-implementation
-
-uses
- ULog,
- SysUtils;
-
-{ TAudioPlaybackBase }
-
-function TAudioPlaybackBase.FinalizePlayback: boolean;
-begin
- FreeAndNil(MusicStream);
- ClearOutputDeviceList();
- Result := true;
-end;
-
-function TAudioPlaybackBase.Open(const Filename: string): boolean;
-begin
- // free old MusicStream
- MusicStream.Free;
-
- MusicStream := OpenStream(Filename);
- if not assigned(MusicStream) then
- begin
- Result := false;
- Exit;
- end;
-
- //MusicStream.AddSoundEffect(TVoiceRemoval.Create());
-
- Result := true;
-end;
-
-procedure TAudioPlaybackBase.Close;
-begin
- FreeAndNil(MusicStream);
-end;
-
-function TAudioPlaybackBase.OpenDecodeStream(const Filename: String): TAudioDecodeStream;
-var
- i: integer;
-begin
- for i := 0 to AudioDecoders.Count-1 do
- begin
- Result := IAudioDecoder(AudioDecoders[i]).Open(Filename);
- if (assigned(Result)) then
- begin
- Log.LogInfo('Using decoder ' + IAudioDecoder(AudioDecoders[i]).GetName() +
- ' for "' + Filename + '"', 'TAudioPlaybackBase.OpenDecodeStream');
- Exit;
- end;
- end;
- Result := nil;
-end;
-
-procedure OnClosePlaybackStream(Stream: TAudioProcessingStream);
-var
- PlaybackStream: TAudioPlaybackStream;
- SourceStream: TAudioSourceStream;
-begin
- PlaybackStream := TAudioPlaybackStream(Stream);
- SourceStream := PlaybackStream.GetSourceStream();
- SourceStream.Free;
-end;
-
-function TAudioPlaybackBase.OpenStream(const Filename: string): TAudioPlaybackStream;
-var
- PlaybackStream: TAudioPlaybackStream;
- DecodeStream: TAudioDecodeStream;
-begin
- Result := nil;
-
- //Log.LogStatus('Loading Sound: "' + Filename + '"', 'TAudioPlayback_Bass.OpenStream');
-
- DecodeStream := OpenDecodeStream(Filename);
- if (not assigned(DecodeStream)) then
- begin
- Log.LogStatus('Could not open "' + Filename + '"', 'TAudioPlayback_Bass.OpenStream');
- Exit;
- end;
-
- // create a matching playback-stream for the decoder
- PlaybackStream := CreatePlaybackStream();
- if (not PlaybackStream.Open(DecodeStream)) then
- begin
- FreeAndNil(PlaybackStream);
- FreeAndNil(DecodeStream);
- Exit;
- end;
-
- PlaybackStream.AddOnCloseHandler(OnClosePlaybackStream);
-
- Result := PlaybackStream;
-end;
-
-procedure TAudioPlaybackBase.Play;
-begin
- if assigned(MusicStream) then
- MusicStream.Play();
-end;
-
-procedure TAudioPlaybackBase.Pause;
-begin
- if assigned(MusicStream) then
- MusicStream.Pause();
-end;
-
-procedure TAudioPlaybackBase.Stop;
-begin
- if assigned(MusicStream) then
- MusicStream.Stop();
-end;
-
-function TAudioPlaybackBase.Length: real;
-begin
- if assigned(MusicStream) then
- Result := MusicStream.Length
- else
- Result := 0;
-end;
-
-function TAudioPlaybackBase.GetPosition: real;
-begin
- if assigned(MusicStream) then
- Result := MusicStream.Position
- else
- Result := 0;
-end;
-
-procedure TAudioPlaybackBase.SetPosition(Time: real);
-begin
- if assigned(MusicStream) then
- MusicStream.Position := Time;
-end;
-
-procedure TAudioPlaybackBase.SetSyncSource(SyncSource: TSyncSource);
-begin
- if assigned(MusicStream) then
- MusicStream.SetSyncSource(SyncSource);
-end;
-
-procedure TAudioPlaybackBase.Rewind;
-begin
- SetPosition(0);
-end;
-
-function TAudioPlaybackBase.Finished: boolean;
-begin
- if assigned(MusicStream) then
- Result := (MusicStream.Status = ssStopped)
- else
- Result := true;
-end;
-
-procedure TAudioPlaybackBase.SetVolume(Volume: single);
-begin
- if assigned(MusicStream) then
- MusicStream.Volume := Volume;
-end;
-
-procedure TAudioPlaybackBase.FadeIn(Time: real; TargetVolume: single);
-begin
- if assigned(MusicStream) then
- MusicStream.FadeIn(Time, TargetVolume);
-end;
-
-procedure TAudioPlaybackBase.SetLoop(Enabled: boolean);
-begin
- if assigned(MusicStream) then
- MusicStream.Loop := Enabled;
-end;
-
-// Equalizer
-procedure TAudioPlaybackBase.GetFFTData(var data: TFFTData);
-begin
- if assigned(MusicStream) then
- MusicStream.GetFFTData(data);
-end;
-
-{*
- * Copies interleaved PCM SInt16 stereo samples into data.
- * Returns the number of frames
- *}
-function TAudioPlaybackBase.GetPCMData(var data: TPCMData): Cardinal;
-begin
- if assigned(MusicStream) then
- Result := MusicStream.GetPCMData(data)
- else
- Result := 0;
-end;
-
-function TAudioPlaybackBase.OpenSound(const Filename: string): TAudioPlaybackStream;
-begin
- Result := OpenStream(Filename);
-end;
-
-procedure TAudioPlaybackBase.PlaySound(stream: TAudioPlaybackStream);
-begin
- if assigned(stream) then
- stream.Play();
-end;
-
-procedure TAudioPlaybackBase.StopSound(stream: TAudioPlaybackStream);
-begin
- if assigned(stream) then
- stream.Stop();
-end;
-
-procedure TAudioPlaybackBase.ClearOutputDeviceList();
-var
- DeviceIndex: integer;
-begin
- for DeviceIndex := 0 to High(OutputDeviceList) do
- OutputDeviceList[DeviceIndex].Free();
- SetLength(OutputDeviceList, 0);
-end;
-
-function TAudioPlaybackBase.GetOutputDeviceList(): TAudioOutputDeviceList;
-begin
- Result := OutputDeviceList;
-end;
-
-end.
diff --git a/Game/Code/Classes/UAudioPlayback_Bass.pas b/Game/Code/Classes/UAudioPlayback_Bass.pas
deleted file mode 100644
index 41a91173..00000000
--- a/Game/Code/Classes/UAudioPlayback_Bass.pas
+++ /dev/null
@@ -1,731 +0,0 @@
-unit UAudioPlayback_Bass;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-implementation
-
-uses
- Classes,
- SysUtils,
- Math,
- UIni,
- UMain,
- UMusic,
- UAudioPlaybackBase,
- UAudioCore_Bass,
- ULog,
- sdl,
- bass;
-
-type
- PHDSP = ^HDSP;
-
-type
- TBassPlaybackStream = class(TAudioPlaybackStream)
- private
- Handle: HSTREAM;
- NeedsRewind: boolean;
- PausedSeek: boolean; // true if a seek was performed in pause state
-
- procedure Reset();
- function IsEOF(): boolean;
- protected
- function GetLatency(): double; override;
- function GetLoop(): boolean; override;
- procedure SetLoop(Enabled: boolean); override;
- function GetLength(): real; override;
- function GetStatus(): TStreamStatus; override;
- function GetVolume(): single; override;
- procedure SetVolume(Volume: single); override;
- function GetPosition: real; override;
- procedure SetPosition(Time: real); override;
- public
- constructor Create();
- destructor Destroy(); override;
-
- function Open(SourceStream: TAudioSourceStream): boolean; override;
- procedure Close(); override;
-
- procedure Play(); override;
- procedure Pause(); override;
- procedure Stop(); override;
- procedure FadeIn(Time: real; TargetVolume: single); override;
-
- procedure AddSoundEffect(Effect: TSoundEffect); override;
- procedure RemoveSoundEffect(Effect: TSoundEffect); override;
-
- procedure GetFFTData(var Data: TFFTData); override;
- function GetPCMData(var Data: TPCMData): Cardinal; override;
-
- function GetAudioFormatInfo(): TAudioFormatInfo; override;
-
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
-
- property EOF: boolean READ IsEOF;
- end;
-
-const
- MAX_VOICE_DELAY = 0.020; // 20ms
-
-type
- TBassVoiceStream = class(TAudioVoiceStream)
- private
- Handle: HSTREAM;
- public
- function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
- procedure Close(); override;
-
- procedure WriteData(Buffer: PChar; BufferSize: integer); override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
- function IsEOF(): boolean; override;
- function IsError(): boolean; override;
- end;
-
-type
- TAudioPlayback_Bass = class(TAudioPlaybackBase)
- private
- function EnumDevices(): boolean;
- protected
- function GetLatency(): double; override;
- function CreatePlaybackStream(): TAudioPlaybackStream; override;
- public
- function GetName: String; override;
- function InitializePlayback(): boolean; override;
- function FinalizePlayback: boolean; override;
- procedure SetAppVolume(Volume: single); override;
- function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; override;
- end;
-
- TBassOutputDevice = class(TAudioOutputDevice)
- private
- BassDeviceID: DWORD; // DeviceID used by BASS
- end;
-
-var
- BassCore: TAudioCore_Bass;
-
-
-{ TBassPlaybackStream }
-
-function PlaybackStreamHandler(handle: HSTREAM; buffer: Pointer; length: DWORD; user: Pointer): DWORD;
-{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-var
- PlaybackStream: TBassPlaybackStream;
- BytesRead: integer;
-begin
- PlaybackStream := TBassPlaybackStream(user);
- if (not assigned (PlaybackStream)) then
- begin
- Result := BASS_STREAMPROC_END;
- Exit;
- end;
-
- BytesRead := PlaybackStream.ReadData(buffer, length);
- // check for errors
- if (BytesRead < 0) then
- Result := BASS_STREAMPROC_END
- // check for EOF
- else if (PlaybackStream.EOF) then
- Result := BytesRead or BASS_STREAMPROC_END
- // no error/EOF
- else
- Result := BytesRead;
-end;
-
-function TBassPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-var
- AdjustedSize: integer;
- RequestedSourceSize, SourceSize: integer;
- SkipCount: integer;
- SourceFormatInfo: TAudioFormatInfo;
- FrameSize: integer;
- PadFrame: PChar;
- //Info: BASS_INFO;
- //Latency: double;
-begin
- Result := -1;
-
- if (not assigned(SourceStream)) then
- Exit;
-
- // sanity check
- if (BufferSize = 0) then
- begin
- Result := 0;
- Exit;
- end;
-
- SourceFormatInfo := SourceStream.GetAudioFormatInfo();
- FrameSize := SourceFormatInfo.FrameSize;
-
- // check how much data to fetch to be in synch
- AdjustedSize := Synchronize(BufferSize, SourceFormatInfo);
-
- // skip data if we are too far behind
- SkipCount := AdjustedSize - BufferSize;
- while (SkipCount > 0) do
- begin
- RequestedSourceSize := Min(SkipCount, BufferSize);
- SourceSize := SourceStream.ReadData(Buffer, RequestedSourceSize);
- // if an error or EOF occured stop skipping and handle error/EOF with the next ReadData()
- if (SourceSize <= 0) then
- break;
- Dec(SkipCount, SourceSize);
- end;
-
- // get source data (e.g. from a decoder)
- RequestedSourceSize := Min(AdjustedSize, BufferSize);
- SourceSize := SourceStream.ReadData(Buffer, RequestedSourceSize);
- if (SourceSize < 0) then
- Exit;
-
- // set preliminary result
- Result := SourceSize;
-
- // if we are to far ahead, fill output-buffer with last frame of source data
- // Note that AdjustedSize is used instead of SourceSize as the SourceSize might
- // be less than expected because of errors etc.
- if (AdjustedSize < BufferSize) then
- begin
- // use either the last frame for padding or fill with zero
- if (SourceSize >= FrameSize) then
- PadFrame := @Buffer[SourceSize-FrameSize]
- else
- PadFrame := nil;
-
- FillBufferWithFrame(@Buffer[SourceSize], BufferSize - SourceSize,
- PadFrame, FrameSize);
- Result := BufferSize;
- end;
-end;
-
-constructor TBassPlaybackStream.Create();
-begin
- inherited;
- Reset();
-end;
-
-destructor TBassPlaybackStream.Destroy();
-begin
- Close();
- inherited;
-end;
-
-function TBassPlaybackStream.Open(SourceStream: TAudioSourceStream): boolean;
-var
- FormatInfo: TAudioFormatInfo;
- FormatFlags: DWORD;
-begin
- Result := false;
-
- // close previous stream and reset state
- Reset();
-
- // sanity check if stream is valid
- if not assigned(SourceStream) then
- Exit;
-
- Self.SourceStream := SourceStream;
- FormatInfo := SourceStream.GetAudioFormatInfo();
- if (not BassCore.ConvertAudioFormatToBASSFlags(FormatInfo.Format, FormatFlags)) then
- begin
- Log.LogError('Unhandled sample-format', 'TBassPlaybackStream.Open');
- Exit;
- end;
-
- // create matching playback stream
- Handle := BASS_StreamCreate(Round(FormatInfo.SampleRate), FormatInfo.Channels, formatFlags,
- @PlaybackStreamHandler, Self);
- if (Handle = 0) then
- begin
- Log.LogError('BASS_StreamCreate failed: ' + BassCore.ErrorGetString(BASS_ErrorGetCode()),
- 'TBassPlaybackStream.Open');
- Exit;
- end;
-
- Result := true;
-end;
-
-procedure TBassPlaybackStream.Close();
-begin
- // stop and free stream
- if (Handle <> 0) then
- begin
- Bass_StreamFree(Handle);
- Handle := 0;
- end;
-
- // Note: PerformOnClose must be called before SourceStream is invalidated
- PerformOnClose();
- // unset source-stream
- SourceStream := nil;
-end;
-
-procedure TBassPlaybackStream.Reset();
-begin
- Close();
- NeedsRewind := false;
- PausedSeek := false;
-end;
-
-procedure TBassPlaybackStream.Play();
-var
- NeedsFlush: boolean;
-begin
- if (not assigned(SourceStream)) then
- Exit;
-
- NeedsFlush := true;
-
- if (BASS_ChannelIsActive(Handle) = BASS_ACTIVE_PAUSED) then
- begin
- // only paused (and not seeked while paused) streams are not flushed
- if (not PausedSeek) then
- NeedsFlush := false;
- // paused streams do not need a rewind
- NeedsRewind := false;
- end;
-
- // rewind if necessary. Cases that require no rewind are:
- // - stream was created and never played
- // - stream was paused and is resumed now
- // - stream was stopped and set to a new position already
- if (NeedsRewind) then
- SourceStream.Position := 0;
-
- NeedsRewind := true;
- PausedSeek := false;
-
- // start playing and flush buffers on rewind
- BASS_ChannelPlay(Handle, NeedsFlush);
-end;
-
-procedure TBassPlaybackStream.FadeIn(Time: real; TargetVolume: single);
-begin
- // start stream
- Play();
- // start fade-in: slide from fadeStart- to fadeEnd-volume in FadeInTime
- BASS_ChannelSlideAttribute(Handle, BASS_ATTRIB_VOL, TargetVolume, Trunc(Time * 1000));
-end;
-
-procedure TBassPlaybackStream.Pause();
-begin
- BASS_ChannelPause(Handle);
-end;
-
-procedure TBassPlaybackStream.Stop();
-begin
- BASS_ChannelStop(Handle);
-end;
-
-function TBassPlaybackStream.IsEOF(): boolean;
-begin
- if (assigned(SourceStream)) then
- Result := SourceStream.EOF
- else
- Result := true;
-end;
-
-function TBassPlaybackStream.GetLatency(): double;
-begin
- // TODO: should we consider output latency for synching (needs BASS_DEVICE_LATENCY)?
- //if (BASS_GetInfo(Info)) then
- // Latency := Info.latency / 1000
- //else
- // Latency := 0;
- Result := 0;
-end;
-
-function TBassPlaybackStream.GetVolume(): single;
-var
- lVolume: single;
-begin
- if (not BASS_ChannelGetAttribute(Handle, BASS_ATTRIB_VOL, lVolume)) then
- begin
- Log.LogError('BASS_ChannelGetAttribute: ' + BassCore.ErrorGetString(),
- 'TBassPlaybackStream.GetVolume');
- Result := 0;
- Exit;
- end;
- Result := Round(lVolume);
-end;
-
-procedure TBassPlaybackStream.SetVolume(Volume: single);
-begin
- // clamp volume
- if Volume < 0 then
- Volume := 0;
- if Volume > 1.0 then
- Volume := 1.0;
- // set volume
- BASS_ChannelSetAttribute(Handle, BASS_ATTRIB_VOL, Volume);
-end;
-
-function TBassPlaybackStream.GetPosition: real;
-var
- BufferPosByte: QWORD;
- BufferPosSec: double;
-begin
- if assigned(SourceStream) then
- begin
- BufferPosByte := BASS_ChannelGetData(Handle, nil, BASS_DATA_AVAILABLE);
- BufferPosSec := BASS_ChannelBytes2Seconds(Handle, BufferPosByte);
- // decrease the decoding position by the amount buffered (and hence not played)
- // in the BASS playback stream.
- Result := SourceStream.Position - BufferPosSec;
- end
- else
- begin
- Result := -1;
- end;
-end;
-
-procedure TBassPlaybackStream.SetPosition(Time: real);
-var
- ChannelState: DWORD;
-begin
- if assigned(SourceStream) then
- begin
- ChannelState := BASS_ChannelIsActive(Handle);
- if (ChannelState = BASS_ACTIVE_STOPPED) then
- begin
- // if the stream is stopped, do not rewind when the stream is played next time
- NeedsRewind := false
- end
- else if (ChannelState = BASS_ACTIVE_PAUSED) then
- begin
- // buffers must be flushed if in paused state but there is no
- // BASS_ChannelFlush() function so we have to use BASS_ChannelPlay() called in Play().
- PausedSeek := true;
- end;
-
- // set new position
- SourceStream.Position := Time;
- end;
-end;
-
-function TBassPlaybackStream.GetLength(): real;
-begin
- if assigned(SourceStream) then
- Result := SourceStream.Length
- else
- Result := -1;
-end;
-
-function TBassPlaybackStream.GetStatus(): TStreamStatus;
-var
- State: DWORD;
-begin
- State := BASS_ChannelIsActive(Handle);
- case State of
- BASS_ACTIVE_PLAYING,
- BASS_ACTIVE_STALLED:
- Result := ssPlaying;
- BASS_ACTIVE_PAUSED:
- Result := ssPaused;
- BASS_ACTIVE_STOPPED:
- Result := ssStopped;
- else
- begin
- Log.LogError('Unknown status', 'TBassPlaybackStream.GetStatus');
- Result := ssStopped;
- end;
- end;
-end;
-
-function TBassPlaybackStream.GetLoop(): boolean;
-begin
- if assigned(SourceStream) then
- Result := SourceStream.Loop
- else
- Result := false;
-end;
-
-procedure TBassPlaybackStream.SetLoop(Enabled: boolean);
-begin
- if assigned(SourceStream) then
- SourceStream.Loop := Enabled;
-end;
-
-procedure DSPProcHandler(handle: HDSP; channel: DWORD; buffer: Pointer; length: DWORD; user: Pointer);
-{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-var
- Effect: TSoundEffect;
-begin
- Effect := TSoundEffect(user);
- if assigned(Effect) then
- Effect.Callback(buffer, length);
-end;
-
-procedure TBassPlaybackStream.AddSoundEffect(Effect: TSoundEffect);
-var
- DspHandle: HDSP;
-begin
- if assigned(Effect.engineData) then
- begin
- Log.LogError('TSoundEffect.engineData already set', 'TBassPlaybackStream.AddSoundEffect');
- Exit;
- end;
-
- DspHandle := BASS_ChannelSetDSP(Handle, @DSPProcHandler, Effect, 0);
- if (DspHandle = 0) then
- begin
- Log.LogError(BassCore.ErrorGetString(), 'TBassPlaybackStream.AddSoundEffect');
- Exit;
- end;
-
- GetMem(Effect.EngineData, SizeOf(HDSP));
- PHDSP(Effect.EngineData)^ := DspHandle;
-end;
-
-procedure TBassPlaybackStream.RemoveSoundEffect(Effect: TSoundEffect);
-begin
- if not assigned(Effect.EngineData) then
- begin
- Log.LogError('TSoundEffect.engineData invalid', 'TBassPlaybackStream.RemoveSoundEffect');
- Exit;
- end;
-
- if not BASS_ChannelRemoveDSP(Handle, PHDSP(Effect.EngineData)^) then
- begin
- Log.LogError(BassCore.ErrorGetString(), 'TBassPlaybackStream.RemoveSoundEffect');
- Exit;
- end;
-
- FreeMem(Effect.EngineData);
- Effect.EngineData := nil;
-end;
-
-procedure TBassPlaybackStream.GetFFTData(var Data: TFFTData);
-begin
- // get FFT channel data (Mono, FFT512 -> 256 values)
- BASS_ChannelGetData(Handle, @Data, BASS_DATA_FFT512);
-end;
-
-{*
- * Copies interleaved PCM SInt16 stereo samples into data.
- * Returns the number of frames
- *}
-function TBassPlaybackStream.GetPCMData(var Data: TPCMData): Cardinal;
-var
- Info: BASS_CHANNELINFO;
- nBytes: DWORD;
-begin
- Result := 0;
-
- FillChar(Data, SizeOf(TPCMData), 0);
-
- // no support for non-stereo files at the moment
- BASS_ChannelGetInfo(Handle, Info);
- if (Info.chans <> 2) then
- Exit;
-
- nBytes := BASS_ChannelGetData(Handle, @Data, SizeOf(TPCMData));
- if(nBytes <= 0) then
- Result := 0
- else
- Result := nBytes div SizeOf(TPCMStereoSample);
-end;
-
-function TBassPlaybackStream.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- if assigned(SourceStream) then
- Result := SourceStream.GetAudioFormatInfo()
- else
- Result := nil;
-end;
-
-
-{ TBassVoiceStream }
-
-function TBassVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
-var
- Flags: DWORD;
-begin
- Result := false;
-
- Close();
-
- if (not inherited Open(ChannelMap, FormatInfo)) then
- Exit;
-
- // get channel flags
- BassCore.ConvertAudioFormatToBASSFlags(FormatInfo.Format, Flags);
-
- (*
- // distribute the mics equally to both speakers
- if ((ChannelMap and CHANNELMAP_LEFT) <> 0) then
- Flags := Flags or BASS_SPEAKER_FRONTLEFT;
- if ((ChannelMap and CHANNELMAP_RIGHT) <> 0) then
- Flags := Flags or BASS_SPEAKER_FRONTRIGHT;
- *)
-
- // create the channel
- Handle := BASS_StreamCreate(Round(FormatInfo.SampleRate), 1, Flags, STREAMPROC_PUSH, nil);
-
- // start the channel
- BASS_ChannelPlay(Handle, true);
-
- Result := true;
-end;
-
-procedure TBassVoiceStream.Close();
-begin
- if (Handle <> 0) then
- begin
- BASS_ChannelStop(Handle);
- BASS_StreamFree(Handle);
- end;
- inherited Close();
-end;
-
-procedure TBassVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
-var QueueSize: DWORD;
-begin
- if ((Handle <> 0) and (BufferSize > 0)) then
- begin
- // query the queue size (normally 0)
- QueueSize := BASS_StreamPutData(Handle, nil, 0);
- // flush the buffer if the delay would be too high
- if (QueueSize > MAX_VOICE_DELAY * FormatInfo.BytesPerSec) then
- BASS_ChannelPlay(Handle, true);
- // send new data to playback buffer
- BASS_StreamPutData(Handle, Buffer, BufferSize);
- end;
-end;
-
-// Note: we do not need the read-function for the BASS implementation
-function TBassVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-begin
- Result := -1;
-end;
-
-function TBassVoiceStream.IsEOF(): boolean;
-begin
- Result := false;
-end;
-
-function TBassVoiceStream.IsError(): boolean;
-begin
- Result := false;
-end;
-
-
-{ TAudioPlayback_Bass }
-
-function TAudioPlayback_Bass.GetName: String;
-begin
- Result := 'BASS_Playback';
-end;
-
-function TAudioPlayback_Bass.EnumDevices(): boolean;
-var
- BassDeviceID: DWORD;
- DeviceIndex: integer;
- Device: TBassOutputDevice;
- DeviceInfo: BASS_DEVICEINFO;
-begin
- Result := true;
-
- ClearOutputDeviceList();
-
- // skip "no sound"-device (ID = 0)
- BassDeviceID := 1;
-
- while (true) do
- begin
- // check for device
- if (not BASS_GetDeviceInfo(BassDeviceID, DeviceInfo)) then
- Break;
-
- // set device info
- Device := TBassOutputDevice.Create();
- Device.Name := DeviceInfo.name;
- Device.BassDeviceID := BassDeviceID;
-
- // add device to list
- SetLength(OutputDeviceList, BassDeviceID);
- OutputDeviceList[BassDeviceID-1] := Device;
-
- Inc(BassDeviceID);
- end;
-end;
-
-function TAudioPlayback_Bass.InitializePlayback(): boolean;
-begin
- result := false;
-
- BassCore := TAudioCore_Bass.GetInstance();
-
- EnumDevices();
-
- //Log.BenchmarkStart(4);
- //Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
-
- // TODO: use BASS_DEVICE_LATENCY to determine the latency
- if not BASS_Init(-1, 44100, 0, 0, nil) then
- begin
- Log.LogError('Could not initialize BASS', 'TAudioPlayback_Bass.InitializePlayback');
- Exit;
- end;
-
- //Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
-
- // config playing buffer
- //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
- //BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
-
- result := true;
-end;
-
-function TAudioPlayback_Bass.FinalizePlayback(): boolean;
-begin
- Close;
- BASS_Free;
- inherited FinalizePlayback();
- Result := true;
-end;
-
-function TAudioPlayback_Bass.CreatePlaybackStream(): TAudioPlaybackStream;
-begin
- Result := TBassPlaybackStream.Create();
-end;
-
-procedure TAudioPlayback_Bass.SetAppVolume(Volume: single);
-begin
- // set volume for this application (ranges from 0..10000 since BASS 2.4)
- BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Round(Volume*10000));
-end;
-
-function TAudioPlayback_Bass.CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
-var
- VoiceStream: TAudioVoiceStream;
-begin
- Result := nil;
-
- VoiceStream := TBassVoiceStream.Create();
- if (not VoiceStream.Open(ChannelMap, FormatInfo)) then
- begin
- VoiceStream.Free;
- Exit;
- end;
-
- Result := VoiceStream;
-end;
-
-function TAudioPlayback_Bass.GetLatency(): double;
-begin
- Result := 0;
-end;
-
-
-initialization
- MediaManager.Add(TAudioPlayback_Bass.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioPlayback_Portaudio.pas b/Game/Code/Classes/UAudioPlayback_Portaudio.pas
deleted file mode 100644
index c3717ba6..00000000
--- a/Game/Code/Classes/UAudioPlayback_Portaudio.pas
+++ /dev/null
@@ -1,361 +0,0 @@
-unit UAudioPlayback_Portaudio;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- UMusic;
-
-implementation
-
-uses
- portaudio,
- UAudioCore_Portaudio,
- UAudioPlayback_SoftMixer,
- ULog,
- UIni,
- UMain;
-
-type
- TAudioPlayback_Portaudio = class(TAudioPlayback_SoftMixer)
- private
- paStream: PPaStream;
- AudioCore: TAudioCore_Portaudio;
- Latency: double;
- function OpenDevice(deviceIndex: TPaDeviceIndex): boolean;
- function EnumDevices(): boolean;
- protected
- function InitializeAudioPlaybackEngine(): boolean; override;
- function StartAudioPlaybackEngine(): boolean; override;
- procedure StopAudioPlaybackEngine(); override;
- function FinalizeAudioPlaybackEngine(): boolean; override;
- function GetLatency(): double; override;
- public
- function GetName: String; override;
- end;
-
- TPortaudioOutputDevice = class(TAudioOutputDevice)
- private
- PaDeviceIndex: TPaDeviceIndex;
- end;
-
-
-{ TAudioPlayback_Portaudio }
-
-function PortaudioAudioCallback(input: Pointer; output: Pointer; frameCount: Longword;
- timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- userData: Pointer): Integer; cdecl;
-var
- Engine: TAudioPlayback_Portaudio;
-begin
- Engine := TAudioPlayback_Portaudio(userData);
- // update latency
- Engine.Latency := timeInfo.outputBufferDacTime - timeInfo.currentTime;
- // call superclass callback
- Engine.AudioCallback(output, frameCount * Engine.FormatInfo.FrameSize);
- Result := paContinue;
-end;
-
-function TAudioPlayback_Portaudio.GetName: String;
-begin
- Result := 'Portaudio_Playback';
-end;
-
-function TAudioPlayback_Portaudio.OpenDevice(deviceIndex: TPaDeviceIndex): boolean;
-var
- DeviceInfo : PPaDeviceInfo;
- SampleRate : double;
- OutParams : TPaStreamParameters;
- StreamInfo : PPaStreamInfo;
- err : TPaError;
-begin
- Result := false;
-
- DeviceInfo := Pa_GetDeviceInfo(deviceIndex);
-
- Log.LogInfo('Audio-Output Device: ' + DeviceInfo^.name, 'TAudioPlayback_Portaudio.OpenDevice');
-
- SampleRate := DeviceInfo^.defaultSampleRate;
-
- with OutParams do
- begin
- device := deviceIndex;
- channelCount := 2;
- sampleFormat := paInt16;
- suggestedLatency := DeviceInfo^.defaultLowOutputLatency;
- hostApiSpecificStreamInfo := nil;
- end;
-
- // check souncard and adjust sample-rate
- if not AudioCore.TestDevice(nil, @OutParams, SampleRate) then
- begin
- Log.LogStatus('TestDevice failed!', 'TAudioPlayback_Portaudio.OpenDevice');
- Exit;
- end;
-
- // open output stream
- err := Pa_OpenStream(paStream, nil, @OutParams, SampleRate,
- paFramesPerBufferUnspecified,
- paNoFlag, @PortaudioAudioCallback, Self);
- if(err <> paNoError) then
- begin
- Log.LogStatus(Pa_GetErrorText(err), 'TAudioPlayback_Portaudio.OpenDevice');
- paStream := nil;
- Exit;
- end;
-
- // get estimated latency (will be updated with real latency in the callback)
- StreamInfo := Pa_GetStreamInfo(paStream);
- if (StreamInfo <> nil) then
- Latency := StreamInfo^.outputLatency
- else
- Latency := 0;
-
- FormatInfo := TAudioFormatInfo.Create(
- OutParams.channelCount,
- SampleRate,
- asfS16 // FIXME: is paInt16 system-dependant or -independant?
- );
-
- Result := true;
-end;
-
-function TAudioPlayback_Portaudio.EnumDevices(): boolean;
-var
- i: integer;
- paApiIndex: TPaHostApiIndex;
- paApiInfo: PPaHostApiInfo;
- deviceName: string;
- deviceIndex: TPaDeviceIndex;
- deviceInfo: PPaDeviceInfo;
- channelCnt: integer;
- SC: integer; // soundcard
- err: TPaError;
- errMsg: string;
- paDevice: TPortaudioOutputDevice;
- outputParams: TPaStreamParameters;
- stream: PPaStream;
- streamInfo: PPaStreamInfo;
- sampleRate: double;
- latency: TPaTime;
- cbPolls: integer;
- cbWorks: boolean;
-begin
- Result := false;
-
-(*
- // choose the best available Audio-API
- paApiIndex := AudioCore.GetPreferredApiIndex();
- if(paApiIndex = -1) then
- begin
- Log.LogError('No working Audio-API found', 'TAudioPlayback_Portaudio.EnumDevices');
- Exit;
- end;
-
- paApiInfo := Pa_GetHostApiInfo(paApiIndex);
-
- SC := 0;
-
- // init array-size to max. output-devices count
- SetLength(OutputDeviceList, paApiInfo^.deviceCount);
- for i:= 0 to High(OutputDeviceList) do
- begin
- // convert API-specific device-index to global index
- deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
- deviceInfo := Pa_GetDeviceInfo(deviceIndex);
-
- channelCnt := deviceInfo^.maxOutputChannels;
-
- // current device is no output device -> skip
- if (channelCnt <= 0) then
- continue;
-
- // portaudio returns a channel-count of 128 for some devices
- // (e.g. the "default"-device), so we have to detect those
- // fantasy channel counts.
- if (channelCnt > 8) then
- channelCnt := 2;
-
- paDevice := TPortaudioOutputDevice.Create();
- OutputDeviceList[SC] := paDevice;
-
- // retrieve device-name
- deviceName := deviceInfo^.name;
- paDevice.Name := deviceName;
- paDevice.PaDeviceIndex := deviceIndex;
-
- if (deviceInfo^.defaultSampleRate > 0) then
- sampleRate := deviceInfo^.defaultSampleRate
- else
- sampleRate := 44100;
-
- // on vista and xp the defaultLowInputLatency may be set to 0 but it works.
- // TODO: correct too low latencies (what is a too low latency, maybe < 10ms?)
- latency := deviceInfo^.defaultLowInputLatency;
-
- // setup desired output parameters
- // TODO: retry with input-latency set to 20ms (defaultLowOutputLatency might
- // not be set correctly in OSS)
- with outputParams do
- begin
- device := deviceIndex;
- channelCount := channelCnt;
- sampleFormat := paInt16;
- suggestedLatency := latency;
- hostApiSpecificStreamInfo := nil;
- end;
-
- // check if mic-callback works (might not be called on some devices)
- if (not TAudioCore_Portaudio.TestDevice(nil, @outputParams, sampleRate)) then
- begin
- // ignore device if callback did not work
- Log.LogError('Device "'+paDevice.Name+'" does not respond',
- 'TAudioPlayback_Portaudio.InitializeRecord');
- paDevice.Free();
- continue;
- end;
-
- // open device for further info
- err := Pa_OpenStream(stream, nil, @outputParams, sampleRate,
- paFramesPerBufferUnspecified, paNoFlag, @MicrophoneTestCallback, nil);
- if(err <> paNoError) then
- begin
- // unable to open device -> skip
- errMsg := Pa_GetErrorText(err);
- Log.LogError('Device error: "'+ deviceName +'" ('+ errMsg +')',
- 'TAudioPlayback_Portaudio.InitializeRecord');
- paDevice.Free();
- continue;
- end;
-
- // adjust sample-rate (might be changed by portaudio)
- streamInfo := Pa_GetStreamInfo(stream);
- if (streamInfo <> nil) then
- begin
- if (sampleRate <> streamInfo^.sampleRate) then
- begin
- Log.LogStatus('Portaudio changed Samplerate from ' + FloatToStr(sampleRate) +
- ' to ' + FloatToStr(streamInfo^.sampleRate),
- 'TAudioInput_Portaudio.InitializeRecord');
- sampleRate := streamInfo^.sampleRate;
- end;
- end;
-
- // create audio-format info and resize capture-buffer array
- paDevice.AudioFormat := TAudioFormatInfo.Create(
- channelCnt,
- sampleRate,
- asfS16
- );
- SetLength(paDevice.CaptureChannel, paDevice.AudioFormat.Channels);
-
- Log.LogStatus('OutputDevice "'+paDevice.Name+'"@' +
- IntToStr(paDevice.AudioFormat.Channels)+'x'+
- FloatToStr(paDevice.AudioFormat.SampleRate)+'Hz ('+
- FloatTostr(outputParams.suggestedLatency)+'sec)' ,
- 'TAudioInput_Portaudio.InitializeRecord');
-
- // close test-stream
- Pa_CloseStream(stream);
-
- Inc(SC);
- end;
-
- // adjust size to actual input-device count
- SetLength(OutputDeviceList, SC);
-
- Log.LogStatus('#Output-Devices: ' + inttostr(SC), 'Portaudio');
-*)
-
- Result := true;
-end;
-
-function TAudioPlayback_Portaudio.InitializeAudioPlaybackEngine(): boolean;
-var
- paApiIndex : TPaHostApiIndex;
- paApiInfo : PPaHostApiInfo;
- paOutDevice : TPaDeviceIndex;
- err: TPaError;
-begin
- Result := false;
-
- AudioCore := TAudioCore_Portaudio.GetInstance();
-
- // initialize portaudio
- err := Pa_Initialize();
- if(err <> paNoError) then
- begin
- Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord');
- Exit;
- end;
-
- paApiIndex := AudioCore.GetPreferredApiIndex();
- if(paApiIndex = -1) then
- begin
- Log.LogError('No working Audio-API found', 'TAudioPlayback_Portaudio.InitializeAudioPlaybackEngine');
- Exit;
- end;
-
- EnumDevices();
-
- paApiInfo := Pa_GetHostApiInfo(paApiIndex);
- Log.LogInfo('Audio-Output API-Type: ' + paApiInfo^.name, 'TAudioPlayback_Portaudio.OpenDevice');
-
- paOutDevice := paApiInfo^.defaultOutputDevice;
- if (not OpenDevice(paOutDevice)) then
- begin
- Exit;
- end;
-
- Result := true;
-end;
-
-function TAudioPlayback_Portaudio.StartAudioPlaybackEngine(): boolean;
-var
- err: TPaError;
-begin
- Result := false;
-
- if (paStream = nil) then
- Exit;
-
- err := Pa_StartStream(paStream);
- if(err <> paNoError) then
- begin
- Log.LogStatus('Pa_StartStream: '+Pa_GetErrorText(err), 'UAudioPlayback_Portaudio');
- Exit;
- end;
-
- Result := true;
-end;
-
-procedure TAudioPlayback_Portaudio.StopAudioPlaybackEngine();
-begin
- if (paStream <> nil) then
- Pa_StopStream(paStream);
-end;
-
-function TAudioPlayback_Portaudio.FinalizeAudioPlaybackEngine(): boolean;
-begin
- Pa_Terminate();
- Result := true;
-end;
-
-function TAudioPlayback_Portaudio.GetLatency(): double;
-begin
- Result := Latency;
-end;
-
-
-initialization
- MediaManager.Add(TAudioPlayback_Portaudio.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioPlayback_SDL.pas b/Game/Code/Classes/UAudioPlayback_SDL.pas
deleted file mode 100644
index deef91e8..00000000
--- a/Game/Code/Classes/UAudioPlayback_SDL.pas
+++ /dev/null
@@ -1,160 +0,0 @@
-unit UAudioPlayback_SDL;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- UMusic;
-
-implementation
-
-uses
- sdl,
- UAudioPlayback_SoftMixer,
- ULog,
- UIni,
- UMain;
-
-type
- TAudioPlayback_SDL = class(TAudioPlayback_SoftMixer)
- private
- Latency: double;
- function EnumDevices(): boolean;
- protected
- function InitializeAudioPlaybackEngine(): boolean; override;
- function StartAudioPlaybackEngine(): boolean; override;
- procedure StopAudioPlaybackEngine(); override;
- function FinalizeAudioPlaybackEngine(): boolean; override;
- function GetLatency(): double; override;
- public
- function GetName: String; override;
- procedure MixBuffers(dst, src: PChar; size: Cardinal; volume: Single); override;
- end;
-
-
-{ TAudioPlayback_SDL }
-
-procedure SDLAudioCallback(userdata: Pointer; stream: PChar; len: integer); cdecl;
-var
- Engine: TAudioPlayback_SDL;
-begin
- Engine := TAudioPlayback_SDL(userdata);
- Engine.AudioCallback(stream, len);
-end;
-
-function TAudioPlayback_SDL.GetName: String;
-begin
- Result := 'SDL_Playback';
-end;
-
-function TAudioPlayback_SDL.EnumDevices(): boolean;
-begin
- // Note: SDL does not provide Device-Selection capabilities (will be introduced in 1.3)
- ClearOutputDeviceList();
- SetLength(OutputDeviceList, 1);
- OutputDeviceList[0] := TAudioOutputDevice.Create();
- OutputDeviceList[0].Name := '[SDL Default-Device]';
- Result := true;
-end;
-
-function TAudioPlayback_SDL.InitializeAudioPlaybackEngine(): boolean;
-var
- DesiredAudioSpec, ObtainedAudioSpec: TSDL_AudioSpec;
- SampleBufferSize: integer;
-begin
- Result := false;
-
- EnumDevices();
-
- if (SDL_InitSubSystem(SDL_INIT_AUDIO) = -1) then
- begin
- Log.LogError('SDL_InitSubSystem failed!', 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
- Exit;
- end;
-
- SampleBufferSize := IAudioOutputBufferSizeVals[Ini.AudioOutputBufferSizeIndex];
- if (SampleBufferSize <= 0) then
- begin
- // Automatic setting default
- // FIXME: too much glitches with 1024 samples
- SampleBufferSize := 2048; //1024;
- end;
-
- FillChar(DesiredAudioSpec, SizeOf(DesiredAudioSpec), 0);
- with DesiredAudioSpec do
- begin
- freq := 44100;
- format := AUDIO_S16SYS;
- channels := 2;
- samples := SampleBufferSize;
- callback := @SDLAudioCallback;
- userdata := Self;
- end;
-
- // Note: always use the "obtained" parameter, otherwise SDL might try to convert
- // the samples itself if the desired format is not available. This might lead
- // to problems if for example ALSA does not support 44100Hz and proposes 48000Hz.
- // Without the obtained parameter, SDL would try to convert 44.1kHz to 48kHz with
- // its crappy (non working) converter resulting in a wrong (too high) pitch.
- if(SDL_OpenAudio(@DesiredAudioSpec, @ObtainedAudioSpec) = -1) then
- begin
- Log.LogStatus('SDL_OpenAudio: ' + SDL_GetError(), 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
- Exit;
- end;
-
- FormatInfo := TAudioFormatInfo.Create(
- ObtainedAudioSpec.channels,
- ObtainedAudioSpec.freq,
- asfS16
- );
-
- // Note: SDL does not provide info of the internal buffer state.
- // So we use the average buffer-size.
- Latency := (ObtainedAudioSpec.samples/2) / FormatInfo.SampleRate;
-
- Log.LogStatus('Opened audio device', 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
-
- Result := true;
-end;
-
-function TAudioPlayback_SDL.StartAudioPlaybackEngine(): boolean;
-begin
- SDL_PauseAudio(0);
- Result := true;
-end;
-
-procedure TAudioPlayback_SDL.StopAudioPlaybackEngine();
-begin
- SDL_PauseAudio(1);
-end;
-
-function TAudioPlayback_SDL.FinalizeAudioPlaybackEngine(): boolean;
-begin
- SDL_CloseAudio();
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
- Result := true;
-end;
-
-function TAudioPlayback_SDL.GetLatency(): double;
-begin
- Result := Latency;
-end;
-
-procedure TAudioPlayback_SDL.MixBuffers(dst, src: PChar; size: Cardinal; volume: Single);
-begin
- SDL_MixAudio(PUInt8(dst), PUInt8(src), size, Round(volume * SDL_MIX_MAXVOLUME));
-end;
-
-
-initialization
- MediaManager.add(TAudioPlayback_SDL.Create);
-
-end.
diff --git a/Game/Code/Classes/UAudioPlayback_SoftMixer.pas b/Game/Code/Classes/UAudioPlayback_SoftMixer.pas
deleted file mode 100644
index 6ddae980..00000000
--- a/Game/Code/Classes/UAudioPlayback_SoftMixer.pas
+++ /dev/null
@@ -1,1132 +0,0 @@
-unit UAudioPlayback_SoftMixer;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- Classes,
- SysUtils,
- sdl,
- URingBuffer,
- UMusic,
- UAudioPlaybackBase;
-
-type
- TAudioPlayback_SoftMixer = class;
-
- TGenericPlaybackStream = class(TAudioPlaybackStream)
- private
- Engine: TAudioPlayback_SoftMixer;
-
- SampleBuffer: PChar;
- SampleBufferSize: integer;
- SampleBufferCount: integer; // number of available bytes in SampleBuffer
- SampleBufferPos: cardinal;
-
- SourceBuffer: PChar;
- SourceBufferSize: integer;
- SourceBufferCount: integer; // number of available bytes in SourceBuffer
-
- Converter: TAudioConverter;
- Status: TStreamStatus;
- InternalLock: PSDL_Mutex;
- SoundEffects: TList;
- fVolume: single;
-
- FadeInStartTime, FadeInTime: cardinal;
- FadeInStartVolume, FadeInTargetVolume: single;
-
- NeedsRewind: boolean;
-
- procedure Reset();
-
- procedure ApplySoundEffects(Buffer: PChar; BufferSize: integer);
- function InitFormatConversion(): boolean;
- procedure FlushBuffers();
-
- procedure LockSampleBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
- procedure UnlockSampleBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
- protected
- function GetLatency(): double; override;
- function GetStatus(): TStreamStatus; override;
- function GetVolume(): single; override;
- procedure SetVolume(Volume: single); override;
- function GetLength(): real; override;
- function GetLoop(): boolean; override;
- procedure SetLoop(Enabled: boolean); override;
- function GetPosition: real; override;
- procedure SetPosition(Time: real); override;
- public
- constructor Create(Engine: TAudioPlayback_SoftMixer);
- destructor Destroy(); override;
-
- function Open(SourceStream: TAudioSourceStream): boolean; override;
- procedure Close(); override;
-
- procedure Play(); override;
- procedure Pause(); override;
- procedure Stop(); override;
- procedure FadeIn(Time: real; TargetVolume: single); override;
-
- function GetAudioFormatInfo(): TAudioFormatInfo; override;
-
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
-
- function GetPCMData(var Data: TPCMData): Cardinal; override;
- procedure GetFFTData(var Data: TFFTData); override;
-
- procedure AddSoundEffect(Effect: TSoundEffect); override;
- procedure RemoveSoundEffect(Effect: TSoundEffect); override;
- end;
-
- TAudioMixerStream = class
- private
- Engine: TAudioPlayback_SoftMixer;
-
- ActiveStreams: TList;
- MixerBuffer: PChar;
- InternalLock: PSDL_Mutex;
-
- AppVolume: single;
-
- procedure Lock(); {$IFDEF HasInline}inline;{$ENDIF}
- procedure Unlock(); {$IFDEF HasInline}inline;{$ENDIF}
-
- function GetVolume(): single;
- procedure SetVolume(Volume: single);
- public
- constructor Create(Engine: TAudioPlayback_SoftMixer);
- destructor Destroy(); override;
- procedure AddStream(Stream: TAudioPlaybackStream);
- procedure RemoveStream(Stream: TAudioPlaybackStream);
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
-
- property Volume: single read GetVolume write SetVolume;
- end;
-
- TAudioPlayback_SoftMixer = class(TAudioPlaybackBase)
- private
- MixerStream: TAudioMixerStream;
- protected
- FormatInfo: TAudioFormatInfo;
-
- function InitializeAudioPlaybackEngine(): boolean; virtual; abstract;
- function StartAudioPlaybackEngine(): boolean; virtual; abstract;
- procedure StopAudioPlaybackEngine(); virtual; abstract;
- function FinalizeAudioPlaybackEngine(): boolean; virtual; abstract;
- procedure AudioCallback(Buffer: PChar; Size: integer); {$IFDEF HasInline}inline;{$ENDIF}
-
- function CreatePlaybackStream(): TAudioPlaybackStream; override;
- public
- function GetName: String; override; abstract;
- function InitializePlayback(): boolean; override;
- function FinalizePlayback: boolean; override;
-
- procedure SetAppVolume(Volume: single); override;
-
- function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; override;
-
- function GetMixer(): TAudioMixerStream; {$IFDEF HasInline}inline;{$ENDIF}
- function GetAudioFormatInfo(): TAudioFormatInfo;
-
- procedure MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single); virtual;
- end;
-
-type
- TGenericVoiceStream = class(TAudioVoiceStream)
- private
- VoiceBuffer: TRingBuffer;
- BufferLock: PSDL_Mutex;
- PlaybackStream: TGenericPlaybackStream;
- Engine: TAudioPlayback_SoftMixer;
- public
- constructor Create(Engine: TAudioPlayback_SoftMixer);
-
- function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
- procedure Close(); override;
- procedure WriteData(Buffer: PChar; BufferSize: integer); override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
- function IsEOF(): boolean; override;
- function IsError(): boolean; override;
- end;
-
-const
- SOURCE_BUFFER_FRAMES = 4096;
-
-const
- MAX_VOICE_DELAY = 0.500; // 20ms
-
-implementation
-
-uses
- Math,
- ULog,
- UIni,
- UFFT,
- UAudioConverter,
- UMain;
-
-{ TAudioMixerStream }
-
-constructor TAudioMixerStream.Create(Engine: TAudioPlayback_SoftMixer);
-begin
- inherited Create();
-
- Self.Engine := Engine;
-
- ActiveStreams := TList.Create;
- InternalLock := SDL_CreateMutex();
- AppVolume := 1.0;
-end;
-
-destructor TAudioMixerStream.Destroy();
-begin
- if assigned(MixerBuffer) then
- Freemem(MixerBuffer);
- ActiveStreams.Free;
- SDL_DestroyMutex(InternalLock);
- inherited;
-end;
-
-procedure TAudioMixerStream.Lock();
-begin
- SDL_mutexP(InternalLock);
-end;
-
-procedure TAudioMixerStream.Unlock();
-begin
- SDL_mutexV(InternalLock);
-end;
-
-function TAudioMixerStream.GetVolume(): single;
-begin
- Lock();
- Result := AppVolume;
- Unlock();
-end;
-
-procedure TAudioMixerStream.SetVolume(Volume: single);
-begin
- Lock();
- AppVolume := Volume;
- Unlock();
-end;
-
-procedure TAudioMixerStream.AddStream(Stream: TAudioPlaybackStream);
-begin
- if not assigned(Stream) then
- Exit;
-
- Lock();
- // check if stream is already in list to avoid duplicates
- if (ActiveStreams.IndexOf(Pointer(Stream)) = -1) then
- ActiveStreams.Add(Pointer(Stream));
- Unlock();
-end;
-
-(*
- * Sets the entry of stream in the ActiveStreams-List to nil
- * but does not remove it from the list (Count is not changed!).
- * Otherwise iterations over the elements might fail due to a
- * changed Count-property.
- * Call ActiveStreams.Pack() to remove the nil-pointers
- * or check for nil-pointers when accessing ActiveStreams.
- *)
-procedure TAudioMixerStream.RemoveStream(Stream: TAudioPlaybackStream);
-var
- Index: integer;
-begin
- Lock();
- Index := activeStreams.IndexOf(Pointer(Stream));
- if (Index <> -1) then
- begin
- // remove entry but do not decrease count-property
- ActiveStreams[Index] := nil;
- end;
- Unlock();
-end;
-
-function TAudioMixerStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-var
- i: integer;
- Size: integer;
- Stream: TGenericPlaybackStream;
- NeedsPacking: boolean;
-begin
- Result := BufferSize;
-
- // zero target-buffer (silence)
- FillChar(Buffer^, BufferSize, 0);
-
- // resize mixer-buffer if necessary
- ReallocMem(MixerBuffer, BufferSize);
- if not assigned(MixerBuffer) then
- Exit;
-
- Lock();
-
- NeedsPacking := false;
-
- // mix streams to one stream
- for i := 0 to ActiveStreams.Count-1 do
- begin
- if (ActiveStreams[i] = nil) then
- begin
- NeedsPacking := true;
- continue;
- end;
-
- Stream := TGenericPlaybackStream(ActiveStreams[i]);
- // fetch data from current stream
- Size := Stream.ReadData(MixerBuffer, BufferSize);
- if (Size > 0) then
- begin
- // mix stream-data with mixer-buffer
- // Note: use Self.appVolume instead of Self.Volume to prevent recursive locking
- Engine.MixBuffers(Buffer, MixerBuffer, Size, AppVolume * Stream.Volume);
- end;
- end;
-
- // remove nil-pointers from list
- if (NeedsPacking) then
- begin
- ActiveStreams.Pack();
- end;
-
- Unlock();
-end;
-
-
-{ TGenericPlaybackStream }
-
-constructor TGenericPlaybackStream.Create(Engine: TAudioPlayback_SoftMixer);
-begin
- inherited Create();
- Self.Engine := Engine;
- InternalLock := SDL_CreateMutex();
- SoundEffects := TList.Create;
- Status := ssStopped;
- Reset();
-end;
-
-destructor TGenericPlaybackStream.Destroy();
-begin
- Close();
- SDL_DestroyMutex(InternalLock);
- FreeAndNil(SoundEffects);
- inherited;
-end;
-
-procedure TGenericPlaybackStream.Reset();
-begin
- SourceStream := nil;
-
- FreeAndNil(Converter);
-
- FreeMem(SampleBuffer);
- SampleBuffer := nil;
- SampleBufferPos := 0;
- SampleBufferSize := 0;
- SampleBufferCount := 0;
-
- FreeMem(SourceBuffer);
- SourceBuffer := nil;
- SourceBufferSize := 0;
- SourceBufferCount := 0;
-
- NeedsRewind := false;
-
- fVolume := 0;
- SoundEffects.Clear;
- FadeInTime := 0;
-end;
-
-function TGenericPlaybackStream.Open(SourceStream: TAudioSourceStream): boolean;
-begin
- Result := false;
-
- Close();
-
- if (not assigned(SourceStream)) then
- Exit;
- Self.SourceStream := SourceStream;
-
- if (not InitFormatConversion()) then
- begin
- // reset decode-stream so it will not be freed on destruction
- Self.SourceStream := nil;
- Exit;
- end;
-
- SourceBufferSize := SOURCE_BUFFER_FRAMES * SourceStream.GetAudioFormatInfo().FrameSize;
- GetMem(SourceBuffer, SourceBufferSize);
- fVolume := 1.0;
-
- Result := true;
-end;
-
-procedure TGenericPlaybackStream.Close();
-begin
- // stop audio-callback on this stream
- Stop();
-
- // Note: PerformOnClose must be called before SourceStream is invalidated
- PerformOnClose();
- // and free data
- Reset();
-end;
-
-procedure TGenericPlaybackStream.LockSampleBuffer();
-begin
- SDL_mutexP(InternalLock);
-end;
-
-procedure TGenericPlaybackStream.UnlockSampleBuffer();
-begin
- SDL_mutexV(InternalLock);
-end;
-
-function TGenericPlaybackStream.InitFormatConversion(): boolean;
-var
- SrcFormatInfo: TAudioFormatInfo;
- DstFormatInfo: TAudioFormatInfo;
-begin
- Result := false;
-
- SrcFormatInfo := SourceStream.GetAudioFormatInfo();
- DstFormatInfo := GetAudioFormatInfo();
-
- // TODO: selection should not be done here, use a factory (TAudioConverterFactory) instead
- {$IF Defined(UseFFmpegResample)}
- Converter := TAudioConverter_FFmpeg.Create();
- {$ELSEIF Defined(UseSRCResample)}
- Converter := TAudioConverter_SRC.Create();
- {$ELSE}
- Converter := TAudioConverter_SDL.Create();
- {$IFEND}
-
- Result := Converter.Init(SrcFormatInfo, DstFormatInfo);
-end;
-
-procedure TGenericPlaybackStream.Play();
-var
- Mixer: TAudioMixerStream;
-begin
- // only paused streams are not flushed
- if (Status = ssPaused) then
- NeedsRewind := false;
-
- // rewind if necessary. Cases that require no rewind are:
- // - stream was created and never played
- // - stream was paused and is resumed now
- // - stream was stopped and set to a new position already
- if (NeedsRewind) then
- SetPosition(0);
-
- // update status
- Status := ssPlaying;
-
- NeedsRewind := true;
-
- // add this stream to the mixer
- Mixer := Engine.GetMixer();
- if (Mixer <> nil) then
- Mixer.AddStream(Self);
-end;
-
-procedure TGenericPlaybackStream.FadeIn(Time: real; TargetVolume: single);
-begin
- FadeInTime := Trunc(Time * 1000);
- FadeInStartTime := SDL_GetTicks();
- FadeInStartVolume := fVolume;
- FadeInTargetVolume := TargetVolume;
- Play();
-end;
-
-procedure TGenericPlaybackStream.Pause();
-var
- Mixer: TAudioMixerStream;
-begin
- if (Status <> ssPlaying) then
- Exit;
-
- Status := ssPaused;
-
- Mixer := Engine.GetMixer();
- if (Mixer <> nil) then
- Mixer.RemoveStream(Self);
-end;
-
-procedure TGenericPlaybackStream.Stop();
-var
- Mixer: TAudioMixerStream;
-begin
- if (Status = ssStopped) then
- Exit;
-
- Status := ssStopped;
-
- Mixer := Engine.GetMixer();
- if (Mixer <> nil) then
- Mixer.RemoveStream(Self);
-end;
-
-function TGenericPlaybackStream.GetLoop(): boolean;
-begin
- if assigned(SourceStream) then
- Result := SourceStream.Loop
- else
- Result := false;
-end;
-
-procedure TGenericPlaybackStream.SetLoop(Enabled: boolean);
-begin
- if assigned(SourceStream) then
- SourceStream.Loop := Enabled;
-end;
-
-function TGenericPlaybackStream.GetLength(): real;
-begin
- if assigned(SourceStream) then
- Result := SourceStream.Length
- else
- Result := -1;
-end;
-
-function TGenericPlaybackStream.GetLatency(): double;
-begin
- Result := Engine.GetLatency();
-end;
-
-function TGenericPlaybackStream.GetStatus(): TStreamStatus;
-begin
- Result := Status;
-end;
-
-function TGenericPlaybackStream.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- Result := Engine.GetAudioFormatInfo();
-end;
-
-procedure TGenericPlaybackStream.FlushBuffers();
-begin
- SampleBufferCount := 0;
- SampleBufferPos := 0;
- SourceBufferCount := 0;
-end;
-
-procedure TGenericPlaybackStream.ApplySoundEffects(Buffer: PChar; BufferSize: integer);
-var
- i: integer;
-begin
- for i := 0 to SoundEffects.Count-1 do
- begin
- if (SoundEffects[i] <> nil) then
- begin
- TSoundEffect(SoundEffects[i]).Callback(Buffer, BufferSize);
- end;
- end;
-end;
-
-function TGenericPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-var
- ConversionInputCount: integer;
- ConversionOutputSize: integer; // max. number of converted data (= buffer size)
- ConversionOutputCount: integer; // actual number of converted data
- SourceSize: integer;
- RequestedSourceSize: integer;
- NeededSampleBufferSize: integer;
- BytesNeeded, BytesAvail: integer;
- SourceFormatInfo, OutputFormatInfo: TAudioFormatInfo;
- SourceFrameSize, OutputFrameSize: integer;
- SkipOutputCount: integer; // number of output-data bytes to skip
- SkipSourceCount: integer; // number of source-data bytes to skip
- FillCount: integer; // number of bytes to fill with padding data
- CopyCount: integer;
- PadFrame: PChar;
- i: integer;
-begin
- Result := -1;
-
- // sanity check for the source-stream
- if (not assigned(SourceStream)) then
- Exit;
-
- SkipOutputCount := 0;
- SkipSourceCount := 0;
- FillCount := 0;
-
- SourceFormatInfo := SourceStream.GetAudioFormatInfo();
- SourceFrameSize := SourceFormatInfo.FrameSize;
- OutputFormatInfo := GetAudioFormatInfo();
- OutputFrameSize := OutputFormatInfo.FrameSize;
-
- // synchronize (adjust buffer size)
- BytesNeeded := Synchronize(BufferSize, OutputFormatInfo);
- if (BytesNeeded > BufferSize) then
- begin
- SkipOutputCount := BytesNeeded - BufferSize;
- BytesNeeded := BufferSize;
- end
- else if (BytesNeeded < BufferSize) then
- begin
- FillCount := BufferSize - BytesNeeded;
- end;
-
- // lock access to sample-buffer
- LockSampleBuffer();
- try
-
- // skip sample-buffer data
- SampleBufferPos := SampleBufferPos + SkipOutputCount;
- // size of available bytes in SampleBuffer after skipping
- SampleBufferCount := SampleBufferCount - SampleBufferPos;
- // update byte skip-count
- SkipOutputCount := -SampleBufferCount;
-
- // now that we skipped all buffered data from the last pass, we have to skip
- // data directly after fetching it from the source-stream.
- if (SkipOutputCount > 0) then
- begin
- SampleBufferCount := 0;
- // convert skip-count to source-format units and resize to a multiple of
- // the source frame-size.
- SkipSourceCount := Round((SkipOutputCount * OutputFormatInfo.GetRatio(SourceFormatInfo)) /
- SourceFrameSize) * SourceFrameSize;
- SkipOutputCount := 0;
- end;
-
- // copy data to front of buffer
- if ((SampleBufferCount > 0) and (SampleBufferPos > 0)) then
- Move(SampleBuffer[SampleBufferPos], SampleBuffer[0], SampleBufferCount);
- SampleBufferPos := 0;
-
- // resize buffer to a reasonable size
- if (BufferSize > SampleBufferCount) then
- begin
- // Note: use BufferSize instead of BytesNeeded to minimize the need for resizing
- SampleBufferSize := BufferSize;
- ReallocMem(SampleBuffer, SampleBufferSize);
- if (not assigned(SampleBuffer)) then
- Exit;
- end;
-
- // fill sample-buffer (fetch and convert one block of source data per loop)
- while (SampleBufferCount < BytesNeeded) do
- begin
- // move remaining source data from the previous pass to front of buffer
- if (SourceBufferCount > 0) then
- begin
- Move(SourceBuffer[SourceBufferSize-SourceBufferCount],
- SourceBuffer[0],
- SourceBufferCount);
- end;
-
- SourceSize := SourceStream.ReadData(
- @SourceBuffer[SourceBufferCount], SourceBufferSize-SourceBufferCount);
- // break on error (-1) or if no data is available (0), e.g. while seeking
- if (SourceSize <= 0) then
- begin
- // if we do not have data -> exit
- if (SourceBufferCount = 0) then
- begin
- FlushBuffers();
- Exit;
- end;
- // if we have some data, stop retrieving data from the source stream
- // and use the data we have so far
- Break;
- end;
-
- SourceBufferCount := SourceBufferCount + SourceSize;
-
- // end-of-file reached -> stop playback
- if (SourceStream.EOF) then
- begin
- if (Loop) then
- SourceStream.Position := 0
- else
- Stop();
- end;
-
- if (SkipSourceCount > 0) then
- begin
- // skip data and update source buffer count
- SourceBufferCount := SourceBufferCount - SkipSourceCount;
- SkipSourceCount := -SourceBufferCount;
- // continue with next pass if we skipped all data
- if (SourceBufferCount <= 0) then
- begin
- SourceBufferCount := 0;
- Continue;
- end;
- end;
-
- // calc buffer size (might be bigger than actual resampled byte count)
- ConversionOutputSize := Converter.GetOutputBufferSize(SourceBufferCount);
- NeededSampleBufferSize := SampleBufferCount + ConversionOutputSize;
-
- // resize buffer if necessary
- if (SampleBufferSize < NeededSampleBufferSize) then
- begin
- SampleBufferSize := NeededSampleBufferSize;
- ReallocMem(SampleBuffer, SampleBufferSize);
- if (not assigned(SampleBuffer)) then
- begin
- FlushBuffers();
- Exit;
- end;
- end;
-
- // resample source data (Note: ConversionInputCount might be adjusted by Convert())
- ConversionInputCount := SourceBufferCount;
- ConversionOutputCount := Converter.Convert(
- SourceBuffer, @SampleBuffer[SampleBufferCount], ConversionInputCount);
- if (ConversionOutputCount = -1) then
- begin
- FlushBuffers();
- Exit;
- end;
-
- // adjust sample- and source-buffer count by the number of converted bytes
- SampleBufferCount := SampleBufferCount + ConversionOutputCount;
- SourceBufferCount := SourceBufferCount - ConversionInputCount;
- end;
-
- // apply effects
- ApplySoundEffects(SampleBuffer, SampleBufferCount);
-
- // copy data to result buffer
- CopyCount := Min(BytesNeeded, SampleBufferCount);
- Move(SampleBuffer[0], Buffer[BufferSize - BytesNeeded], CopyCount);
- Dec(BytesNeeded, CopyCount);
- SampleBufferPos := CopyCount;
-
- // release buffer lock
- finally
- UnlockSampleBuffer();
- end;
-
- // pad the buffer with the last frame if we are to fast
- if (FillCount > 0) then
- begin
- if (CopyCount >= OutputFrameSize) then
- PadFrame := @Buffer[CopyCount-OutputFrameSize]
- else
- PadFrame := nil;
- FillBufferWithFrame(@Buffer[CopyCount], FillCount,
- PadFrame, OutputFrameSize);
- end;
-
- // BytesNeeded now contains the number of remaining bytes we were not able to fetch
- Result := BufferSize - BytesNeeded;
-end;
-
-function TGenericPlaybackStream.GetPCMData(var Data: TPCMData): Cardinal;
-var
- ByteCount: integer;
-begin
- Result := 0;
-
- // just SInt16 stereo support for now
- if ((Engine.GetAudioFormatInfo().Format <> asfS16) or
- (Engine.GetAudioFormatInfo().Channels <> 2)) then
- begin
- Exit;
- end;
-
- // zero memory
- FillChar(Data, SizeOf(Data), 0);
-
- // TODO: At the moment just the first samples of the SampleBuffer
- // are returned, even if there is newer data in the upper samples.
-
- LockSampleBuffer();
- ByteCount := Min(SizeOf(Data), SampleBufferCount);
- if (ByteCount > 0) then
- begin
- Move(SampleBuffer[0], Data, ByteCount);
- end;
- UnlockSampleBuffer();
-
- Result := ByteCount div SizeOf(TPCMStereoSample);
-end;
-
-procedure TGenericPlaybackStream.GetFFTData(var Data: TFFTData);
-var
- i: integer;
- Frames: integer;
- DataIn: PSingleArray;
- AudioFormat: TAudioFormatInfo;
-begin
- // only works with SInt16 and Float values at the moment
- AudioFormat := GetAudioFormatInfo();
-
- DataIn := AllocMem(FFTSize * SizeOf(Single));
- if (DataIn = nil) then
- Exit;
-
- LockSampleBuffer();
- // TODO: We just use the first Frames frames, the others are ignored.
- Frames := Min(FFTSize, SampleBufferCount div AudioFormat.FrameSize);
- // use only first channel and convert data to float-values
- case AudioFormat.Format of
- asfS16:
- begin
- for i := 0 to Frames-1 do
- DataIn[i] := PSmallInt(@SampleBuffer[i*AudioFormat.FrameSize])^ / -Low(SmallInt);
- end;
- asfFloat:
- begin
- for i := 0 to Frames-1 do
- DataIn[i] := PSingle(@SampleBuffer[i*AudioFormat.FrameSize])^;
- end;
- end;
- UnlockSampleBuffer();
-
- WindowFunc(fwfHanning, FFTSize, DataIn);
- PowerSpectrum(FFTSize, DataIn, @Data);
- FreeMem(DataIn);
-
- // resize data to a 0..1 range
- for i := 0 to High(TFFTData) do
- begin
- Data[i] := Sqrt(Data[i]) / 100;
- end;
-end;
-
-procedure TGenericPlaybackStream.AddSoundEffect(Effect: TSoundEffect);
-begin
- if (not assigned(Effect)) then
- Exit;
-
- LockSampleBuffer();
- // check if effect is already in list to avoid duplicates
- if (SoundEffects.IndexOf(Pointer(Effect)) = -1) then
- SoundEffects.Add(Pointer(Effect));
- UnlockSampleBuffer();
-end;
-
-procedure TGenericPlaybackStream.RemoveSoundEffect(Effect: TSoundEffect);
-begin
- LockSampleBuffer();
- SoundEffects.Remove(Effect);
- UnlockSampleBuffer();
-end;
-
-function TGenericPlaybackStream.GetPosition: real;
-var
- BufferedTime: double;
-begin
- if assigned(SourceStream) then
- begin
- LockSampleBuffer();
-
- // calc the time of source data that is buffered (in the SampleBuffer and SourceBuffer)
- // but not yet outputed
- BufferedTime := (SampleBufferCount - SampleBufferPos) / Engine.FormatInfo.BytesPerSec +
- SourceBufferCount / SourceStream.GetAudioFormatInfo().BytesPerSec;
- // and subtract it from the source position
- Result := SourceStream.Position - BufferedTime;
-
- UnlockSampleBuffer();
- end
- else
- begin
- Result := -1;
- end;
-end;
-
-procedure TGenericPlaybackStream.SetPosition(Time: real);
-begin
- if assigned(SourceStream) then
- begin
- LockSampleBuffer();
-
- SourceStream.Position := Time;
- if (Status = ssStopped) then
- NeedsRewind := false;
- // do not use outdated data
- FlushBuffers();
-
- AvgSyncDiff := -1;
-
- UnlockSampleBuffer();
- end;
-end;
-
-function TGenericPlaybackStream.GetVolume(): single;
-var
- FadeAmount: Single;
-begin
- LockSampleBuffer();
- // adjust volume if fading is enabled
- if (FadeInTime > 0) then
- begin
- FadeAmount := (SDL_GetTicks() - FadeInStartTime) / FadeInTime;
- // check if fade-target is reached
- if (FadeAmount >= 1) then
- begin
- // target reached -> stop fading
- FadeInTime := 0;
- fVolume := FadeInTargetVolume;
- end
- else
- begin
- // fading in progress
- fVolume := FadeAmount*FadeInTargetVolume + (1-FadeAmount)*FadeInStartVolume;
- end;
- end;
- // return current volume
- Result := fVolume;
- UnlockSampleBuffer();
-end;
-
-procedure TGenericPlaybackStream.SetVolume(Volume: single);
-begin
- LockSampleBuffer();
- // stop fading
- FadeInTime := 0;
- // clamp volume
- if (Volume > 1.0) then
- fVolume := 1.0
- else if (Volume < 0) then
- fVolume := 0
- else
- fVolume := Volume;
- UnlockSampleBuffer();
-end;
-
-
-{ TGenericVoiceStream }
-
-constructor TGenericVoiceStream.Create(Engine: TAudioPlayback_SoftMixer);
-begin
- inherited Create();
- Self.Engine := Engine;
-end;
-
-function TGenericVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
-var
- BufferSize: integer;
-begin
- Result := false;
-
- Close();
-
- if (not inherited Open(ChannelMap, FormatInfo)) then
- Exit;
-
- // Note:
- // - use Self.FormatInfo instead of FormatInfo as the latter one might have a
- // channel size of 2.
- // - the buffer-size must be a multiple of the FrameSize
- BufferSize := (Ceil(MAX_VOICE_DELAY * Self.FormatInfo.BytesPerSec) div Self.FormatInfo.FrameSize) *
- Self.FormatInfo.FrameSize;
- VoiceBuffer := TRingBuffer.Create(BufferSize);
-
- BufferLock := SDL_CreateMutex();
-
-
- // create a matching playback stream for the voice-stream
- PlaybackStream := TGenericPlaybackStream.Create(Engine);
- // link voice- and playback-stream
- if (not PlaybackStream.Open(Self)) then
- begin
- PlaybackStream.Free;
- Exit;
- end;
-
- // start voice passthrough
- PlaybackStream.Play();
-
- Result := true;
-end;
-
-procedure TGenericVoiceStream.Close();
-begin
- // stop and free the playback stream
- FreeAndNil(PlaybackStream);
-
- // free data
- FreeAndNil(VoiceBuffer);
- if (BufferLock <> nil) then
- SDL_DestroyMutex(BufferLock);
-
- inherited Close();
-end;
-
-procedure TGenericVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
-begin
- // lock access to buffer
- SDL_mutexP(BufferLock);
- try
- if (VoiceBuffer = nil) then
- Exit;
- VoiceBuffer.Write(Buffer, BufferSize);
- finally
- SDL_mutexV(BufferLock);
- end;
-end;
-
-function TGenericVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
-begin
- Result := -1;
-
- // lock access to buffer
- SDL_mutexP(BufferLock);
- try
- if (VoiceBuffer = nil) then
- Exit;
- Result := VoiceBuffer.Read(Buffer, BufferSize);
- finally
- SDL_mutexV(BufferLock);
- end;
-end;
-
-function TGenericVoiceStream.IsEOF(): boolean;
-begin
- SDL_mutexP(BufferLock);
- Result := (VoiceBuffer = nil);
- SDL_mutexV(BufferLock);
-end;
-
-function TGenericVoiceStream.IsError(): boolean;
-begin
- Result := false;
-end;
-
-
-{ TAudioPlayback_SoftMixer }
-
-function TAudioPlayback_SoftMixer.InitializePlayback: boolean;
-begin
- Result := false;
-
- //Log.LogStatus('InitializePlayback', 'UAudioPlayback_SoftMixer');
-
- if(not InitializeAudioPlaybackEngine()) then
- Exit;
-
- MixerStream := TAudioMixerStream.Create(Self);
-
- if(not StartAudioPlaybackEngine()) then
- Exit;
-
- Result := true;
-end;
-
-function TAudioPlayback_SoftMixer.FinalizePlayback: boolean;
-begin
- Close;
- StopAudioPlaybackEngine();
-
- FreeAndNil(MixerStream);
- FreeAndNil(FormatInfo);
-
- FinalizeAudioPlaybackEngine();
- inherited FinalizePlayback;
- Result := true;
-end;
-
-procedure TAudioPlayback_SoftMixer.AudioCallback(Buffer: PChar; Size: integer);
-begin
- MixerStream.ReadData(Buffer, Size);
-end;
-
-function TAudioPlayback_SoftMixer.GetMixer(): TAudioMixerStream;
-begin
- Result := MixerStream;
-end;
-
-function TAudioPlayback_SoftMixer.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- Result := FormatInfo;
-end;
-
-function TAudioPlayback_SoftMixer.CreatePlaybackStream(): TAudioPlaybackStream;
-begin
- Result := TGenericPlaybackStream.Create(Self);
-end;
-
-function TAudioPlayback_SoftMixer.CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
-var
- VoiceStream: TGenericVoiceStream;
-begin
- Result := nil;
-
- // create a voice stream
- VoiceStream := TGenericVoiceStream.Create(Self);
- if (not VoiceStream.Open(ChannelMap, FormatInfo)) then
- begin
- VoiceStream.Free;
- Exit;
- end;
-
- Result := VoiceStream;
-end;
-
-procedure TAudioPlayback_SoftMixer.SetAppVolume(Volume: single);
-begin
- // sets volume only for this application
- MixerStream.Volume := Volume;
-end;
-
-procedure TAudioPlayback_SoftMixer.MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single);
-var
- SampleIndex: Cardinal;
- SampleInt: Integer;
- SampleFlt: Single;
-begin
- SampleIndex := 0;
- case FormatInfo.Format of
- asfS16:
- begin
- while (SampleIndex < Size) do
- begin
- // apply volume and sum with previous mixer value
- SampleInt := PSmallInt(@DstBuffer[SampleIndex])^ +
- Round(PSmallInt(@SrcBuffer[SampleIndex])^ * Volume);
- // clip result
- if (SampleInt > High(SmallInt)) then
- SampleInt := High(SmallInt)
- else if (SampleInt < Low(SmallInt)) then
- SampleInt := Low(SmallInt);
- // assign result
- PSmallInt(@DstBuffer[SampleIndex])^ := SampleInt;
- // increase index by one sample
- Inc(SampleIndex, SizeOf(SmallInt));
- end;
- end;
- asfFloat:
- begin
- while (SampleIndex < Size) do
- begin
- // apply volume and sum with previous mixer value
- SampleFlt := PSingle(@DstBuffer[SampleIndex])^ +
- PSingle(@SrcBuffer[SampleIndex])^ * Volume;
- // clip result
- if (SampleFlt > 1.0) then
- SampleFlt := 1.0
- else if (SampleFlt < -1.0) then
- SampleFlt := -1.0;
- // assign result
- PSingle(@DstBuffer[SampleIndex])^ := SampleFlt;
- // increase index by one sample
- Inc(SampleIndex, SizeOf(Single));
- end;
- end;
- else
- begin
- Log.LogError('Incompatible format', 'TAudioMixerStream.MixAudio');
- end;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UCatCovers.pas b/Game/Code/Classes/UCatCovers.pas
deleted file mode 100644
index d8f6cdb0..00000000
--- a/Game/Code/Classes/UCatCovers.pas
+++ /dev/null
@@ -1,173 +0,0 @@
-unit UCatCovers;
-/////////////////////////////////////////////////////////////////////////
-// UCatCovers by Whiteshark //
-// Class for listing and managing the Category Covers //
-/////////////////////////////////////////////////////////////////////////
-
-interface
-
-{$I switches.inc}
-
-uses UIni;
-
-type
- TCatCovers = class
- protected
- cNames: array [0..high(ISorting)] of array of string;
- cFiles: array [0..high(ISorting)] of array of string;
- public
- constructor Create;
- procedure Load; //Load Cover aus Cover.ini and Cover Folder
- procedure LoadPath(const CoversPath: string);
- procedure Add(Sorting: integer; Name, Filename: string); //Add a Cover
- function CoverExists(Sorting: integer; Name: string): boolean; //Returns True when a cover with the given Name exists
- function GetCover(Sorting: integer; Name: string): string; //Returns the Filename of a Cover
- end;
-
-var
- CatCovers: TCatCovers;
-
-implementation
-
-uses
- IniFiles,
- SysUtils,
- Classes,
- // UFiles,
- UMain,
- ULog;
-
-constructor TCatCovers.Create;
-begin
- inherited;
- Load;
-end;
-
-procedure TCatCovers.Load;
-var
- I: integer;
-begin
- for I := 0 to CoverPaths.Count-1 do
- LoadPath(CoverPaths[I]);
-end;
-
-(**
- * Load Cover from Cover.ini and Cover Folder
- *)
-procedure TCatCovers.LoadPath(const CoversPath: string);
-var
- Ini: TMemIniFile;
- SR: TSearchRec;
- List: TStringlist;
- I, J: Integer;
- Name, Filename, Temp: string;
-begin
- Ini := nil;
- List := nil;
-
- try
- Ini := TMemIniFile.Create(CoversPath + 'covers.ini');
- List := TStringlist.Create;
-
- //Add every Cover in Covers Ini for Every Sorting option
- for I := 0 to High(ISorting) do
- begin
- Ini.ReadSection(ISorting[I], List);
-
- for J := 0 to List.Count - 1 do
- Add(I, List.Strings[J], CoversPath + Ini.ReadString(ISorting[I], List.Strings[J], 'NoCover.jpg'));
- end;
- finally
- Ini.Free;
- List.Free;
- end;
-
- try
- //Add Covers from Folder
- if (FindFirst (CoversPath + '*.jpg', faAnyFile, SR) = 0) then
- repeat
- //Add Cover if it doesn't exist for every Section
- Name := SR.Name;
- Filename := CoversPath + Name;
- Delete (Name, length(Name) - 3, 4);
-
- for I := 0 to high(ISorting) do
- begin
- Temp := Name;
- if ((I = sTitle) or (I = sTitle2)) and (Pos ('Title', Temp) <> 0) then
- Delete (Temp, Pos ('Title', Temp), 5)
- else if (I = sArtist) or (I = sArtist2) and (Pos ('Artist', Temp) <> 0) then
- Delete (Temp, Pos ('Artist', Temp), 6);
-
- if not CoverExists(I, Temp) then
- Add (I, Temp, Filename);
- end;
- until FindNext (SR) <> 0;
- finally
- FindClose (SR);
- end;
-end;
-
- //Add a Cover
-procedure TCatCovers.Add(Sorting: integer; Name, Filename: string);
-begin
- if FileExists (Filename) then //If Exists -> Add
- begin
- SetLength (CNames[Sorting], Length(CNames[Sorting]) + 1);
- SetLength (CFiles[Sorting], Length(CNames[Sorting]) + 1);
-
- CNames[Sorting][high(cNames[Sorting])] := Uppercase(Name);
- CFiles[Sorting][high(cNames[Sorting])] := FileName;
- end;
-end;
-
- //Returns True when a cover with the given Name exists
-function TCatCovers.CoverExists(Sorting: integer; Name: string): boolean;
-var
- I: Integer;
-begin
- Result := False;
- Name := Uppercase(Name); //Case Insensitiv
-
- for I := 0 to high(cNames[Sorting]) do
- begin
- if (cNames[Sorting][I] = Name) then //Found Name
- begin
- Result := true;
- break; //Break For Loop
- end;
- end;
-end;
-
- //Returns the Filename of a Cover
-function TCatCovers.GetCover(Sorting: integer; Name: string): string;
-var
- I: Integer;
-begin
- Result := '';
- Name := Uppercase(Name);
-
- for I := 0 to high(cNames[Sorting]) do
- begin
- if cNames[Sorting][I] = Name then
- begin
- Result := cFiles[Sorting][I];
- Break;
- end;
- end;
-
- //No Cover
- if (Result = '') then
- begin
- for I := 0 to CoverPaths.Count-1 do
- begin
- if (FileExists(CoverPaths[I] + 'NoCover.jpg')) then
- begin
- Result := CoverPaths[I] + 'NoCover.jpg';
- Break;
- end;
- end;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UCommandLine.pas b/Game/Code/Classes/UCommandLine.pas
deleted file mode 100644
index 3c56c606..00000000
--- a/Game/Code/Classes/UCommandLine.pas
+++ /dev/null
@@ -1,339 +0,0 @@
-unit UCommandLine;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-type
- //-----------
- // TCMDParams - Class Reads Infos from ParamStr and set some easy Interface Variables
- //-----------
- TCMDParams = class
- private
- sLanguage: String;
- sResolution: String;
- public
- //Some Boolean Variables Set when Reading Infos
- Debug: Boolean;
- Benchmark: Boolean;
- NoLog: Boolean;
- FullScreen: Boolean;
- Joypad: Boolean;
-
- //Some Value Variables Set when Reading Infos {-1: Not Set, others: Value}
- Depth: Integer;
- Screens: Integer;
-
- //Some Strings Set when Reading Infos {Length=0 Not Set}
- SongPath: String;
- ConfigFile: String;
- ScoreFile: String;
-
- procedure showhelp();
-
- //Pseudo Integer Values
- Function GetLanguage: Integer;
- Property Language: Integer read GetLanguage;
-
- Function GetResolution: Integer;
- Property Resolution: Integer read GetResolution;
-
- //Some Procedures for Reading Infos
- Constructor Create;
-
- Procedure ResetVariables;
- Procedure ReadParamInfo;
- end;
-
-var
- Params: TCMDParams;
-
-const
- cHelp = 'help';
- cDebug = 'debug';
- cMediaInterfaces = 'showinterfaces';
- cUseLocalPaths = 'localpaths';
-
-
-implementation
-
-uses SysUtils,
- uPlatform;
-// uINI -- Nasty requirement... ( removed with permission of blindy )
-
-
-//-------------
-// Constructor - Create class, Reset Variables and Read Infos
-//-------------
-Constructor TCMDParams.Create;
-begin
- inherited;
-
- if FindCmdLineSwitch( cHelp ) or FindCmdLineSwitch( 'h' ) then
- showhelp();
-
- ResetVariables;
- ReadParamInfo;
-end;
-
-procedure TCMDParams.showhelp();
-
- function s( aString : String ) : string;
- begin
- result := aString + StringofChar( ' ', 15 - length( aString ) );
- end;
-
-begin
-
- writeln( '' );
- writeln( '**************************************************************' );
- writeln( ' UltraStar Deluxe - Command line switches ' );
- writeln( '**************************************************************' );
- writeln( '' );
- writeln( ' '+s( 'Switch' ) +' : Purpose' );
- writeln( ' ----------------------------------------------------------' );
- writeln( ' '+s( cMediaInterfaces ) + #9 + ' : Show in-use media interfaces' );
- writeln( ' '+s( cUseLocalPaths ) + #9 + ' : Use relative paths' );
- writeln( ' '+s( cDebug ) + #9 + ' : Display Debugging info' );
-
-
-
- writeln( '' );
-
- platform.halt;
-end;
-
-//-------------
-// ResetVariables - Reset Class Variables
-//-------------
-Procedure TCMDParams.ResetVariables;
-begin
- Debug := False;
- Benchmark := False;
- NoLog := False;
- FullScreen := False;
- Joypad := False;
-
- //Some Value Variables Set when Reading Infos {-1: Not Set, others: Value}
- sResolution := '';
- sLanguage := '';
- Depth := -1;
- Screens := -1;
-
- //Some Strings Set when Reading Infos {Length=0 Not Set}
- SongPath := '';
- ConfigFile := '';
- ScoreFile := '';
-end;
-
-//-------------
-// ReadParamInfo - Read Infos from Parameters
-//-------------
-Procedure TCMDParams.ReadParamInfo;
-var
- I: Integer;
- PCount: Integer;
- Command: String;
-begin
- PCount := ParamCount;
- //Log.LogError('ParamCount: ' + Inttostr(PCount));
-
-
- //Check all Parameters
- For I := 1 to PCount do
- begin
- Command := Paramstr(I);
- //Log.LogError('Start parsing Command: ' + Command);
- //Is String Parameter ?
- if (Length(Command) > 1) AND (Command[1] = '-') then
- begin
- //Remove - from Command
- Command := Lowercase(Trim(Copy(Command, 2, Length(Command) - 1)));
- //Log.LogError('Command prepared: ' + Command);
-
- //Check Command
-
- // Boolean Triggers:
- if (Command = 'debug') then
- Debug := True
- else if (Command = 'benchmark') then
- Benchmark := True
- else if (Command = 'nolog') then
- NoLog := True
- else if (Command = 'fullscreen') then
- Fullscreen := True
- else if (Command = 'window') then
- Fullscreen := False
- else if (Command = 'joypad') then
- Joypad := True
-
- //Integer Variables
- else if (Command = 'depth') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- Command := ParamStr(I + 1);
-
- //Check for valid Value
- If (Command = '16') then
- Depth := 0
- Else If (Command = '32') then
- Depth := 1;
- end;
- end
-
- else if (Command = 'screens') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- Command := ParamStr(I + 1);
-
- //Check for valid Value
- If (Command = '1') then
- Screens := 0
- Else If (Command = '2') then
- Screens := 1;
- end;
- end
-
- //Pseudo Integer Values
- else if (Command = 'language') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- //Write Value to String
- sLanguage := Lowercase(ParamStr(I + 1));
- end;
- end
-
- else if (Command = 'resolution') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- //Write Value to String
- sResolution := Lowercase(ParamStr(I + 1));
- end;
- end
-
- //String Values
- else if (Command = 'songpath') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- //Write Value to String
- SongPath := ParamStr(I + 1);
- end;
- end
-
- else if (Command = 'configfile') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- //Write Value to String
- ConfigFile := ParamStr(I + 1);
-
- //is this a relative PAth -> then add Gamepath
- if Not ((Length(ConfigFile) > 2) AND (ConfigFile[2] = ':')) then
- ConfigFile := ExtractFilePath(ParamStr(0)) + Configfile;
- end;
- end
-
- else if (Command = 'scorefile') then
- begin
- //Check if there is another Parameter to get the Value from
- if (PCount > I) then
- begin
- //Write Value to String
- ScoreFile := ParamStr(I + 1);
- end;
- end;
-
- end;
-
- end;
-
-{ Log.LogError('Values: ');
-
- if Debug then
- Log.LogError('Debug');
-
- if Benchmark then
- Log.LogError('Benchmark');
-
- if NoLog then
- Log.LogError('NoLog');
-
- if Fullscreen then
- Log.LogError('FullScreen');
-
- if JoyStick then
- Log.LogError('Joystick');
-
-
- Log.LogError('Screens: ' + Inttostr(Screens));
- Log.LogError('Depth: ' + Inttostr(Depth));
-
- Log.LogError('Resolution: ' + Inttostr(Resolution));
- Log.LogError('Resolution: ' + Inttostr(Language));
-
- Log.LogError('sResolution: ' + sResolution);
- Log.LogError('sLanguage: ' + sLanguage);
-
- Log.LogError('ConfigFile: ' + ConfigFile);
- Log.LogError('SongPath: ' + SongPath);
- Log.LogError('ScoreFile: ' + ScoreFile); }
-
-end;
-
-//-------------
-// GetLanguage - Get Language ID from saved String Information
-//-------------
-Function TCMDParams.GetLanguage: Integer;
-var
- I: integer;
-begin
- Result := -1;
-{* JB - 12sep07 to remove uINI dependency
-
- //Search for Language
- For I := 0 to high(ILanguage) do
- if (LowerCase(ILanguage[I]) = sLanguage) then
- begin
- Result := I;
- Break;
- end;
-*}
-end;
-
-//-------------
-// GetResolution - Get Resolution ID from saved String Information
-//-------------
-Function TCMDParams.GetResolution: Integer;
-var
- I: integer;
-begin
- Result := -1;
-{* JB - 12sep07 to remove uINI dependency
-
- //Search for Resolution
- For I := 0 to high(IResolution) do
- if (LowerCase(IResolution[I]) = sResolution) then
- begin
- Result := I;
- Break;
- end;
-*}
-end;
-
-end.
diff --git a/Game/Code/Classes/UCommon.pas b/Game/Code/Classes/UCommon.pas
deleted file mode 100644
index 41e3c1f1..00000000
--- a/Game/Code/Classes/UCommon.pas
+++ /dev/null
@@ -1,774 +0,0 @@
-unit UCommon;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SysUtils,
- Classes,
- {$IFDEF MSWINDOWS}
- Windows,
- {$ENDIF}
- sdl,
- UConfig,
- ULog;
-
-type
- TMessageType = ( mtInfo, mtError );
-
-procedure ShowMessage( const msg : String; msgType: TMessageType = mtInfo );
-
-procedure ConsoleWriteLn(const msg: string);
-
-function GetResourceStream(const aName, aType : string): TStream;
-function RWopsFromStream(Stream: TStream): PSDL_RWops;
-
-{$IFDEF FPC}
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-{$ENDIF}
-
-function StringReplaceW(text : WideString; search, rep: WideChar):WideString;
-function AdaptFilePaths( const aPath : widestring ): widestring;
-
-procedure DisableFloatingPointExceptions();
-procedure SetDefaultNumericLocale();
-procedure RestoreNumericLocale();
-
-{$IFNDEF MSWINDOWS}
- procedure ZeroMemory( Destination: Pointer; Length: DWORD );
- function MakeLong(a, b: Word): Longint;
- (*
- #define LOBYTE(a) (BYTE)(a)
- #define HIBYTE(a) (BYTE)((a)>>8)
- #define LOWORD(a) (WORD)(a)
- #define HIWORD(a) (WORD)((a)>>16)
- #define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8))
- *)
-{$ENDIF}
-
-function FileExistsInsensitive(var FileName: string): boolean;
-
-(*
- * 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;
-
-// A stable alternative to TList.Sort() (use TList.Sort() if applicable, see below)
-procedure MergeSort(List: TList; CompareFunc: TListSortCompare);
-
-function GetAlignedMem(Size: cardinal; Alignment: integer): Pointer;
-procedure FreeAlignedMem(P: Pointer);
-
-
-implementation
-
-uses
- Math,
- {$IFDEF Delphi}
- Dialogs,
- {$ENDIF}
- UMain;
-
-
-// data used by the ...Locale() functions
-{$IFDEF LINUX}
-
-var
- PrevNumLocale: string;
-
-const
- LC_NUMERIC = 1;
-
-function setlocale(category: integer; locale: pchar): pchar; cdecl; external 'c' name 'setlocale';
-
-{$ENDIF}
-
-// In Linux and maybe MacOSX some units (like cwstring) call setlocale(LC_ALL, '')
-// to set the language/country specific locale (e.g. charset) for this application.
-// Unfortunately, LC_NUMERIC is set by this call too.
-// It defines the decimal-separator and other country-specific numeric settings.
-// This parameter is used by the C string-to-float parsing functions atof() and strtod().
-// After changing LC_NUMERIC some external C-based libs (like projectM) are not
-// able to parse strings correctly
-// (e.g. in Germany "0.9" is not recognized as a valid number anymore but "0,9" is).
-// So we reset the numeric settings to the default ('C').
-// Note: The behaviour of Pascal parsing functions (e.g. strtofloat()) is not
-// changed by this because it doesn't use the locale-settings.
-// TODO:
-// - Check if this is needed in MacOSX (at least the locale is set in cwstring)
-// - Find out which libs are concerned by this problem.
-// If only projectM is concerned by this problem set and restore the numeric locale
-// for each call to projectM instead of changing it globally.
-procedure SetDefaultNumericLocale();
-begin
- {$ifdef LINUX}
- PrevNumLocale := setlocale(LC_NUMERIC, nil);
- setlocale(LC_NUMERIC, 'C');
- {$endif}
-end;
-
-procedure RestoreNumericLocale();
-begin
- {$ifdef LINUX}
- setlocale(LC_NUMERIC, PChar(PrevNumLocale));
- {$endif}
-end;
-
-(*
- * If an invalid floating point operation was performed the Floating-point unit (FPU)
- * generates a Floating-point exception (FPE). Dependending on the settings in
- * the FPU's control-register (interrupt mask) the FPE is handled by the FPU itself
- * (we will call this as "FPE disabled" later on) or is passed to the application
- * (FPE enabled).
- * If FPEs are enabled a floating-point division by zero (e.g. 10.0 / 0.0) is
- * considered an error and an exception is thrown. Otherwise the FPU will handle
- * the error and return the result infinity (INF) (10.0 / 0.0 = INF) without
- * throwing an error to the application.
- * The same applies to a division by INF that either raises an exception
- * (FPE enabled) or returns 0.0 (FPE disabled).
- * Normally (as with C-programs), Floating-point exceptions (FPE) are DISABLED
- * on program startup (at least with Intel CPUs), but for some strange reasons
- * they are ENABLED in pascal (both delphi and FPC) by default.
- * Many libs operating with floating-point values rely heavily on the C-specific
- * behaviour. So using them in delphi is a ticking time-bomb because sooner or
- * later they will crash because of an FPE (this problem occurs massively
- * in OpenGL-based libs like projectM). In contrast to this no error will occur
- * if the lib is linked to a C-program.
- *
- * Further info on FPUs:
- * For x86 and x86_64 CPUs we have to consider two FPU instruction sets.
- * The math co-processor i387 (aka 8087 or x87) set introduced with the i386
- * and SSE (Streaming SIMD Extensions) introduced with the Pentium3.
- * Both of them have separate control-registers (x87: FPUControlWord, SSE: MXCSR)
- * to control FPEs. Either has (among others) 6bits to enable/disable several
- * exception types (Invalid,Denormalized,Zero,Overflow,Underflow,Precision).
- * Those exception-types must all be masked (=1) to get the default C behaviour.
- * The control-registers can be set with the asm-ops FLDCW (x87) and LDMXCSR (SSE).
- * Instead of using assembler code, we can use Set8087CW() provided by delphi and
- * FPC to set the x87 control-word. FPC also provides SetSSECSR() for SSE's MXCSR.
- * Note that both Delphi and FPC enable FPEs (e.g. for div-by-zero) on program
- * startup but only FPC enables FPEs (especially div-by-zero) for SSE too.
- * So we have to mask FPEs for x87 in Delphi and FPC and for SSE in FPC only.
- * FPC and Delphi both provide a SetExceptionMask() for control of the FPE
- * mask. SetExceptionMask() sets the masks for x87 in Delphi and for x87 and SSE
- * in FPC (seems as if Delphi [2005] is not SSE aware). So SetExceptionMask()
- * is what we need and it even is plattform and CPU independent.
- *
- * Pascal OpenGL headers (like the Delphi standard ones or JEDI-SDL headers)
- * already call Set8087CW() to disable FPEs but due to some bugs in the JEDI-SDL
- * headers they do not work properly with FPC. I already patched them, so they
- * work at least until they are updated the next time. In addition Set8086CW()
- * does not suffice to disable FPEs because the SSE FPEs are not disabled by this.
- * FPEs with SSE are a big problem with some libs because many linux distributions
- * optimize code for SSE or Pentium3 (for example: int(INF) which convert the
- * double value "infinity" to an integer might be automatically optimized by
- * using SSE's CVTSD2SI instruction). So SSE FPEs must be turned off in any case
- * to make USDX portable.
- *
- * Summary:
- * Call this function on initialization to make sure FPEs are turned off.
- * It will solve a lot of errors with FPEs in external libs.
- *)
-procedure DisableFloatingPointExceptions();
-begin
- (*
- // We will use SetExceptionMask() instead of Set8087CW()/SetSSECSR().
- // Note: Leave these lines for documentation purposes just in case
- // SetExceptionMask() does not work anymore (due to bugs in FPC etc.).
- {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
- Set8087CW($133F);
- {$IFEND}
- {$IF Defined(FPC)}
- if (has_sse_support) then
- SetSSECSR($1F80);
- {$IFEND}
- *)
-
- // disable all of the six FPEs (x87 and SSE) to be compatible with C/C++ and
- // other libs which rely on the standard FPU behaviour (no div-by-zero FPE anymore).
- SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,
- exOverflow, exUnderflow, exPrecision]);
-end;
-
-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 := 1 to length(result) 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 MSWINDOWS}
-procedure ZeroMemory( Destination: Pointer; Length: DWORD );
-begin
- FillChar( Destination^, Length, 0 );
-end;
-
-function MakeLong(A, B: Word): Longint;
-begin
- Result := (LongInt(B) shl 16) + A;
-end;
-
-(*
-function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
-
- // From http://en.wikipedia.org/wiki/RDTSC
- function RDTSC: Int64; register;
- asm
- rdtsc
- end;
-
-begin
- // Use clock_gettime(CLOCK_REALTIME, ...) here (but not from the libc unit)
- lpPerformanceCount := RDTSC();
- result := true;
-end;
-
-function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
-begin
- // clock_getres(CLOCK_REALTIME, ...)
- lpFrequency := 0;
- result := true;
-end;
-*)
-{$ENDIF}
-
-// Checks if a regular files or directory with the given name exists.
-// The comparison is case insensitive.
-function FileExistsInsensitive(var FileName: string): boolean;
-var
- FilePath, LocalFileName: string;
- SearchInfo: TSearchRec;
-begin
-{$IFDEF LINUX} // eddie: Changed FPC to LINUX: Windows and Mac OS X dont have case sensitive file systems
- // speed up standard case
- if FileExists(FileName) then
- begin
- Result := true;
- exit;
- end;
-
- Result := false;
-
- FilePath := ExtractFilePath(FileName);
- if (FindFirst(FilePath+'*', faAnyFile, SearchInfo) = 0) then
- begin
- LocalFileName := ExtractFileName(FileName);
- repeat
- if (AnsiSameText(LocalFileName, SearchInfo.Name)) then
- begin
- FileName := FilePath + SearchInfo.Name;
- Result := true;
- break;
- end;
- until (FindNext(SearchInfo) <> 0);
- end;
- FindClose(SearchInfo);
-{$ELSE}
- Result := FileExists(FileName);
-{$ENDIF}
-end;
-
-
-{$IFDEF Unix}
- // include resource-file info (stored in the constant array "resources")
- {$I ../resource.inc}
-{$ENDIF}
-
-function GetResourceStream(const aName, aType: string): TStream;
-{$IFDEF Unix}
-var
- ResIndex: integer;
- Filename: string;
-{$ENDIF}
-begin
- Result := nil;
-
- {$IFDEF Unix}
- for ResIndex := 0 to High(resources) do
- begin
- if (resources[ResIndex][0] = aName ) and
- (resources[ResIndex][1] = aType ) then
- begin
- try
- Filename := ResourcesPath + resources[ResIndex][2];
- Result := TFileStream.Create(Filename, fmOpenRead);
- except
- Log.LogError('Failed to open: "'+ resources[ResIndex][2] +'"', 'GetResourceStream');
- end;
- exit;
- end;
- end;
- {$ELSE}
- try
- Result := TResourceStream.Create(HInstance, aName , PChar(aType));
- except
- Log.LogError('Invalid resource: "'+ aType + ':' + aName +'"', 'GetResourceStream');
- end;
- {$ENDIF}
-end;
-
-// +++++++++++++++++++++ helpers for RWOpsFromStream() +++++++++++++++
- function SdlStreamSeek( context : PSDL_RWops; offset : Integer; whence : Integer ) : integer; cdecl;
- var
- stream : TStream;
- origin : Word;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamSeek on nil' );
- case whence of
- 0 : origin := soFromBeginning; // Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
- 1 : origin := soFromCurrent; // Offset is from the current position in the resource. Seek moves to Position + Offset.
- 2 : origin := soFromEnd;
- else
- origin := soFromBeginning; // just in case
- end;
- Result := stream.Seek( offset, origin );
- end;
-
- function SdlStreamRead( context : PSDL_RWops; Ptr : Pointer; size : Integer; maxnum: Integer ) : Integer; cdecl;
- var
- stream : TStream;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamRead on nil' );
- try
- Result := stream.read( Ptr^, Size * maxnum ) div size;
- except
- Result := -1;
- end;
- end;
-
- function SDLStreamClose( context : PSDL_RWops ) : Integer; cdecl;
- var
- stream : TStream;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamClose on nil' );
- stream.Free;
- Result := 1;
- end;
-// -----------------------------------------------
-
-(*
- * Creates an SDL_RWops handle from a TStream.
- * The stream and RWops must be freed by the user after usage.
- * Use SDL_FreeRW(...) to free the RWops data-struct.
- *)
-function RWopsFromStream(Stream: TStream): PSDL_RWops;
-begin
- Result := SDL_AllocRW();
- if (Result = nil) then
- Exit;
-
- // set RW-callbacks
- with Result^ do
- begin
- unknown := TUnknown(Stream);
- seek := SDLStreamSeek;
- read := SDLStreamRead;
- write := nil;
- close := SDLStreamClose;
- type_ := 2;
- end;
-end;
-
-
-
-{$IFDEF FPC}
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-begin
- RandomRange := Random(aMax-aMin) + aMin ;
-end;
-{$ENDIF}
-
-
-{$IFDEF FPC}
-var
- MessageList: TStringList;
- ConsoleHandler: TThreadID;
- // Note: TRTLCriticalSection is defined in the units System and Libc, use System one
- ConsoleCriticalSection: System.TRTLCriticalSection;
- ConsoleEvent: PRTLEvent;
- ConsoleQuit: boolean;
-{$ENDIF}
-
-(*
- * Write to console if one is available.
- * It checks if a console is available before output so it will not
- * crash on windows if none is available.
- * Do not use this function directly because it is not thread-safe,
- * use ConsoleWriteLn() instead.
- *)
-procedure _ConsoleWriteLn(const aString: string); {$IFDEF HasInline}inline;{$ENDIF}
-begin
- {$IFDEF MSWINDOWS}
- // sanity check to avoid crashes with writeln()
- if (IsConsole) then
- begin
- {$ENDIF}
- Writeln(aString);
- {$IFDEF MSWINDOWS}
- end;
- {$ENDIF}
-end;
-
-{$IFDEF FPC}
-{*
- * The console-handlers main-function.
- * TODO: create a quit-event on closing.
- *}
-function ConsoleHandlerFunc(param: pointer): PtrInt;
-var
- i: integer;
- quit: boolean;
-begin
- quit := false;
- while (not quit) do
- begin
- // wait for new output or quit-request
- RTLeventWaitFor(ConsoleEvent);
-
- System.EnterCriticalSection(ConsoleCriticalSection);
- // output pending messages
- for i := 0 to MessageList.Count-1 do
- begin
- _ConsoleWriteLn(MessageList[i]);
- end;
- MessageList.Clear();
-
- // use local quit-variable to avoid accessing
- // ConsoleQuit outside of the critical section
- if (ConsoleQuit) then
- quit := true;
-
- RTLeventResetEvent(ConsoleEvent);
- System.LeaveCriticalSection(ConsoleCriticalSection);
- end;
- result := 0;
-end;
-{$ENDIF}
-
-procedure InitConsoleOutput();
-begin
- {$IFDEF FPC}
- // init thread-safe output
- MessageList := TStringList.Create();
- System.InitCriticalSection(ConsoleCriticalSection);
- ConsoleEvent := RTLEventCreate();
- ConsoleQuit := false;
- // must be a thread managed by FPC. Otherwise (e.g. SDL-thread)
- // it will crash when using Writeln.
- ConsoleHandler := BeginThread(@ConsoleHandlerFunc);
- {$ENDIF}
-end;
-
-procedure FinalizeConsoleOutput();
-begin
- {$IFDEF FPC}
- // terminate console-handler
- System.EnterCriticalSection(ConsoleCriticalSection);
- ConsoleQuit := true;
- RTLeventSetEvent(ConsoleEvent);
- System.LeaveCriticalSection(ConsoleCriticalSection);
- WaitForThreadTerminate(ConsoleHandler, 0);
- // free data
- System.DoneCriticalsection(ConsoleCriticalSection);
- RTLeventDestroy(ConsoleEvent);
- MessageList.Free();
- {$ENDIF}
-end;
-
-{*
- * With FPC console output is not thread-safe.
- * Using WriteLn() from external threads (like in SDL callbacks)
- * will damage the heap and crash the program.
- * Most probably FPC uses thread-local-data (TLS) to lock a mutex on
- * the console-buffer. This does not work with external lib's threads
- * because these do not have the TLS data and so it crashes while
- * accessing unallocated memory.
- * The solution is to create an FPC-managed thread which has the TLS data
- * and use it to handle the console-output (hence it is called Console-Handler)
- * It should be safe to do so, but maybe FPC requires the main-thread to access
- * the console-buffer only. In this case output should be delegated to it.
- *
- * TODO: - check if it is safe if an FPC-managed thread different than the
- * main-thread accesses the console-buffer in FPC.
- * - check if Delphi's WriteLn is thread-safe.
- * - check if we need to synchronize file-output too
- *}
-procedure ConsoleWriteLn(const msg: string);
-begin
-{$IFDEF CONSOLE}
- {$IFDEF FPC}
- // TODO: check for the main-thread and use a simple _ConsoleWriteLn() then?
- //GetCurrentThreadThreadId();
- System.EnterCriticalSection(ConsoleCriticalSection);
- MessageList.Add(msg);
- RTLeventSetEvent(ConsoleEvent);
- System.LeaveCriticalSection(ConsoleCriticalSection);
- {$ELSE}
- _ConsoleWriteLn(msg);
- {$ENDIF}
-{$ENDIF}
-end;
-
-procedure ShowMessage(const msg: String; msgType: TMessageType);
-{$IFDEF MSWINDOWS}
-var Flags: Cardinal;
-{$ENDIF}
-begin
-{$IF Defined(MSWINDOWS)}
- case msgType of
- mtInfo: Flags := MB_ICONINFORMATION or MB_OK;
- mtError: Flags := MB_ICONERROR or MB_OK;
- else Flags := MB_OK;
- end;
- MessageBox(0, PChar(msg), PChar(USDXVersionStr()), Flags);
-{$ELSE}
- ConsoleWriteln(msg);
-{$IFEND}
-end;
-
-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;
-
-(*
- * Recursive part of the MergeSort algorithm.
- * OutList will be either InList or TempList and will be swapped in each
- * depth-level of recursion. By doing this it we can directly merge into the
- * output-list. If we only had In- and OutList parameters we had to merge into
- * InList after the recursive calls and copy the data to the OutList afterwards.
- *)
-procedure _MergeSort(InList, TempList, OutList: TList; StartPos, BlockSize: integer;
- CompareFunc: TListSortCompare);
-var
- LeftSize, RightSize: integer; // number of elements in left/right block
- LeftEnd, RightEnd: integer; // Index after last element in left/right block
- MidPos: integer; // index of first element in right block
- Pos: integer; // position in output list
-begin
- LeftSize := BlockSize div 2;
- RightSize := BlockSize - LeftSize;
- MidPos := StartPos + LeftSize;
-
- // sort left and right halves of this block by recursive calls of this function
- if (LeftSize >= 2) then
- _MergeSort(InList, OutList, TempList, StartPos, LeftSize, CompareFunc)
- else
- TempList[StartPos] := InList[StartPos];
- if (RightSize >= 2) then
- _MergeSort(InList, OutList, TempList, MidPos, RightSize, CompareFunc)
- else
- TempList[MidPos] := InList[MidPos];
-
- // merge sorted left and right sub-lists into output-list
- LeftEnd := MidPos;
- RightEnd := StartPos + BlockSize;
- Pos := StartPos;
- while ((StartPos < LeftEnd) and (MidPos < RightEnd)) do
- begin
- if (CompareFunc(TempList[StartPos], TempList[MidPos]) <= 0) then
- begin
- OutList[Pos] := TempList[StartPos];
- Inc(StartPos);
- end
- else
- begin
- OutList[Pos] := TempList[MidPos];
- Inc(MidPos);
- end;
- Inc(Pos);
- end;
-
- // copy remaining elements to output-list
- while (StartPos < LeftEnd) do
- begin
- OutList[Pos] := TempList[StartPos];
- Inc(StartPos);
- Inc(Pos);
- end;
- while (MidPos < RightEnd) do
- begin
- OutList[Pos] := TempList[MidPos];
- Inc(MidPos);
- Inc(Pos);
- end;
-end;
-
-(*
- * Stable alternative to the instable TList.Sort() (uses QuickSort) implementation.
- * A stable sorting algorithm preserves preordered items. E.g. if sorting by
- * songs by title first and artist afterwards, the songs of each artist will
- * be ordered by title. In contrast to this an unstable algorithm (like QuickSort)
- * may destroy an existing order, so the songs of an artist will not be ordered
- * by title anymore after sorting by artist in the previous example.
- * If you do not need a stable algorithm, use TList.Sort() instead.
- *)
-procedure MergeSort(List: TList; CompareFunc: TListSortCompare);
-var
- TempList: TList;
-begin
- TempList := TList.Create();
- TempList.Count := List.Count;
- if (List.Count >= 2) then
- _MergeSort(List, TempList, List, 0, List.Count, CompareFunc);
- TempList.Free;
-end;
-
-
-type
- // stores the unaligned pointer of data allocated by GetAlignedMem()
- PMemAlignHeader = ^TMemAlignHeader;
- TMemAlignHeader = Pointer;
-
-(**
- * Use this function to assure that allocated memory is aligned on a specific
- * byte boundary.
- * Alignment must be a power of 2.
- *
- * Important: Memory allocated with GetAlignedMem() MUST be freed with
- * FreeAlignedMem(), FreeMem() will cause a segmentation fault.
- *
- * Hint: If you do not need dynamic memory, consider to allocate memory
- * statically and use the {$ALIGN x} compiler directive. Note that delphi
- * supports an alignment "x" of up to 8 bytes only whereas FPC supports
- * alignments on 16 and 32 byte boundaries too.
- *)
-{$WARNINGS OFF}
-function GetAlignedMem(Size: cardinal; Alignment: integer): Pointer;
-var
- OrigPtr: Pointer;
-const
- MIN_ALIGNMENT = 16;
-begin
- // Delphi and FPC (tested with 2.2.0) align memory blocks allocated with
- // GetMem() at least on 8 byte boundaries. Delphi uses a minimal alignment
- // of either 8 or 16 bytes depending on the size of the requested block
- // (see System.GetMinimumBlockAlignment). As we do not want to change the
- // boundary for the worse, we align at least on MIN_ALIGN.
- if (Alignment < MIN_ALIGNMENT) then
- Alignment := MIN_ALIGNMENT;
-
- // allocate unaligned memory
- GetMem(OrigPtr, SizeOf(TMemAlignHeader) + Size + Alignment);
- if (OrigPtr = nil) then
- begin
- Result := nil;
- Exit;
- end;
-
- // reserve space for the header
- Result := Pointer(PtrUInt(OrigPtr) + SizeOf(TMemAlignHeader));
- // align memory
- Result := Pointer(PtrUInt(Result) + Alignment - PtrUInt(Result) mod Alignment);
-
- // set header with info on old pointer for FreeMem
- PMemAlignHeader(PtrUInt(Result) - SizeOf(TMemAlignHeader))^ := OrigPtr;
-end;
-{$WARNINGS ON}
-
-{$WARNINGS OFF}
-procedure FreeAlignedMem(P: Pointer);
-begin
- if (P <> nil) then
- FreeMem(PMemAlignHeader(PtrUInt(P) - SizeOf(TMemAlignHeader))^);
-end;
-{$WARNINGS ON}
-
-
-initialization
- InitConsoleOutput();
-
-finalization
- FinalizeConsoleOutput();
-
-end.
diff --git a/Game/Code/Classes/UConfig.pas b/Game/Code/Classes/UConfig.pas
deleted file mode 100644
index b77c2a5a..00000000
--- a/Game/Code/Classes/UConfig.pas
+++ /dev/null
@@ -1,199 +0,0 @@
-unit UConfig;
-
-// -------------------------------------------------------------------
-// Note on version comparison (for developers only):
-// -------------------------------------------------------------------
-// Delphi (in contrast to FPC) DOESN'T support MACROS. So we
-// can't define a macro like VERSION_MAJOR(version) to extract
-// parts of the version-number or to create version numbers for
-// comparison purposes as with a MAKE_VERSION(maj, min, rev) macro.
-// So we have to define constants for every part of the version here.
-//
-// In addition FPC (in contrast to delphi) DOES NOT support floating-
-// point numbers in $IF compiler-directives (e.g. {$IF VERSION > 1.23})
-// It also DOESN'T support arithmetic operations so we aren't able to
-// compare versions this way (brackets aren't supported too):
-// {$IF VERSION > ((VER_MAJ*2)+(VER_MIN*23)+(VER_REL*1))}
-//
-// Hence we have to use fixed numbers in the directives. At least
-// Pascal allows leading 0s so 0005 equals 5 (octals are
-// preceded by & and not by 0 in FPC).
-// We also fix the count of digits for each part of the version number
-// to 3 (aaaiiirrr with aaa=major, iii=minor, rrr=release version)
-//
-// A check for a library with at least a version of 2.5.11 would look
-// like this:
-// {$IF LIB_VERSION >= 002005011}
-//
-// If you just need to check the major version do this:
-// {$IF LIB_VERSION_MAJOR >= 23}
-//
-// IMPORTANT:
-// Because this unit must be included in a uses-section it is
-// not possible to use the version-numbers in this uses-clause.
-// Example:
-// interface
-// uses
-// versions, // include this file
-// {$IF USE_UNIT_XYZ}xyz;{$IFEND} // Error: USE_UNIT_XYZ not defined
-// const
-// {$IF USE_UNIT_XYZ}test = 2;{$IFEND} // OK
-// uses
-// {$IF USE_UNIT_XYZ}xyz;{$IFEND} // OK
-//
-// Even if this file was an include-file no constants could be declared
-// before the interface's uses clause.
-// In FPC macros {$DEFINE VER:= 3} could be used to declare the version-numbers
-// but this is incompatible to Delphi. In addition macros do not allow expand
-// arithmetic expressions. Although you can define
-// {$DEFINE FPC_VER:= FPC_VERSION*1000000+FPC_RELEASE*1000+FPC_PATCH}
-// the following check would fail:
-// {$IF FPC_VERSION_INT >= 002002000}
-// would fail because FPC_VERSION_INT is interpreted as a string.
-//
-// PLEASE consider this if you use version numbers in $IF compiler-
-// directives. Otherwise you might break portability.
-// -------------------------------------------------------------------
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
- {$MACRO ON} // for evaluation of FPC_VERSION/RELEASE/PATCH
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Sysutils;
-
-const
- // IMPORTANT:
- // If IncludeConstants is defined, the const-sections
- // of the config-file will be included too.
- // This switch is necessary because it is not possible to
- // include the const-sections in the switches.inc.
- // switches.inc is always included before the first uses-
- // section but at that place no const-section is allowed.
- // So we have to include the config-file in switches.inc
- // with IncludeConstants undefined and in UConfig.pas with
- // IncludeConstants defined (see the note above).
- {$DEFINE IncludeConstants}
-
- // include config-file (defines + constants)
- {$IF Defined(MSWindows)}
- {$I ../config-win.inc}
- {$ELSEIF Defined(Linux)}
- {$I ../config-linux.inc}
- {$ELSEIF Defined(Darwin)}
- {$I ../config-darwin.inc}
- {$ELSE}
- {$MESSAGE Fatal 'Unknown OS'}
- {$IFEND}
-
-{* Libraries *}
-
- VERSION_MAJOR = 1000000;
- VERSION_MINOR = 1000;
- VERSION_RELEASE = 1;
-
- (*
- * Current version of UltraStar Deluxe
- *)
- USDX_VERSION_MAJOR = 1;
- USDX_VERSION_MINOR = 1;
- USDX_VERSION_RELEASE = 0;
- USDX_VERSION_STATE = 'Alpha';
- USDX_STRING = 'UltraStar Deluxe';
-
- (*
- * FPC version numbers are already defined as built-in macros:
- * FPC_VERSION (MAJOR)
- * FPC_RELEASE (MINOR)
- * FPC_PATCH (RELEASE)
- * Since FPC_VERSION is already defined, we will use FPC_VERSION_INT as
- * composed version number.
- *)
- {$IFNDEF FPC}
- // Delphi 7 evaluates every $IF-directive even if it is disabled by a surrounding
- // $IF or $IFDEF so the follwing will give you an error in delphi:
- // {$IFDEF FPC}{$IF (FPC_VERSION > 2)}...{$IFEND}{$ENDIF}
- // The reason for this error is that FPC_VERSION is not a valid constant.
- // To avoid this error, we define dummys here.
- FPC_VERSION = 0;
- FPC_RELEASE = 0;
- FPC_PATCH = 0;
- {$ENDIF}
-
- FPC_VERSION_INT = (FPC_VERSION * VERSION_MAJOR) +
- (FPC_RELEASE * VERSION_MINOR) +
- (FPC_PATCH * VERSION_RELEASE);
-
-
- {$IFDEF HaveFFmpeg}
-
- LIBAVCODEC_VERSION = (LIBAVCODEC_VERSION_MAJOR * VERSION_MAJOR) +
- (LIBAVCODEC_VERSION_MINOR * VERSION_MINOR) +
- (LIBAVCODEC_VERSION_RELEASE * VERSION_RELEASE);
-
- LIBAVFORMAT_VERSION = (LIBAVFORMAT_VERSION_MAJOR * VERSION_MAJOR) +
- (LIBAVFORMAT_VERSION_MINOR * VERSION_MINOR) +
- (LIBAVFORMAT_VERSION_RELEASE * VERSION_RELEASE);
-
- LIBAVUTIL_VERSION = (LIBAVUTIL_VERSION_MAJOR * VERSION_MAJOR) +
- (LIBAVUTIL_VERSION_MINOR * VERSION_MINOR) +
- (LIBAVUTIL_VERSION_RELEASE * VERSION_RELEASE);
-
- {$IFDEF HaveSWScale}
- LIBSWSCALE_VERSION = (LIBSWSCALE_VERSION_MAJOR * VERSION_MAJOR) +
- (LIBSWSCALE_VERSION_MINOR * VERSION_MINOR) +
- (LIBSWSCALE_VERSION_RELEASE * VERSION_RELEASE);
- {$ENDIF}
-
- {$ENDIF}
-
- {$IFDEF HaveProjectM}
- PROJECTM_VERSION = (PROJECTM_VERSION_MAJOR * VERSION_MAJOR) +
- (PROJECTM_VERSION_MINOR * VERSION_MINOR) +
- (PROJECTM_VERSION_RELEASE * VERSION_RELEASE);
- {$ENDIF}
-
- {$IFDEF HavePortaudio}
- PORTAUDIO_VERSION = (PORTAUDIO_VERSION_MAJOR * VERSION_MAJOR) +
- (PORTAUDIO_VERSION_MINOR * VERSION_MINOR) +
- (PORTAUDIO_VERSION_RELEASE * VERSION_RELEASE);
- {$ENDIF}
-
- {$IFDEF HaveLibsamplerate}
- LIBSAMPLERATE_VERSION = (LIBSAMPLERATE_VERSION_MAJOR * VERSION_MAJOR) +
- (LIBSAMPLERATE_VERSION_MINOR * VERSION_MINOR) +
- (LIBSAMPLERATE_VERSION_RELEASE * VERSION_RELEASE);
- {$ENDIF}
-
-function USDXVersionStr(): string;
-function USDXShortVersionStr(): string;
-
-implementation
-
-uses
- StrUtils, Math;
-
-function USDXShortVersionStr(): string;
-begin
- Result :=
- USDX_STRING +
- IfThen(USDX_VERSION_STATE <> '', ' '+USDX_VERSION_STATE);
-end;
-
-function USDXVersionStr(): string;
-begin
- Result :=
- USDX_STRING + ' V ' +
- IntToStr(USDX_VERSION_MAJOR) + '.' +
- IntToStr(USDX_VERSION_MINOR) + '.' +
- IntToStr(USDX_VERSION_RELEASE) +
- IfThen(USDX_VERSION_STATE <> '', ' '+USDX_VERSION_STATE) +
- ' Build';
-end;
-
-end.
diff --git a/Game/Code/Classes/UCore.pas b/Game/Code/Classes/UCore.pas
deleted file mode 100644
index fe23a68e..00000000
--- a/Game/Code/Classes/UCore.pas
+++ /dev/null
@@ -1,525 +0,0 @@
-unit UCore;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- uPluginDefs,
- uCoreModule,
- UHooks,
- UServices,
- UModules;
-
-{*********************
- TCore
- Class manages all CoreModules, teh StartUp, teh MainLoop and the shutdown process
- Also it does some Error Handling, and maybe sometime multithreaded Loading ;)
-*********************}
-
-type
- TModuleListItem = record
- Module: TCoreModule; //Instance of the Modules Class
- Info: TModuleInfo; //ModuleInfo returned by Modules Modulinfo Proc
- NeedsDeInit: Boolean; //True if Module was succesful inited
- end;
-
- TCore = class
- private
- //Some Hook Handles. See Plugin SDKs Hooks.txt for Infos
- hLoadingFinished: THandle;
- hMainLoop: THandle;
- hTranslate: THandle;
- hLoadTextures: THandle;
- hExitQuery: THandle;
- hExit: THandle;
- hDebug: THandle;
- hError: THandle;
- sReportError: THandle;
- sReportDebug: THandle;
- sShowMessage: THandle;
- sRetranslate: THandle;
- sReloadTextures: THandle;
- sGetModuleInfo: THandle;
- sGetApplicationHandle: THandle;
-
- Modules: Array [0..High(CORE_MODULES_TO_LOAD)] of TModuleListItem;
-
- //Cur + Last Executed Setting and Getting ;)
- iCurExecuted: Integer;
- iLastExecuted: Integer;
-
- procedure SetCurExecuted(Value: Integer);
-
- //Function Get all Modules and Creates them
- function GetModules: Boolean;
-
- //Loads Core and all Modules
- function Load: Boolean;
-
- //Inits Core and all Modules
- function Init: Boolean;
-
- //DeInits Core and all Modules
- function DeInit: Boolean;
-
- //Load the Core
- function LoadCore: Boolean;
-
- //Init the Core
- function InitCore: Boolean;
-
- //DeInit the Core
- function DeInitCore: Boolean;
-
- //Called one Time per Frame
- function MainLoop: Boolean;
-
- public
- Hooks: THookManager; //Teh Hook Manager ;)
- Services: TServiceManager;//The Service Manager
-
- Name: String; //Name of this Application
- Version: LongWord; //Version of this ". For Info Look PluginDefs Functions
-
- LastErrorReporter:String; //Who Reported the Last Error String
- LastErrorString: String; //Last Error String reported
-
- property CurExecuted: Integer read iCurExecuted write SetCurExecuted; //ID of Plugin or Module curently Executed
- property LastExecuted: Integer read iLastExecuted;
-
- //---------------
- //Main Methods to control the Core:
- //---------------
- constructor Create(const cName: String; const cVersion: LongWord);
-
- //Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
- procedure Run;
-
- //Method for other Classes to get Pointer to a specific Module
- function GetModulebyName(const Name: String): PCoreModule;
-
- //--------------
- // Hook and Service Procs:
- //--------------
- function ShowMessage(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol)
- function ReportError(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
- function ReportDebug(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
- function Retranslate(wParam: TwParam; lParam: TlParam): integer; //Calls Translate hook
- function ReloadTextures(wParam: TwParam; lParam: TlParam): integer; //Calls LoadTextures hook
- function GetModuleInfo(wParam: TwParam; lParam: TlParam): integer; //If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
- function GetApplicationHandle(wParam: TwParam; lParam: TlParam): integer; //Returns Application Handle
- end;
-
-var
- Core: TCore;
-
-implementation
-
-uses
- {$IFDEF win32}
- Windows,
- {$ENDIF}
- SysUtils;
-
-//-------------
-// Create - Creates Class + Hook and Service Manager
-//-------------
-constructor TCore.Create(const cName: String; const cVersion: LongWord);
-begin
- inherited Create;
-
- Name := cName;
- Version := cVersion;
- iLastExecuted := 0;
- iCurExecuted := 0;
-
- LastErrorReporter := '';
- LastErrorString := '';
-
- Hooks := THookManager.Create(50);
- Services := TServiceManager.Create;
-end;
-
-//-------------
-//Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
-//-------------
-procedure TCore.Run;
-var
- Success: Boolean;
-
- procedure HandleError(const ErrorMsg: string);
- begin
- if (LastErrorString <> '') then
- Self.ShowMessage(CORE_SM_ERROR, PChar(ErrorMsg + ': ' + LastErrorString))
- else
- Self.ShowMessage(CORE_SM_ERROR, PChar(ErrorMsg));
-
- //DeInit
- DeInit;
- end;
-
-begin
- //Get Modules
- try
- Success := GetModules();
- except
- Success := False;
- end;
-
- if (not Success) then
- begin
- HandleError('Error Getting Modules');
- Exit;
- end;
-
- //Loading
- try
- Success := Load();
- except
- Success := False;
- end;
-
- if (not Success) then
- begin
- HandleError('Error loading Modules');
- Exit;
- end;
-
- //Init
- try
- Success := Init();
- except
- Success := False;
- end;
-
- if (not Success) then
- begin
- HandleError('Error initing Modules');
- Exit;
- end;
-
- //Call Translate Hook
- if (Hooks.CallEventChain(hTranslate, 0, nil) <> 0) then
- begin
- HandleError('Error translating');
- Exit;
- end;
-
- //Calls LoadTextures Hook
- if (Hooks.CallEventChain(hLoadTextures, 0, nil) <> 0) then
- begin
- HandleError('Error loading textures');
- Exit;
- end;
-
- //Calls Loading Finished Hook
- if (Hooks.CallEventChain(hLoadingFinished, 0, nil) <> 0) then
- begin
- HandleError('Error calling LoadingFinished Hook');
- Exit;
- end;
-
- //Start MainLoop
- while Success do
- begin
- Success := MainLoop();
- // to-do : Call Display Draw here
- end;
-end;
-
-//-------------
-//Called one Time per Frame
-//-------------
-function TCore.MainLoop: Boolean;
-begin
- Result := False;
-end;
-
-//-------------
-//Function Get all Modules and Creates them
-//-------------
-function TCore.GetModules: Boolean;
-var
- i: Integer;
-begin
- Result := False;
- for i := 0 to high(Modules) do
- begin
- try
- Modules[i].NeedsDeInit := False;
- Modules[i].Module := CORE_MODULES_TO_LOAD[i].Create;
- Modules[i].Module.Info(@Modules[i].Info);
- except
- ReportError(Integer(PChar('Can''t get module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
- Exit;
- end;
- end;
- Result := True;
-end;
-
-//-------------
-//Loads Core and all Modules
-//-------------
-function TCore.Load: Boolean;
-var
- i: Integer;
-begin
- Result := LoadCore;
-
- for i := 0 to High(CORE_MODULES_TO_LOAD) do
- begin
- try
- Result := Modules[i].Module.Load;
- except
- Result := False;
- end;
-
- if (not Result) then
- begin
- ReportError(Integer(PChar('Error loading module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
- break;
- end;
- end;
-end;
-
-//-------------
-//Inits Core and all Modules
-//-------------
-function TCore.Init: Boolean;
-var
- i: Integer;
-begin
- Result := InitCore;
-
- for i := 0 to High(CORE_MODULES_TO_LOAD) do
- begin
- try
- Result := Modules[i].Module.Init;
- except
- Result := False;
- end;
-
- if (not Result) then
- begin
- ReportError(Integer(PChar('Error initing module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
- break;
- end;
-
- Modules[i].NeedsDeInit := Result;
- end;
-end;
-
-//-------------
-//DeInits Core and all Modules
-//-------------
-function TCore.DeInit: boolean;
-var
- i: integer;
-begin
-
- for i := High(CORE_MODULES_TO_LOAD) downto 0 do
- begin
- try
- if (Modules[i].NeedsDeInit) then
- Modules[i].Module.DeInit;
- except
- end;
- end;
-
- DeInitCore;
-
- Result := true;
-end;
-
-//-------------
-//Load the Core
-//-------------
-function TCore.LoadCore: Boolean;
-begin
- hLoadingFinished := Hooks.AddEvent('Core/LoadingFinished');
- hMainLoop := Hooks.AddEvent('Core/MainLoop');
- hTranslate := Hooks.AddEvent('Core/Translate');
- hLoadTextures := Hooks.AddEvent('Core/LoadTextures');
- hExitQuery := Hooks.AddEvent('Core/ExitQuery');
- hExit := Hooks.AddEvent('Core/Exit');
- hDebug := Hooks.AddEvent('Core/NewDebugInfo');
- hError := Hooks.AddEvent('Core/NewError');
-
- sReportError := Services.AddService('Core/ReportError', nil, Self.ReportError);
- sReportDebug := Services.AddService('Core/ReportDebug', nil, Self.ReportDebug);
- sShowMessage := Services.AddService('Core/ShowMessage', nil, Self.ShowMessage);
- sRetranslate := Services.AddService('Core/Retranslate', nil, Self.Retranslate);
- sReloadTextures := Services.AddService('Core/ReloadTextures', nil, Self.ReloadTextures);
- sGetModuleInfo := Services.AddService('Core/GetModuleInfo', nil, Self.GetModuleInfo);
- sGetApplicationHandle := Services.AddService('Core/GetApplicationHandle', nil, Self.GetApplicationHandle);
-
- //A little Test
- Hooks.AddSubscriber('Core/NewError', HookTest);
-
- result := true;
-end;
-
-//-------------
-//Init the Core
-//-------------
-function TCore.InitCore: Boolean;
-begin
- //Don not init something atm.
- result := true;
-end;
-
-//-------------
-//DeInit the Core
-//-------------
-function TCore.DeInitCore: Boolean;
-begin
- // TODO: write TService-/HookManager.Free and call it here
- Result := true;
-end;
-
-//-------------
-//Method for other classes to get pointer to a specific module
-//-------------
-function TCore.GetModuleByName(const Name: String): PCoreModule;
-var i: Integer;
-begin
- Result := nil;
- for i := 0 to High(Modules) do
- begin
- if (Modules[i].Info.Name = Name) then
- begin
- Result := @Modules[i].Module;
- Break;
- end;
- end;
-end;
-
-//-------------
-// Shows a MessageDialog (lParam: PChar Text, wParam: Symbol)
-//-------------
-function TCore.ShowMessage(wParam: TwParam; lParam: TlParam): integer;
-{$IFDEF MSWINDOWS}
-var Params: Cardinal;
-{$ENDIF}
-begin
- Result := -1;
-
- {$IFDEF MSWINDOWS}
- if (lParam <> nil) then
- begin
- Params := MB_OK;
- case wParam of
- CORE_SM_ERROR: Params := Params or MB_ICONERROR;
- CORE_SM_WARNING: Params := Params or MB_ICONWARNING;
- CORE_SM_INFO: Params := Params or MB_ICONINFORMATION;
- end;
-
- //Show:
- Result := Messagebox(0, lParam, PChar(Name), Params);
- end;
- {$ENDIF}
-
- // TODO: write ShowMessage for other OSes
-end;
-
-//-------------
-// Calls NewError HookChain (wParam: Pchar(Message), lParam: PChar(Reportername))
-//-------------
-function TCore.ReportError(wParam: TwParam; lParam: TlParam): integer;
-begin
- //Update LastErrorReporter and LastErrorString
- LastErrorReporter := String(PChar(lParam));
- LastErrorString := String(PChar(Pointer(wParam)));
-
- Hooks.CallEventChain(hError, wParam, lParam);
-
- // FIXME: return a correct result
- Result := 0;
-end;
-
-//-------------
-// Calls NewDebugInfo HookChain (wParam: Pchar(Message), lParam: PChar(Reportername))
-//-------------
-function TCore.ReportDebug(wParam: TwParam; lParam: TlParam): integer;
-begin
- Hooks.CallEventChain(hDebug, wParam, lParam);
-
- // FIXME: return a correct result
- Result := 0;
-end;
-
-//-------------
-// Calls Translate hook
-//-------------
-function TCore.Retranslate(wParam: TwParam; lParam: TlParam): integer;
-begin
- Hooks.CallEventChain(hTranslate, 1, nil);
-
- // FIXME: return a correct result
- Result := 0;
-end;
-
-//-------------
-// Calls LoadTextures hook
-//-------------
-function TCore.ReloadTextures(wParam: TwParam; lParam: TlParam): integer;
-begin
- Hooks.CallEventChain(hLoadTextures, 1, nil);
-
- // FIXME: return a correct result
- Result := 0;
-end;
-
-//-------------
-// If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
-//-------------
-function TCore.GetModuleInfo(wParam: TwParam; lParam: TlParam): integer;
-var
- I: integer;
-begin
- if (Pointer(lParam) = nil) then
- begin
- Result := Length(Modules);
- end
- else
- begin
- try
- for I := 0 to High(Modules) do
- begin
- AModuleInfo(Pointer(lParam))[I].Name := Modules[I].Info.Name;
- AModuleInfo(Pointer(lParam))[I].Version := Modules[I].Info.Version;
- AModuleInfo(Pointer(lParam))[I].Description := Modules[I].Info.Description;
- end;
- Result := Length(Modules);
- except
- Result := -1;
- end;
- end;
-end;
-
-//-------------
-// Returns Application Handle
-//-------------
-function TCore.GetApplicationHandle(wParam: TwParam; lParam: TlParam): integer;
-begin
- Result := hInstance;
-end;
-
-//-------------
-// Called when setting CurExecuted
-//-------------
-procedure TCore.SetCurExecuted(Value: Integer);
-begin
- //Set Last Executed
- iLastExecuted := iCurExecuted;
-
- //Set Cur Executed
- iCurExecuted := Value;
-end;
-
-end.
diff --git a/Game/Code/Classes/UCoreModule.pas b/Game/Code/Classes/UCoreModule.pas
deleted file mode 100644
index 031fb04e..00000000
--- a/Game/Code/Classes/UCoreModule.pas
+++ /dev/null
@@ -1,128 +0,0 @@
-unit UCoreModule;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-{*********************
- TCoreModule
- Dummy Class that has Methods that will be called from Core
- In the Best case every Piece of this Software is a Module
-*********************}
-uses UPluginDefs;
-
-type
- PCoreModule = ^TCoreModule;
- TCoreModule = class
- public
- Constructor Create; virtual;
-
- //Function that gives some Infos about the Module to the Core
- Procedure Info(const pInfo: PModuleInfo); virtual;
-
- //Is Called on Loading.
- //In this Method only Events and Services should be created
- //to offer them to other Modules or Plugins during the Init process
- //If False is Returned this will cause a Forced Exit
- Function Load: Boolean; virtual;
-
- //Is Called on Init Process
- //In this Method you can Hook some Events and Create + Init
- //your Classes, Variables etc.
- //If False is Returned this will cause a Forced Exit
- Function Init: Boolean; virtual;
-
- //Is Called during Mainloop before 'Core/MainLoop' Hook and Drawing
- //If False is Returned this will cause a Forced Exit
- Function MainLoop: Boolean; virtual;
-
- //Is Called if this Module has been Inited and there is a Exit.
- //Deinit is in backwards Initing Order
- //If False is Returned this will cause a Forced Exit
- Procedure DeInit; virtual;
-
- //Is Called if this Module will be unloaded and has been created
- //Should be used to Free Memory
- Destructor Destroy; override;
- end;
- cCoreModule = class of TCoreModule;
-
-implementation
-
-//-------------
-// Just the Constructor
-//-------------
-Constructor TCoreModule.Create;
-begin
- //Dummy maaaan ;)
- inherited;
-end;
-
-//-------------
-// Function that gives some Infos about the Module to the Core
-//-------------
-Procedure TCoreModule.Info(const pInfo: PModuleInfo);
-begin
- pInfo^.Name := 'Not Set';
- pInfo^.Version := 0;
- pInfo^.Description := 'Not Set';
-end;
-
-//-------------
-//Is Called on Loading.
-//In this Method only Events and Services should be created
-//to offer them to other Modules or Plugins during the Init process
-//If False is Returned this will cause a Forced Exit
-//-------------
-Function TCoreModule.Load: Boolean;
-begin
- //Dummy ftw!!
- Result := True;
-end;
-
-//-------------
-//Is Called on Init Process
-//In this Method you can Hook some Events and Create + Init
-//your Classes, Variables etc.
-//If False is Returned this will cause a Forced Exit
-//-------------
-Function TCoreModule.Init: Boolean;
-begin
- //Dummy ftw!!
- Result := True;
-end;
-
-//-------------
-//Is Called during Mainloop before 'Core/MainLoop' Hook and Drawing
-//If False is Returned this will cause a Forced Exit
-//-------------
-Function TCoreModule.MainLoop: Boolean;
-begin
- //Dummy ftw!!
- Result := True;
-end;
-
-//-------------
-//Is Called if this Module has been Inited and there is a Exit.
-//Deinit is in backwards Initing Order
-//-------------
-Procedure TCoreModule.DeInit;
-begin
- //Dummy ftw!!
-end;
-
-//-------------
-//Is Called if this Module will be unloaded and has been created
-//Should be used to Free Memory
-//-------------
-Destructor TCoreModule.Destroy;
-begin
- //Dummy ftw!!
- inherited;
-end;
-
-end.
diff --git a/Game/Code/Classes/UCovers.pas b/Game/Code/Classes/UCovers.pas
deleted file mode 100644
index 7bb57b4a..00000000
--- a/Game/Code/Classes/UCovers.pas
+++ /dev/null
@@ -1,430 +0,0 @@
-unit UCovers;
-
-{
- TODO:
- - adjust database to new song-loading (e.g. use SongIDs)
- - support for deletion of outdated covers
- - support for update of changed covers
- - use paths relative to the song for removable disks support
- (a drive might have a different drive-name the next time it is connected,
- so "H:/songs/..." will not match "I:/songs/...")
-}
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- sdl,
- SQLite3,
- SQLiteTable3,
- SysUtils,
- Classes,
- UImage,
- UTexture;
-
-type
- ECoverDBException = class(Exception)
- end;
-
- TCover = class
- private
- ID: int64;
- Filename: WideString;
- public
- constructor Create(ID: int64; Filename: WideString);
- function GetPreviewTexture(): TTexture;
- function GetTexture(): TTexture;
- end;
-
- TThumbnailInfo = record
- CoverWidth: integer; // Original width of cover
- CoverHeight: integer; // Original height of cover
- PixelFormat: TImagePixelFmt; // Pixel-format of thumbnail
- end;
-
- TCoverDatabase = class
- private
- DB: TSQLiteDatabase;
- procedure InitCoverDatabase();
- function CreateThumbnail(const Filename: WideString; var Info: TThumbnailInfo): PSDL_Surface;
- function LoadCover(CoverID: int64): TTexture;
- procedure DeleteCover(CoverID: int64);
- function FindCoverIntern(const Filename: WideString): int64;
- procedure Open();
- function GetVersion(): integer;
- procedure SetVersion(Version: integer);
- public
- constructor Create();
- destructor Destroy; override;
- function AddCover(const Filename: WideString): TCover;
- function FindCover(const Filename: WideString): TCover;
- function CoverExists(const Filename: WideString): boolean;
- function GetMaxCoverSize(): integer;
- procedure SetMaxCoverSize(Size: integer);
- end;
-
- TBlobWrapper = class(TCustomMemoryStream)
- function Write(const Buffer; Count: Integer): Integer; override;
- end;
-
-var
- Covers: TCoverDatabase;
-
-implementation
-
-uses
- UMain,
- ULog,
- UPlatform,
- UIni,
- Math,
- DateUtils;
-
-const
- COVERDB_FILENAME = 'cover.db';
- COVERDB_VERSION = 01; // 0.1
- COVER_TBL = 'Cover';
- COVER_THUMBNAIL_TBL = 'CoverThumbnail';
- COVER_IDX = 'Cover_Filename_IDX';
-
-// Note: DateUtils.DateTimeToUnix() will throw an exception in FPC
-function DateTimeToUnixTime(time: TDateTime): int64;
-begin
- Result := Round((time - UnixDateDelta) * SecsPerDay);
-end;
-
-// Note: DateUtils.UnixToDateTime() will throw an exception in FPC
-function UnixTimeToDateTime(timestamp: int64): TDateTime;
-begin
- Result := timestamp / SecsPerDay + UnixDateDelta;
-end;
-
-
-{ TBlobWrapper }
-
-function TBlobWrapper.Write(const Buffer; Count: Integer): Integer;
-begin
- SetPointer(Pointer(Buffer), Count);
- Result := Count;
-end;
-
-
-{ TCover }
-
-constructor TCover.Create(ID: int64; Filename: WideString);
-begin
- Self.ID := ID;
- Self.Filename := Filename;
-end;
-
-function TCover.GetPreviewTexture(): TTexture;
-begin
- Result := Covers.LoadCover(ID);
-end;
-
-function TCover.GetTexture(): TTexture;
-begin
- Result := Texture.LoadTexture(Filename);
-end;
-
-
-{ TCoverDatabase }
-
-constructor TCoverDatabase.Create();
-begin
- inherited;
-
- Open();
- InitCoverDatabase();
-end;
-
-destructor TCoverDatabase.Destroy;
-begin
- DB.Free;
- inherited;
-end;
-
-function TCoverDatabase.GetVersion(): integer;
-begin
- Result := DB.GetTableValue('PRAGMA user_version');
-end;
-
-procedure TCoverDatabase.SetVersion(Version: integer);
-begin
- DB.ExecSQL(Format('PRAGMA user_version = %d', [Version]));
-end;
-
-function TCoverDatabase.GetMaxCoverSize(): integer;
-begin
- Result := ITextureSizeVals[Ini.TextureSize];
-end;
-
-procedure TCoverDatabase.SetMaxCoverSize(Size: integer);
-var
- I: integer;
-begin
- // search for first valid cover-size > Size
- for I := 0 to Length(ITextureSizeVals)-1 do
- begin
- if (Size <= ITextureSizeVals[I]) then
- begin
- Ini.TextureSize := I;
- Exit;
- end;
- end;
-
- // fall-back to highest size
- Ini.TextureSize := High(ITextureSizeVals);
-end;
-
-procedure TCoverDatabase.Open();
-var
- Version: integer;
- Filename: string;
-begin
- Filename := UTF8Encode(Platform.GetGameUserPath() + COVERDB_FILENAME);
-
- DB := TSQLiteDatabase.Create(Filename);
- Version := GetVersion();
-
- // check version, if version is too old/new, delete database file
- if ((Version <> 0) and (Version <> COVERDB_VERSION)) then
- begin
- Log.LogInfo('Outdated cover-database file found', 'TCoverDatabase.Open');
- // close and delete outdated file
- DB.Free;
- if (not DeleteFile(Filename)) then
- raise ECoverDBException.Create('Could not delete ' + Filename);
- // reopen
- DB := TSQLiteDatabase.Create(Filename);
- Version := 0;
- end;
-
- // set version number after creation
- if (Version = 0) then
- SetVersion(COVERDB_VERSION);
-
- // speed-up disk-writing. The default FULL-synchronous mode is too slow.
- // With this option disk-writing is approx. 4 times faster but the database
- // might be corrupted if the OS crashes, although this is very unlikely.
- DB.ExecSQL('PRAGMA synchronous = OFF;');
-
- // the next line rather gives a slow-down instead of a speed-up, so we do not use it
- //DB.ExecSQL('PRAGMA temp_store = MEMORY;');
-end;
-
-procedure TCoverDatabase.InitCoverDatabase();
-begin
- DB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+COVER_TBL+'] (' +
- '[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
- '[Filename] TEXT UNIQUE NOT NULL, ' +
- '[Date] INTEGER NOT NULL, ' +
- '[Width] INTEGER NOT NULL, ' +
- '[Height] INTEGER NOT NULL ' +
- ')');
-
- DB.ExecSQL('CREATE INDEX IF NOT EXISTS ['+COVER_IDX+'] ON ['+COVER_TBL+'](' +
- '[Filename] ASC' +
- ')');
-
- DB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+COVER_THUMBNAIL_TBL+'] (' +
- '[ID] INTEGER NOT NULL PRIMARY KEY, ' +
- '[Format] INTEGER NOT NULL, ' +
- '[Width] INTEGER NOT NULL, ' +
- '[Height] INTEGER NOT NULL, ' +
- '[Data] BLOB NULL' +
- ')');
-end;
-
-function TCoverDatabase.FindCoverIntern(const Filename: WideString): int64;
-begin
- Result := DB.GetTableValue('SELECT [ID] FROM ['+COVER_TBL+'] ' +
- 'WHERE [Filename] = ?',
- [UTF8Encode(Filename)]);
-end;
-
-function TCoverDatabase.FindCover(const Filename: WideString): TCover;
-var
- CoverID: int64;
-begin
- Result := nil;
- try
- CoverID := FindCoverIntern(Filename);
- if (CoverID > 0) then
- Result := TCover.Create(CoverID, Filename);
- except on E: Exception do
- Log.LogError(E.Message, 'TCoverDatabase.FindCover');
- end;
-end;
-
-function TCoverDatabase.CoverExists(const Filename: WideString): boolean;
-begin
- Result := false;
- try
- Result := (FindCoverIntern(Filename) > 0);
- except on E: Exception do
- Log.LogError(E.Message, 'TCoverDatabase.CoverExists');
- end;
-end;
-
-function TCoverDatabase.AddCover(const Filename: WideString): TCover;
-var
- CoverID: int64;
- Thumbnail: PSDL_Surface;
- CoverData: TBlobWrapper;
- FileDate: TDateTime;
- Info: TThumbnailInfo;
-begin
- Result := nil;
-
- //if (not FileExists(Filename)) then
- // Exit;
-
- // TODO: replace '\' with '/' in filename
- FileDate := Now(); //FileDateToDateTime(FileAge(Filename));
-
- Thumbnail := CreateThumbnail(Filename, Info);
- if (Thumbnail = nil) then
- Exit;
-
- CoverData := TBlobWrapper.Create;
- CoverData.Write(Thumbnail^.pixels, Thumbnail^.h * Thumbnail^.pitch);
-
- try
- // Note: use a transaction to speed-up file-writing.
- // Without data written by the first INSERT might be moved at the second INSERT.
- DB.BeginTransaction();
-
- // add general cover info
- DB.ExecSQL('INSERT INTO ['+COVER_TBL+'] ' +
- '([Filename], [Date], [Width], [Height]) VALUES' +
- '(?, ?, ?, ?)',
- [UTF8Encode(Filename), DateTimeToUnixTime(FileDate),
- Info.CoverWidth, Info.CoverHeight]);
-
- // get auto-generated cover ID
- CoverID := DB.GetLastInsertRowID();
-
- // add thumbnail info
- DB.ExecSQL('INSERT INTO ['+COVER_THUMBNAIL_TBL+'] ' +
- '([ID], [Format], [Width], [Height], [Data]) VALUES' +
- '(?, ?, ?, ?, ?)',
- [CoverID, Ord(Info.PixelFormat),
- Thumbnail^.w, Thumbnail^.h, CoverData]);
-
- Result := TCover.Create(CoverID, Filename);
- except on E: Exception do
- Log.LogError(E.Message, 'TCoverDatabase.AddCover');
- end;
-
- DB.Commit();
- CoverData.Free;
- SDL_FreeSurface(Thumbnail);
-end;
-
-function TCoverDatabase.LoadCover(CoverID: int64): TTexture;
-var
- Width, Height: integer;
- PixelFmt: TImagePixelFmt;
- Data: PChar;
- DataSize: integer;
- Filename: WideString;
- Table: TSQLiteUniTable;
-begin
- Table := nil;
-
- try
- Table := DB.GetUniTable(Format(
- 'SELECT C.[Filename], T.[Format], T.[Width], T.[Height], T.[Data] ' +
- 'FROM ['+COVER_TBL+'] C ' +
- 'INNER JOIN ['+COVER_THUMBNAIL_TBL+'] T ' +
- 'USING(ID) ' +
- 'WHERE [ID] = %d', [CoverID]));
-
- Filename := UTF8Decode(Table.FieldAsString(0));
- PixelFmt := TImagePixelFmt(Table.FieldAsInteger(1));
- Width := Table.FieldAsInteger(2);
- Height := Table.FieldAsInteger(3);
-
- Data := Table.FieldAsBlobPtr(4, DataSize);
- if (Data <> nil) and
- (PixelFmt = ipfRGB) then
- begin
- Result := Texture.CreateTexture(Data, Filename, Width, Height, 24)
- end
- else
- begin
- FillChar(Result, SizeOf(TTexture), 0);
- end;
- except on E: Exception do
- Log.LogError(E.Message, 'TCoverDatabase.LoadCover');
- end;
-
- Table.Free;
-end;
-
-procedure TCoverDatabase.DeleteCover(CoverID: int64);
-begin
- DB.ExecSQL(Format('DELETE FROM ['+COVER_TBL+'] WHERE [ID] = %d', [CoverID]));
- DB.ExecSQL(Format('DELETE FROM ['+COVER_THUMBNAIL_TBL+'] WHERE [ID] = %d', [CoverID]));
-end;
-
-(**
- * Returns a pointer to an array of bytes containing the texture data in the
- * requested size
- *)
-function TCoverDatabase.CreateThumbnail(const Filename: WideString; var Info: TThumbnailInfo): PSDL_Surface;
-var
- TargetAspect, SourceAspect: double;
- //TargetWidth, TargetHeight: integer;
- Thumbnail: PSDL_Surface;
- MaxSize: integer;
-begin
- Result := nil;
-
- MaxSize := GetMaxCoverSize();
-
- Thumbnail := LoadImage(Filename);
- if (not assigned(Thumbnail)) then
- begin
- Log.LogError('Could not load cover: "'+ Filename +'"', 'TCoverDatabase.AddCover');
- Exit;
- end;
-
- // Convert pixel format as needed
- AdjustPixelFormat(Thumbnail, TEXTURE_TYPE_PLAIN);
-
- Info.CoverWidth := Thumbnail^.w;
- Info.CoverHeight := Thumbnail^.h;
- Info.PixelFormat := ipfRGB;
-
- (* TODO: keep aspect ratio
- TargetAspect := Width / Height;
- SourceAspect := TexSurface.w / TexSurface.h;
-
- // Scale texture to covers dimensions (keep aspect)
- if (SourceAspect >= TargetAspect) then
- begin
- TargetWidth := Width;
- TargetHeight := Trunc(Width / SourceAspect);
- end
- else
- begin
- TargetHeight := Height;
- TargetWidth := Trunc(Height * SourceAspect);
- end;
- *)
-
- // TODO: do not scale if image is smaller
- ScaleImage(Thumbnail, MaxSize, MaxSize);
-
- Result := Thumbnail;
-end;
-
-end.
-
diff --git a/Game/Code/Classes/UDLLManager.pas b/Game/Code/Classes/UDLLManager.pas
deleted file mode 100644
index 3d32a72a..00000000
--- a/Game/Code/Classes/UDLLManager.pas
+++ /dev/null
@@ -1,253 +0,0 @@
-unit UDLLManager;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses ModiSDK,
- UFiles;
-
-type
- TDLLMan = class
- private
- hLib: THandle;
- P_Init: fModi_Init;
- P_Draw: fModi_Draw;
- P_Finish: fModi_Finish;
- P_RData: pModi_RData;
- public
- Plugins: array of TPluginInfo;
- PluginPaths: array of String;
- Selected: ^TPluginInfo;
-
- constructor Create;
-
- procedure GetPluginList;
- procedure ClearPluginInfo(No: Cardinal);
- function LoadPluginInfo(Filename: String; No: Cardinal): boolean;
-
- function LoadPlugin(No: Cardinal): boolean;
- procedure UnLoadPlugin;
-
- function PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
- function PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
- function PluginFinish (var Playerinfo: TPlayerinfo): byte;
- procedure PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
- end;
-
-var
- DLLMan: TDLLMan;
-
-const
- DLLPath = 'Plugins';
-
- {$IFDEF MSWINDOWS}
- DLLExt = '.dll';
- {$ENDIF}
- {$IFDEF LINUX}
- DLLExt = '.so';
- {$ENDIF}
- {$IFDEF DARWIN}
- DLLExt = '.dylib';
- {$ENDIF}
-
-implementation
-
-uses {$IFDEF MSWINDOWS}
- windows,
- {$ELSE}
- dynlibs,
- {$ENDIF}
- ULog,
- SysUtils;
-
-
-constructor TDLLMan.Create;
-begin
- inherited;
- SetLength(Plugins, 0);
- SetLength(PluginPaths, Length(Plugins));
- GetPluginList;
-end;
-
-procedure TDLLMan.GetPluginList;
-var
- SR: TSearchRec;
-begin
-
- if FindFirst(DLLPath +PathDelim+ '*' + DLLExt, faAnyFile , SR) = 0 then
- begin
- repeat
- SetLength(Plugins, Length(Plugins)+1);
- SetLength(PluginPaths, Length(Plugins));
-
- if LoadPluginInfo(SR.Name, High(Plugins)) then //Loaded succesful
- begin
- PluginPaths[High(PluginPaths)] := SR.Name;
- end
- else //Error Loading
- begin
- SetLength(Plugins, Length(Plugins)-1);
- SetLength(PluginPaths, Length(Plugins));
- end;
-
- until FindNext(SR) <> 0;
- FindClose(SR);
- end;
-end;
-
-procedure TDLLMan.ClearPluginInfo(No: Cardinal);
-begin
- //Set to Party Modi Plugin
- Plugins[No].Typ := 8;
-
- Plugins[No].Name := 'unknown';
- Plugins[No].NumPlayers := 0;
-
- Plugins[No].Creator := 'Nobody';
- Plugins[No].PluginDesc := 'NO_PLUGIN_DESC';
-
- Plugins[No].LoadSong := True;
- Plugins[No].ShowScore := True;
- Plugins[No].ShowBars := False;
- Plugins[No].ShowNotes := True;
- Plugins[No].LoadVideo := True;
- Plugins[No].LoadBack := True;
-
- Plugins[No].TeamModeOnly := False;
- Plugins[No].GetSoundData := False;
- Plugins[No].Dummy := False;
-
-
- Plugins[No].BGShowFull := False;
- Plugins[No].BGShowFull_O := True;
-
- Plugins[No].ShowRateBar:= False;
- Plugins[No].ShowRateBar_O := True;
-
- Plugins[No].EnLineBonus := False;
- Plugins[No].EnLineBonus_O := True;
-end;
-
-function TDLLMan.LoadPluginInfo(Filename: String; No: Cardinal): boolean;
-var
- hLibg: THandle;
- Info: pModi_PluginInfo;
- I: Integer;
-begin
- Result := False;
- //Clear Plugin Info
- ClearPluginInfo(No);
-
- {//Workaround Plugins Loaded 2 Times
- For I := low(PluginPaths) to high(PluginPaths) do
- if (PluginPaths[I] = Filename) then
- exit; }
-
- //Load Libary
- hLibg := LoadLibrary(PChar(DLLPath +PathDelim+ Filename));
- //If Loaded
- if (hLibg <> 0) then
- begin
- //Load Info Procedure
- @Info := GetProcAddress (hLibg, PChar('PluginInfo'));
-
- //If Loaded
- if (@Info <> nil) then
- begin
- //Load PluginInfo
- Info (Plugins[No]);
- Result := True;
- end
- else
- Log.LogError('Could not Load Plugin "' + Filename + '": Info Procedure not Found');
-
- FreeLibrary (hLibg);
- end
- else
- Log.LogError('Could not Load Plugin "' + Filename + '": Libary not Loaded');
-end;
-
-function TDLLMan.LoadPlugin(No: Cardinal): boolean;
-begin
- Result := False;
- //Load Libary
- hLib := LoadLibrary(PChar(DLLPath +PathDelim+ PluginPaths[No]));
- //If Loaded
- if (hLib <> 0) then
- begin
- //Load Info Procedure
- @P_Init := GetProcAddress (hLib, PChar('Init'));
- @P_Draw := GetProcAddress (hLib, PChar('Draw'));
- @P_Finish := GetProcAddress (hLib, PChar('Finish'));
-
- //If Loaded
- if (@P_Init <> nil) And (@P_Draw <> nil) And (@P_Finish <> nil) then
- begin
- Selected := @Plugins[No];
- Result := True;
- end
- else
- begin
- Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Procedures not Found');
-
- end;
- end
- else
- Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Libary not Loaded');
-end;
-
-procedure TDLLMan.UnLoadPlugin;
-begin
-if (hLib <> 0) then
- FreeLibrary (hLib);
-
-//Selected := nil;
-@P_Init := nil;
-@P_Draw := nil;
-@P_Finish := nil;
-@P_RData := nil;
-end;
-
-function TDLLMan.PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
-var
- Methods: TMethodRec;
-begin
- Methods.LoadTex := LoadTex;
- Methods.Print := Print;
- Methods.LoadSound := LoadSound;
- Methods.PlaySound := PlaySound;
-
- if (@P_Init <> nil) then
- Result := P_Init (TeamInfo, PlayerInfo, Sentences, Methods)
- else
- Result := False
-end;
-
-function TDLLMan.PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
-begin
-if (@P_Draw <> nil) then
- Result := P_Draw (PlayerInfo, CurSentence)
-else
- Result := False
-end;
-
-function TDLLMan.PluginFinish (var Playerinfo: TPlayerinfo): byte;
-begin
-if (@P_Finish <> nil) then
- Result := P_Finish (PlayerInfo)
-else
- Result := 0;
-end;
-
-procedure TDLLMan.PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
-begin
-if (@P_RData <> nil) then
- P_RData (handle, buffer, len, user);
-end;
-
-end.
diff --git a/Game/Code/Classes/UDataBase.pas b/Game/Code/Classes/UDataBase.pas
deleted file mode 100644
index cd315df3..00000000
--- a/Game/Code/Classes/UDataBase.pas
+++ /dev/null
@@ -1,533 +0,0 @@
-unit UDataBase;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses USongs,
- USong,
- Classes,
- SQLiteTable3;
-
-//--------------------
-//DataBaseSystem - Class including all DB Methods
-//--------------------
-type
- TStatType = (
- stBestScores, // Best Scores
- stBestSingers, // Best Singers
- stMostSungSong, // Most sung Songs
- stMostPopBand // Most popular Band
- );
-
- // abstract super-class for statistic results
- TStatResult = class
- public
- Typ: TStatType;
- end;
-
- TStatResultBestScores = class(TStatResult)
- public
- Singer: WideString;
- Score: Word;
- Difficulty: Byte;
- SongArtist: WideString;
- SongTitle: WideString;
- end;
-
- TStatResultBestSingers = class(TStatResult)
- public
- Player: WideString;
- AverageScore: Word;
- end;
-
- TStatResultMostSungSong = class(TStatResult)
- public
- Artist: WideString;
- Title: WideString;
- TimesSung: Word;
- end;
-
- TStatResultMostPopBand = class(TStatResult)
- public
- ArtistName: WideString;
- TimesSungTot: Word;
- end;
-
-
- TDataBaseSystem = class
- private
- ScoreDB: TSQLiteDatabase;
- fFilename: string;
-
- function GetVersion(): integer;
- procedure SetVersion(Version: integer);
- public
- property Filename: string read fFilename;
-
- destructor Destroy; override;
-
- procedure Init(const Filename: string);
- procedure ReadScore(Song: TSong);
- procedure AddScore(Song: TSong; Level: integer; const Name: WideString; Score: integer);
- procedure WriteScore(Song: TSong);
-
- function GetStats(Typ: TStatType; Count: Byte; Page: Cardinal; Reversed: Boolean): TList;
- procedure FreeStats(StatList: TList);
- function GetTotalEntrys(Typ: TStatType): Cardinal;
- function GetStatReset: TDateTime;
- end;
-
-var
- DataBase: TDataBaseSystem;
-
-implementation
-
-uses
- ULog,
- DateUtils,
- StrUtils,
- SysUtils;
-
-const
- cDBVersion = 01; // 0.1
- cUS_Scores = 'us_scores';
- cUS_Songs = 'us_songs';
- cUS_Statistics_Info = 'us_statistics_info';
-
-(**
- * Opens Database and Create Tables if not Exist
- *)
-procedure TDataBaseSystem.Init(const Filename: string);
-var
- Version: integer;
-begin
- if Assigned(ScoreDB) then
- Exit;
-
- Log.LogStatus('Initializing database: "'+Filename+'"', 'TDataBaseSystem.Init');
-
- try
-
- // Open Database
- ScoreDB := TSQLiteDatabase.Create(Filename);
- fFilename := Filename;
-
- // Close and delete outdated file
- Version := GetVersion();
- if ((Version <> 0) and (Version <> cDBVersion)) then
- begin
- Log.LogInfo('Outdated cover-database file found', 'TDataBaseSystem.Init');
- // Close and delete outdated file
- ScoreDB.Free;
- if (not DeleteFile(Filename)) then
- raise Exception.Create('Could not delete ' + Filename);
- // Reopen
- ScoreDB := TSQLiteDatabase.Create(Filename);
- Version := 0;
- end;
-
- // Set version number after creation
- if (Version = 0) then
- SetVersion(cDBVersion);
-
-
- // SQLite does not handle VARCHAR(n) or INT(n) as expected.
- // Texts do not have a restricted length, no matter which type is used,
- // so use the native TEXT type. INT(n) is always INTEGER.
- // In addition, SQLiteTable3 will fail if other types than the native SQLite
- // types are used (especially FieldAsInteger). Also take care to write the
- // types in upper-case letters although SQLite does not care about this -
- // SQLiteTable3 is very sensitive in this regard.
-
- ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Scores+'] (' +
- '[SongID] INTEGER NOT NULL, ' +
- '[Difficulty] INTEGER NOT NULL, ' +
- '[Player] TEXT NOT NULL, ' +
- '[Score] INTEGER NOT NULL' +
- ');');
-
- ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Songs+'] (' +
- '[ID] INTEGER PRIMARY KEY, ' +
- '[Artist] TEXT NOT NULL, ' +
- '[Title] TEXT NOT NULL, ' +
- '[TimesPlayed] INTEGER NOT NULL' +
- ');');
-
- if not ScoreDB.TableExists(cUS_Statistics_Info) then
- begin
- ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Statistics_Info+'] (' +
- '[ResetTime] INTEGER' +
- ');');
- // insert creation timestamp
- ScoreDB.ExecSQL(Format('INSERT INTO ['+cUS_Statistics_Info+'] ' +
- '([ResetTime]) VALUES(%d);',
- [DateTimeToUnix(Now())]));
- end;
-
- except
- on E: Exception do
- begin
- Log.LogError(E.Message, 'TDataBaseSystem.Init');
- FreeAndNil(ScoreDB);
- end;
- end;
-
-end;
-
-(**
- * Frees Database
- *)
-destructor TDataBaseSystem.Destroy;
-begin
- Log.LogInfo('TDataBaseSystem.Free', 'TDataBaseSystem.Destroy');
- ScoreDB.Free;
- inherited;
-end;
-
-(**
- * Read Scores into SongArray
- *)
-procedure TDataBaseSystem.ReadScore(Song: TSong);
-var
- TableData: TSQLiteUniTable;
- Difficulty: Integer;
-begin
- if not Assigned(ScoreDB) then
- Exit;
-
- TableData := nil;
-
- try
- // Search Song in DB
- TableData := ScoreDB.GetUniTable(
- 'SELECT [Difficulty], [Player], [Score] FROM ['+cUS_Scores+'] ' +
- 'WHERE [SongID] = (' +
- 'SELECT [ID] FROM ['+cUS_Songs+'] ' +
- 'WHERE [Artist] = ? AND [Title] = ? ' +
- 'LIMIT 1) ' +
- 'ORDER BY [Score] DESC LIMIT 15',
- [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
-
- // Empty Old Scores
- SetLength(Song.Score[0], 0);
- SetLength(Song.Score[1], 0);
- SetLength(Song.Score[2], 0);
-
- // Go through all Entrys
- while (not TableData.EOF) do
- begin
- // Add one Entry to Array
- Difficulty := TableData.FieldAsInteger(TableData.FieldIndex['Difficulty']);
- if ((Difficulty >= 0) and (Difficulty <= 2)) and
- (Length(Song.Score[Difficulty]) < 5) then
- begin
- SetLength(Song.Score[Difficulty], Length(Song.Score[Difficulty]) + 1);
-
- Song.Score[Difficulty, High(Song.Score[Difficulty])].Name :=
- UTF8Decode(TableData.FieldByName['Player']);
- Song.Score[Difficulty, High(Song.Score[Difficulty])].Score :=
- TableData.FieldAsInteger(TableData.FieldIndex['Score']);
- end;
-
- TableData.Next;
- end; // while
-
- except
- for Difficulty := 0 to 2 do
- begin
- SetLength(Song.Score[Difficulty], 1);
- Song.Score[Difficulty, 1].Name := 'Error Reading ScoreDB';
- end;
- end;
-
- TableData.Free;
-end;
-
-(**
- * Adds one new score to DB
- *)
-procedure TDataBaseSystem.AddScore(Song: TSong; Level: integer; const Name: WideString; Score: integer);
-var
- ID: Integer;
- TableData: TSQLiteTable;
-begin
- if not Assigned(ScoreDB) then
- Exit;
-
- // Prevent 0 Scores from being added
- if (Score <= 0) then
- Exit;
-
- TableData := nil;
-
- try
-
- ID := ScoreDB.GetTableValue(
- 'SELECT [ID] FROM ['+cUS_Songs+'] ' +
- 'WHERE [Artist] = ? AND [Title] = ?',
- [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
- if (ID = 0) then
- begin
- // Create song if it does not exist
- ScoreDB.ExecSQL(
- 'INSERT INTO ['+cUS_Songs+'] ' +
- '([ID], [Artist], [Title], [TimesPlayed]) VALUES ' +
- '(NULL, ?, ?, 0);',
- [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
- // Get song-ID
- ID := ScoreDB.GetLastInsertRowID();
- end;
- // Create new entry
- ScoreDB.ExecSQL(
- 'INSERT INTO ['+cUS_Scores+'] ' +
- '([SongID] ,[Difficulty], [Player], [Score]) VALUES ' +
- '(?, ?, ?, ?);',
- [ID, Level, UTF8Encode(Name), Score]);
-
- // Delete last position when there are more than 5 entrys.
- // Fixes crash when there are > 5 ScoreEntrys
- // Note: GetUniTable is not applicable here, as the results are used while
- // table entries are deleted.
- TableData := ScoreDB.GetTable(
- 'SELECT [Player], [Score] FROM ['+cUS_Scores+'] ' +
- 'WHERE [SongID] = ' + InttoStr(ID) + ' AND ' +
- '[Difficulty] = ' + InttoStr(Level) +' ' +
- 'ORDER BY [Score] DESC LIMIT -1 OFFSET 5');
-
- while (not TableData.EOF) do
- begin
- // Note: Score is an int-value, so in contrast to Player, we do not bind
- // this value. Otherwise we had to convert the string to an int to avoid
- // an automatic cast of this field to the TEXT type (although it might even
- // work that way).
- ScoreDB.ExecSQL(
- 'DELETE FROM ['+cUS_Scores+'] ' +
- 'WHERE [SongID] = ' + InttoStr(ID) + ' AND ' +
- '[Difficulty] = ' + InttoStr(Level) +' AND ' +
- '[Player] = ? AND ' +
- '[Score] = ' + TableData.FieldByName['Score'],
- [TableData.FieldByName['Player']]);
-
- TableData.Next;
- end;
-
- except on E: Exception do
- Log.LogError(E.Message, 'TDataBaseSystem.AddScore');
- end;
-
- TableData.Free;
-end;
-
-(**
- * Not needed with new System.
- * Used for increment played count
- *)
-procedure TDataBaseSystem.WriteScore(Song: TSong);
-begin
- if not Assigned(ScoreDB) then
- Exit;
-
- try
- // Increase TimesPlayed
- ScoreDB.ExecSQL(
- 'UPDATE ['+cUS_Songs+'] ' +
- 'SET [TimesPlayed] = [TimesPlayed] + 1 ' +
- 'WHERE [Title] = ? AND [Artist] = ?;',
- [UTF8Encode(Song.Title), UTF8Encode(Song.Artist)]);
- except on E: Exception do
- Log.LogError(E.Message, 'TDataBaseSystem.WriteScore');
- end;
-end;
-
-(**
- * Writes some stats to array.
- * Returns nil if the database is not ready or a list with zero or more statistic
- * entries.
- * Free the result-list with FreeStats() after usage to avoid memory leaks.
- *)
-function TDataBaseSystem.GetStats(Typ: TStatType; Count: Byte; Page: Cardinal; Reversed: Boolean): TList;
-var
- Query: String;
- TableData: TSQLiteUniTable;
- Stat: TStatResult;
-begin
- Result := nil;
-
- if not Assigned(ScoreDB) then
- Exit;
-
- {Todo: Add Prevention that only players with more than 5 scores are selected at type 2}
-
- // Create query
- case Typ of
- stBestScores: begin
- Query := 'SELECT [Player], [Difficulty], [Score], [Artist], [Title] FROM ['+cUS_Scores+'] ' +
- 'INNER JOIN ['+cUS_Songs+'] ON ([SongID] = [ID]) ORDER BY [Score]';
- end;
- stBestSingers: begin
- Query := 'SELECT [Player], ROUND(AVG([Score])) FROM ['+cUS_Scores+'] ' +
- 'GROUP BY [Player] ORDER BY AVG([Score])';
- end;
- stMostSungSong: begin
- Query := 'SELECT [Artist], [Title], [TimesPlayed] FROM ['+cUS_Songs+'] ' +
- 'ORDER BY [TimesPlayed]';
- end;
- stMostPopBand: begin
- Query := 'SELECT [Artist], SUM([TimesPlayed]) FROM ['+cUS_Songs+'] ' +
- 'GROUP BY [Artist] ORDER BY SUM([TimesPlayed])';
- end;
- end;
-
- // Add order direction
- Query := Query + IfThen(Reversed, ' ASC', ' DESC');
-
- // Add limit
- Query := Query + ' LIMIT ' + InttoStr(Count * Page) + ', ' + InttoStr(Count) + ';';
-
- // Execute query
- try
- TableData := ScoreDB.GetUniTable(Query);
- except
- on E: Exception do
- begin
- Log.LogError(E.Message, 'TDataBaseSystem.GetStats');
- Exit;
- end;
- end;
-
- Result := TList.Create;
- Stat := nil;
-
- // Copy result to stats array
- while not TableData.EOF do
- begin
- case Typ of
- stBestScores: begin
- Stat := TStatResultBestScores.Create;
- with TStatResultBestScores(Stat) do
- begin
- Singer := UTF8Decode(TableData.Fields[0]);
- Difficulty := TableData.FieldAsInteger(1);
- Score := TableData.FieldAsInteger(2);
- SongArtist := UTF8Decode(TableData.Fields[3]);
- SongTitle := UTF8Decode(TableData.Fields[4]);
- end;
- end;
- stBestSingers: begin
- Stat := TStatResultBestSingers.Create;
- with TStatResultBestSingers(Stat) do
- begin
- Player := UTF8Decode(TableData.Fields[0]);
- AverageScore := TableData.FieldAsInteger(1);
- end;
- end;
- stMostSungSong: begin
- Stat := TStatResultMostSungSong.Create;
- with TStatResultMostSungSong(Stat) do
- begin
- Artist := UTF8Decode(TableData.Fields[0]);
- Title := UTF8Decode(TableData.Fields[1]);
- TimesSung := TableData.FieldAsInteger(2);
- end;
- end;
- stMostPopBand: begin
- Stat := TStatResultMostPopBand.Create;
- with TStatResultMostPopBand(Stat) do
- begin
- ArtistName := UTF8Decode(TableData.Fields[0]);
- TimesSungTot := TableData.FieldAsInteger(1);
- end;
- end
- else
- Log.LogCritical('Unknown stat-type', 'TDataBaseSystem.GetStats');
- end;
-
- Stat.Typ := Typ;
- Result.Add(Stat);
-
- TableData.Next;
- end;
-
- TableData.Free;
-end;
-
-procedure TDataBaseSystem.FreeStats(StatList: TList);
-var
- I: integer;
-begin
- if (StatList = nil) then
- Exit;
- for I := 0 to StatList.Count-1 do
- TStatResult(StatList[I]).Free;
- StatList.Free;
-end;
-
-(**
- * Gets total number of entrys for a stats query
- *)
-function TDataBaseSystem.GetTotalEntrys(Typ: TStatType): Cardinal;
-var
- Query: String;
-begin
- Result := 0;
-
- if not Assigned(ScoreDB) then
- Exit;
-
- try
- // Create query
- case Typ of
- stBestScores:
- Query := 'SELECT COUNT([SongID]) FROM ['+cUS_Scores+'];';
- stBestSingers:
- Query := 'SELECT COUNT(DISTINCT [Player]) FROM ['+cUS_Scores+'];';
- stMostSungSong:
- Query := 'SELECT COUNT([ID]) FROM ['+cUS_Songs+'];';
- stMostPopBand:
- Query := 'SELECT COUNT(DISTINCT [Artist]) FROM ['+cUS_Songs+'];';
- end;
-
- Result := ScoreDB.GetTableValue(Query);
- except on E: Exception do
- Log.LogError(E.Message, 'TDataBaseSystem.GetTotalEntrys');
- end;
-
-end;
-
-(**
- * Gets reset date of statistic data
- *)
-function TDataBaseSystem.GetStatReset: TDateTime;
-var
- Query: string;
- ResetTime: int64;
-begin
- Result := 0;
-
- if not Assigned(ScoreDB) then
- Exit;
-
- try
- Query := 'SELECT [ResetTime] FROM ['+cUS_Statistics_Info+'];';
- Result := UnixToDateTime(ScoreDB.GetTableValue(Query));
- except on E: Exception do
- Log.LogError(E.Message, 'TDataBaseSystem.GetStatReset');
- end;
-end;
-
-function TDataBaseSystem.GetVersion(): integer;
-begin
- Result := ScoreDB.GetTableValue('PRAGMA user_version');
-end;
-
-procedure TDataBaseSystem.SetVersion(Version: integer);
-begin
- ScoreDB.ExecSQL(Format('PRAGMA user_version = %d', [Version]));
-end;
-
-end.
diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas
deleted file mode 100644
index ff0920f5..00000000
--- a/Game/Code/Classes/UDraw.pas
+++ /dev/null
@@ -1,1390 +0,0 @@
-unit UDraw;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UThemes,
- ModiSDK,
- UGraphicClasses;
-
-procedure SingDraw;
-procedure SingModiDraw (PlayerInfo: TPlayerInfo);
-procedure SingDrawBackground;
-procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
-procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
-procedure SingDrawLyricHelper(Left, LyricsMid: real);
-procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer);
-procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
-procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer);
-procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer);
-
-// TimeBar
-procedure SingDrawTimeBar();
-
-//Draw Editor NoteLines
-procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
-
-
-type
- TRecR = record
- Top: real;
- Left: real;
- Right: real;
- Bottom: real;
-
- Width: real;
- WMid: real;
- Height: real;
- HMid: real;
-
- Mid: real;
- end;
-
-var
- NotesW: real;
- NotesH: real;
- Starfr: integer;
- StarfrG: integer;
-
- //SingBar
- TickOld: cardinal;
- TickOld2:cardinal;
-
-const
- Przedz = 32;
-
-implementation
-
-uses
- gl,
- UGraphic,
- SysUtils,
- UMusic,
- URecord,
- ULog,
- UScreenSing,
- UScreenSingModi,
- ULyrics,
- UMain,
- TextGL,
- UTexture,
- UDrawTexture,
- UIni,
- Math,
- UDLLManager;
-
-procedure SingDrawBackground;
-var
- Rec: TRecR;
- TexRec: TRecR;
-begin
- if (ScreenSing.Tex_Background.TexNum > 0) then begin
-
- glClearColor (1, 1, 1, 1);
- glColor4f (1, 1, 1, 1);
-
- if (Ini.MovieSize <= 1) then //HalfSize BG
- begin
- (* half screen + gradient *)
- Rec.Top := 110; // 80
- Rec.Bottom := Rec.Top + 20;
- Rec.Left := 0;
- Rec.Right := 800;
-
- TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- TexRec.Left := 0;
- TexRec.Right := ScreenSing.Tex_Background.TexW;
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- (* gradient draw *)
- (* top *)
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glColor4f(1, 1, 1, 1);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
- (* mid *)
- Rec.Top := Rec.Bottom;
- Rec.Bottom := 490 - 20; // 490 - 20
- TexRec.Top := TexRec.Bottom;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- (* bottom *)
- Rec.Top := Rec.Bottom;
- Rec.Bottom := 490; // 490
- TexRec.Top := TexRec.Bottom;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
-
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- end
- else //Full Size BG
- begin
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
- //glEnable(GL_BLEND);
- glBegin(GL_QUADS);
-
- glTexCoord2f(0, 0); glVertex2f(0, 0);
- glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600);
- glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600);
- glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0);
-
- glEnd;
- glDisable(GL_TEXTURE_2D);
- //glDisable(GL_BLEND);
- end;
- end;
-end;
-
-procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
-var
- SampleIndex: integer;
- Sound: TCaptureBuffer;
- MaxX, MaxY: real;
-begin;
- Sound := AudioInputProcessor.Sound[NrSound];
-
- // Log.LogStatus('Oscilloscope', 'SingDraw');
- glColor3f(Skin_OscR, Skin_OscG, Skin_OscB);
- {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
- glColor3f(1, 1, 1); }
-
- MaxX := W-1;
- MaxY := (H-1) / 2;
-
- Sound.LockAnalysisBuffer();
-
- glBegin(GL_LINE_STRIP);
- for SampleIndex := 0 to High(Sound.AnalysisBuffer) do
- begin
- glVertex2f(X + MaxX * SampleIndex/High(Sound.AnalysisBuffer),
- Y + MaxY * (1 - Sound.AnalysisBuffer[SampleIndex]/-Low(Smallint)));
- end;
- glEnd;
-
- Sound.UnlockAnalysisBuffer();
-end;
-
-
-
-procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
-var
- Count: integer;
-begin
- glEnable(GL_BLEND);
- glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4);
- glBegin(GL_LINES);
- for Count := 0 to 9 do begin
- glVertex2f(Left, Top + Count * Space);
- glVertex2f(Right, Top + Count * Space);
- end;
- glEnd;
- glDisable(GL_BLEND);
-end;
-
-procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer);
-var
- Count: integer;
- TempR: real;
-begin
- TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
- glEnable(GL_BLEND);
- glBegin(GL_LINES);
- for Count := Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start to Lines[NrLines].Line[Lines[NrLines].Current].End_ do begin
- if (Count mod Lines[NrLines].Resolution) = Lines[NrLines].NotesGAP then
- glColor4f(0, 0, 0, 1)
- else
- glColor4f(0, 0, 0, 0.3);
- glVertex2f(Left + TempR * (Count - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start), Top);
- glVertex2f(Left + TempR * (Count - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start), Top + 135);
- end;
- glEnd;
- glDisable(GL_BLEND);
-end;
-
-// draw blank Notebars
-procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
-var
- Rec: TRecR;
- Count: integer;
- TempR: real;
- R,G,B: real;
-
- PlayerNumber: Integer;
-
- GoldenStarPos : real;
-
- lTmpA ,
- lTmpB : real;
-begin
-// We actually don't have a playernumber in this procedure, it should reside in NrLines - but it's always set to zero
-// So we exploit this behavior a bit - we give NrLines the playernumber, keep it in playernumber - and then we set NrLines to zero
-// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then
-// BUT this is not implemented yet, all notes are drawn! :D
-
- PlayerNumber := NrLines + 1; // Player 1 is 0
- NrLines := 0;
-
-// exploit done
-
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- lTmpA := (Right-Left);
- lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
-
- if ( lTmpA > 0 ) AND
- ( lTmpB > 0 ) THEN
- begin
- TempR := lTmpA / lTmpB;
- end
- else
- begin
- TempR := 0;
- end;
-
-
- with Lines[NrLines].Line[Lines[NrLines].Current] do begin
- for Count := 0 to HighNote do begin
- with Note[Count] do begin
- if NoteType <> ntFreestyle then begin
-
-
- if Ini.EffectSing = 0 then
- // If Golden note Effect of then Change not Color
- begin
- case NoteType of
- ntNormal: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
- ntGolden: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could
- end; // case
- end //Else all Notes same Color
- else
- glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
- // Czesci == teil, element == piece, element | koniec == end / ending
- // lewa czesc - left part
- Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
- Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
- Rec.Bottom := Rec.Top + 2 * NotesH;
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- //We keep the postion of the top left corner b4 it's overwritten
- GoldenStarPos := Rec.Left;
- //done
-
- // srodkowa czesc - middle part
- Rec.Left := Rec.Right;
- Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == length
-
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum);
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc - right part
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Golden Star Patch
- if (NoteType = ntGolden) AND (Ini.EffectSing=1) then
- begin
- GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom);
- end;
-
- end; // if not FreeStyle
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-
-// draw sung notes
-procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer);
-var
- TempR: real;
- Rec: TRecR;
- N: integer;
- R, G, B, A: real;
- NotesH2: real;
-begin
- //Log.LogStatus('Player notes', 'SingDraw');
-
- //if NrGracza = 0 then LoadColor(R, G, B, 'P1Light')
- //else LoadColor(R, G, B, 'P2Light');
-
- //R := 71/255;
- //G := 175/255;
- //B := 247/255;
-
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- //if Player[NrGracza].LengthNote > 0 then
- begin
- TempR := W / (Lines[0].Line[Lines[0].Current].End_ - Lines[0].Line[Lines[0].Current].Note[0].Start);
- for N := 0 to Player[PlayerIndex].HighNote do
- begin
- with Player[PlayerIndex].Note[N] do
- begin
- // Left part of note
- Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
-
- // Draw it in half size, if not hit
- if Hit then
- begin
- NotesH2 := NotesH
- end
- else
- begin
- NotesH2 := int(NotesH * 0.65);
- end;
-
- Rec.Top := Y - (Tone-Lines[0].Line[Lines[0].Current].BaseNote)*Space/2 - NotesH2;
- Rec.Bottom := Rec.Top + 2 *NotesH2;
-
- // draw the left part
- glColor3f(1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, Tex_Left[PlayerIndex+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Middle part of the note
- Rec.Left := Rec.Right;
- Rec.Right := X + (Start+Length-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR - NotesW - 0.5 + 10*ScreenX;
-
- // (nowe) - dunno
- if (Start+Length-1 = LyricsState.CurrentBeatD) then
- Rec.Right := Rec.Right - (1-Frac(LyricsState.MidBeatD)) * TempR;
- // the left note is more right than the right note itself, sounds weird - so we fix that xD
- if Rec.Right <= Rec.Left then
- Rec.Right := Rec.Left;
-
- // draw the middle part
- glBindTexture(GL_TEXTURE_2D, Tex_Mid[PlayerIndex+1].TexNum);
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- glColor3f(1, 1, 1);
-
- // the right part of the note
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Right[PlayerIndex+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Perfect note is stored
- if Perfect and (Ini.EffectSing=1) then
- begin
- A := 1 - 2*(LyricsState.GetCurrentTime() - GetTimeFromBeat(Start+Length));
- if not (Start+Length-1 = LyricsState.CurrentBeatD) then
- begin
- //Star animation counter
- //inc(Starfr);
- //Starfr := Starfr mod 128;
- GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top);
- end;
- end;
- end; // with
- end; // for
-
- // actually we need a comparison here, to determine if the singing process
- // is ahead Rec.Right even if there is no singing
-
- if (Ini.EffectSing = 1) then
- GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, PlayerIndex);
- end; // if
-end;
-
-//draw Note glow
-procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer);
-var
- Rec: TRecR;
- Count: integer;
- TempR: real;
- R,G,B: real;
- X1, X2, X3, X4: real;
- W, H: real;
-
- lTmpA ,
- lTmpB : real;
-begin
- if (Player[PlayerIndex].ScoreTotalInt >= 0) then
- begin
- glColor4f(1, 1, 1, sqrt((1+sin( AudioPlayback.Position * 3))/4)/ 2 + 0.5 );
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- lTmpA := (Right-Left);
- lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
-
- if ( lTmpA > 0 ) and
- ( lTmpB > 0 ) then
- begin
- TempR := lTmpA / lTmpB;
- end
- else
- begin
- TempR := 0;
- end;
-
- with Lines[NrLines].Line[Lines[NrLines].Current] do
- begin
- for Count := 0 to HighNote do
- begin
- with Note[Count] do
- begin
- if NoteType <> ntFreestyle then
- begin
- // begin: 14, 20
- // easy: 6, 11
- W := NotesW * 2 + 2;
- H := NotesH * 1.5 + 3.5;
-
- X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie
- X1 := X2-W;
-
- X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie
- X4 := X3+W;
-
- // left
- Rec.Left := X1;
- Rec.Right := X2;
- Rec.Top := Top - (Tone-BaseNote)*Space/2 - H;
- Rec.Bottom := Rec.Top + 2 * H;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[PlayerIndex+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // srodkowa czesc
- Rec.Left := X2;
- Rec.Right := X3;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[PlayerIndex+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc
- Rec.Left := X3;
- Rec.Right := X4;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[PlayerIndex+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- end; // if not FreeStyle
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end;
-end;
-
-(**
- * Draws the lyrics helper bar.
- * Left: position the bar starts at
- * LyricsMid: the middle of the lyrics relative to the position Left
- *)
-procedure SingDrawLyricHelper(Left, LyricsMid: real);
-var
- Bounds: TRecR; // bounds of the lyric help bar
- BarProgress: real; // progress of the lyrics helper
- BarMoveDelta: real; // current beat relative to the beat the bar starts to move at
- BarAlpha: real; // transparency
- CurLine: PLine; // current lyric line (beat specific)
- LineWidth: real; // lyric line width
- FirstNoteBeat: integer; // beat of the first note in the current line
- FirstNoteDelta: integer; // time in beats between the start of the current line and its first note
- MoveStartX: real; // x-pos. the bar starts to move from
- MoveDist: real; // number of pixels the bar will move
- LyricEngine: TLyricEngine;
-const
- BarWidth = 50; // width of the lyric helper bar
- BarHeight = 30; // height of the lyric helper bar
- BarMoveLimit = 40; // max. number of beats remaining before the bar starts to move
-begin
- // get current lyrics line and the time in beats of its first note
- CurLine := @Lines[0].Line[Lines[0].Current];
-
- // FIXME: accessing ScreenSing is not that generic
- LyricEngine := ScreenSing.Lyrics;
-
- // do not draw the lyrics helper if the current line does not contain any note
- if (Length(CurLine.Note) > 0) then
- begin
- // start beat of the first note of this line
- FirstNoteBeat := CurLine.Note[0].Start;
- // time in beats between the start of the current line and its first note
- FirstNoteDelta := FirstNoteBeat - CurLine.Start;
-
- // beats from current beat to the first note of the line
- BarMoveDelta := FirstNoteBeat - LyricsState.MidBeat;
-
- if (FirstNoteDelta > 8) and // if the wait-time is large enough
- (BarMoveDelta > 0) then // and the first note of the line is not reached
- begin
- // let the bar blink to the beat
- BarAlpha := 0.75 + cos(BarMoveDelta/2) * 0.25;
-
- // if the number of beats to the first note is too big,
- // the bar stays on the left side.
- if (BarMoveDelta > BarMoveLimit) then
- BarMoveDelta := BarMoveLimit;
-
- // limit number of beats the bar moves
- if (FirstNoteDelta > BarMoveLimit) then
- FirstNoteDelta := BarMoveLimit;
-
- // calc bar progress
- BarProgress := 1 - BarMoveDelta / FirstNoteDelta;
-
- // retrieve the width of the upper lyrics line on the display
- if (LyricEngine.GetUpperLine() <> nil) then
- LineWidth := LyricEngine.GetUpperLine().Width
- else
- LineWidth := 0;
-
- // distance the bar will move (LyricRec.Left to beginning of text)
- MoveDist := LyricsMid - LineWidth / 2 - BarWidth;
- // if the line is too long the helper might move from right to left
- // so we have to assure the start position is left of the text.
- if (MoveDist >= 0) then
- MoveStartX := Left
- else
- MoveStartX := Left + MoveDist;
-
- // determine lyric help bar position and size
- Bounds.Left := MoveStartX + BarProgress * MoveDist;
- Bounds.Right := Bounds.Left + BarWidth;
- Bounds.Top := Skin_LyricsT + 3;
- Bounds.Bottom := Bounds.Top + BarHeight + 3;
-
- // draw lyric help bar
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glColor4f(1, 1, 1, BarAlpha);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Bounds.Left, Bounds.Top);
- glTexCoord2f(0, 1); glVertex2f(Bounds.Left, Bounds.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Bounds.Right, Bounds.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Bounds.Right, Bounds.Top);
- glEnd;
- glDisable(GL_BLEND);
- end;
- end;
-end;
-
-procedure SingDraw;
-var
- NR: TRecR; // lyrics area bounds (NR = NoteRec?)
- LyricEngine: TLyricEngine;
-begin
- // positions
- if Ini.SingWindow = 0 then
- NR.Left := 120
- else
- NR.Left := 20;
-
- NR.Right := 780;
-
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- // FIXME: accessing ScreenSing is not that generic
- LyricEngine := ScreenSing.Lyrics;
-
- // background //BG Fullsize Mod
- //SingDrawBackground;
-
- // draw time-bar
- SingDrawTimeBar();
-
- // draw note-lines
-
- if (PlayersPlay = 1) and (Ini.NoteLines = 1) then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
-
- if ((PlayersPlay = 2) or (PlayersPlay = 4)) and (Ini.NoteLines = 1) then
- begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- end;
-
- if ((PlayersPlay = 3) or (PlayersPlay = 6)) and (Ini.NoteLines = 1) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
- end;
-
- // draw Lyrics
- LyricEngine.Draw(LyricsState.MidBeat);
- SingDrawLyricHelper(NR.Left, NR.WMid);
-
- // oscilloscope
- if Ini.Oscilloscope = 1 then begin
- if PlayersPlay = 1 then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
-
- if PlayersPlay = 2 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
- if ScreenAct = 2 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
- end;
- end;
-
- if PlayersPlay = 3 then begin
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
- if ScreenAct = 2 then begin
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
- end;
- end;
-
- end;
-
- // Set the note heights according to the difficulty level
- case Ini.Difficulty of
- 0:
- begin
- NotesH := 11; // 9
- NotesW := 6; // 5
- end;
- 1:
- begin
- NotesH := 8; // 7
- NotesW := 4; // 4
- end;
- 2:
- begin
- NotesH := 5;
- NotesW := 3;
- end;
- end;
-
- // Draw the Notes
- if PlayersPlay = 1 then begin
- SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes
- end;
-
- if (PlayersPlay = 2) then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
-
- SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
-
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
-
- if PlayersPlay = 3 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
-
- SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
- SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
-
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
- SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 3, 12);
- SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 4, 12);
- SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 5, 12);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
- end;
- end;
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-// q'n'd for using the game mode dll's
-procedure SingModiDraw (PlayerInfo: TPlayerInfo);
-var
- Count: integer;
- Pet2: integer;
- TempR: real;
- Rec: TRecR;
- TexRec: TRecR;
- NR: TRecR;
- FS: real;
- BarFrom: integer;
- BarAlpha: real;
- BarWspol: real;
- TempCol: real;
- Tekst: string;
- PetCz: integer;
-begin
- // positions
- if Ini.SingWindow = 0 then begin
- NR.Left := 120;
- end else begin
- NR.Left := 20;
- end;
-
- NR.Right := 780;
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- // time bar
- SingDrawTimeBar();
-
- if DLLMan.Selected.ShowNotes then
- begin
- if PlayersPlay = 1 then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- end;
-
- if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
- end;
- end;
-
- // Draw Lyrics
- ScreenSingModi.Lyrics.Draw(LyricsState.MidBeat);
-
- // todo: Lyrics
-{ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
- FS := 1.3;
- BarFrom := Lines[0].Line[Lines[0].Current].StartNote - Lines[0].Line[Lines[0].Current].Start;
- if BarFrom > 40 then BarFrom := 40;
- if (Lines[0].Line[Lines[0].Current].StartNote - Lines[0].Line[Lines[0].Current].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
- (Lines[0].Line[Lines[0].Current].StartNote - LyricsState.MidBeat > 0) and // przed tekstem
- (Lines[0].Line[Lines[0].Current].StartNote - LyricsState.MidBeat < 40) then begin // ale nie za wczesnie
- BarWspol := (LyricsState.MidBeat - (Lines[0].Line[Lines[0].Current].StartNote - BarFrom)) / BarFrom;
- Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
- Rec.Right := Rec.Left + 50;
- Rec.Top := Skin_LyricsT + 3;
- Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
- glBegin(GL_QUADS);
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glColor4f(1, 1, 1, 0.5);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- glDisable(GL_BLEND);
- end;
- }
-
- // oscilloscope | the thing that moves when you yell into your mic (imho)
- if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin
- if PlayersPlay = 1 then
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
-
- if PlayersPlay = 2 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
- end;
- end;
-
- if PlayersPlay = 3 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
- if PlayerInfo.Playerinfo[4].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
- if PlayerInfo.Playerinfo[5].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
- end;
- end;
-
- end;
-
-// resize the notes according to the difficulty level
- case Ini.Difficulty of
- 0:
- begin
- NotesH := 11; // 9
- NotesW := 6; // 5
- end;
- 1:
- begin
- NotesH := 8; // 7
- NotesW := 4; // 4
- end;
- 2:
- begin
- NotesH := 5;
- NotesW := 3;
- end;
- end;
-
- if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then
- begin
- if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin
- SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
- end;
-
- if (PlayersPlay = 2) then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- end;
- if PlayerInfo.Playerinfo[1].Enabled then
- begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
-
- end;
-
- if PlayersPlay = 3 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if PlayerInfo.Playerinfo[0].Enabled then
- begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- end;
-
- if PlayerInfo.Playerinfo[1].Enabled then
- begin
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- end;
-
- if PlayerInfo.Playerinfo[2].Enabled then
- begin
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
- end;
-
- SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
-
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
- end;
-
- SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
- SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
-
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
- end;
- end;
- end;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-
-{//SingBar Mod
-procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
-var
- R: Real;
- G: Real;
- B: Real;
- A: cardinal;
- I: Integer;
-
-begin;
-
- //SingBar Background
- glColor4f(1, 1, 1, 0.8);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+W, Y);
- glEnd;
-
- //SingBar coloured Bar
- Case Percent of
- 0..22: begin
- R := 1;
- G := 0;
- B := 0;
- end;
- 23..42: begin
- R := 1;
- G := ((Percent-23)/100)*5;
- B := 0;
- end;
- 43..57: begin
- R := 1;
- G := 1;
- B := 0;
- end;
- 58..77: begin
- R := 1-(Percent - 58)/100*5;
- G := 1;
- B := 0;
- end;
- 78..99: begin
- R := 0;
- G := 1;
- B := 0;
- end;
- End; //Case
-
- glColor4f(R, G, B, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum);
- //Size= Player[PlayerNum].ScorePercent of W
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y);
- glEnd;
-
- //SingBar Front
- glColor4f(1, 1, 1, 0.6);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+W, Y);
- glEnd;
-end;
-//end Singbar Mod
-
-//PhrasenBonus - Line Bonus Pop Up
-procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
-var
-Length, X2: Real; //Length of Text
-Size: Integer; //Size of Popup
-begin
-if Alpha <> 0 then
-begin
-
-//Set Font Propertys
-SetFontStyle(2); //Font: Outlined1
-if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6);
-SetFontItalic(False);
-
-//Check Font Size
-Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^
-
-//Text
-SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
-
-
-if Age < 5 then Size := Age * 10 else Size := 50;
-
- //Draw Background
- //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
- glColor4f(1, 1, 1, Alpha);
-
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-
- //New Method, Not Variable
- glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
- glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
- glEnd;
-
- glColor4f(1, 1, 1, Alpha); //Set Color
- //Draw Text
- glPrint (PChar(Text));
-end;
-end;
-//PhrasenBonus - Line Bonus Mod}
-
-// Draw Note Bars for Editor
-//There are 11 Resons for a new Procdedure: (nice binary :D )
-// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor
-// 2. You can see the Freestyle Notes in the Editor SemiTransparent
-// 3. Its easier and Faster then changing the old Procedure
-procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
-var
- Rec: TRecR;
- Count: integer;
- TempR: real;
-begin
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
- with Lines[NrLines].Line[Lines[NrLines].Current] do begin
- for Count := 0 to HighNote do begin
- with Note[Count] do begin
-
- // Golden Note Patch
- case NoteType of
- ntFreestyle: glColor4f(1, 1, 1, 0.35);
- ntNormal: glColor4f(1, 1, 1, 0.85);
- ntGolden: Glcolor4f(1, 1, 0.3, 0.85);
- end; // case
-
-
-
- // lewa czesc - left part
- Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
- Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
- Rec.Bottom := Rec.Top + 2 * NotesH;
- glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // srodkowa czesc - middle part
- Rec.Left := Rec.Right;
- Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc - right part
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-procedure SingDrawTimeBar();
-var
- x,y: real;
- width, height: real;
- LyricsProgress: real;
- CurLyricsTime: real;
-begin
- x := Theme.Sing.StaticTimeProgress.x;
- y := Theme.Sing.StaticTimeProgress.y;
-
- width := Theme.Sing.StaticTimeProgress.w;
- height := Theme.Sing.StaticTimeProgress.h;
-
- glColor4f(Theme.Sing.StaticTimeProgress.ColR,
- Theme.Sing.StaticTimeProgress.ColG,
- Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(x, y);
-
- CurLyricsTime := LyricsState.GetCurrentTime();
- if (CurLyricsTime > 0) and
- (LyricsState.TotalTime > 0) then
- begin
- LyricsProgress := CurLyricsTime / LyricsState.TotalTime;
- glTexCoord2f((width * LyricsProgress) / 8, 0);
- glVertex2f(x + width * LyricsProgress, y);
-
- glTexCoord2f((width * LyricsProgress) / 8, 1);
- glVertex2f(x + width * LyricsProgress, y + height);
- end;
-
- glTexCoord2f(0, 1);
- glVertex2f(x, y + height);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glcolor4f(1, 1, 1, 1);
-end;
-
-end.
-
diff --git a/Game/Code/Classes/UEditorLyrics.pas b/Game/Code/Classes/UEditorLyrics.pas
deleted file mode 100644
index 25e8423e..00000000
--- a/Game/Code/Classes/UEditorLyrics.pas
+++ /dev/null
@@ -1,229 +0,0 @@
-unit UEditorLyrics;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SysUtils,
- gl,
- UMusic,
- UTexture;
-
-type
- TWord = record
- X: real;
- Y: real;
- Size: real;
- Width: real;
- Text: string;
- ColR: real;
- ColG: real;
- ColB: real;
- FontStyle: integer;
- Italic: boolean;
- Selected: boolean;
- end;
-
- TEditorLyrics = class
- private
- AlignI: integer;
- XR: real;
- YR: real;
- SizeR: real;
- SelectedI: integer;
- FontStyleI: integer; // font number
- Word: array of TWord;
-
- procedure SetX(Value: real);
- procedure SetY(Value: real);
- function GetClientX: real;
- procedure SetAlign(Value: integer);
- function GetSize: real;
- procedure SetSize(Value: real);
- procedure SetSelected(Value: integer);
- procedure SetFStyle(Value: integer);
- procedure AddWord(Text: string);
- procedure Refresh;
- public
- ColR: real;
- ColG: real;
- ColB: real;
- ColSR: real;
- ColSG: real;
- ColSB: real;
- Italic: boolean;
-
- constructor Create;
- destructor Destroy; override;
-
- procedure AddLine(NrLine: integer);
-
- procedure Clear;
- procedure Draw;
- published
- property X: real write SetX;
- property Y: real write SetY;
- property ClientX: real read GetClientX;
- property Align: integer write SetAlign;
- property Size: real read GetSize write SetSize;
- property Selected: integer read SelectedI write SetSelected;
- property FontStyle: integer write SetFStyle;
- end;
-
-implementation
-
-uses
- TextGL, UGraphic, UDrawTexture, Math, USkins;
-
-constructor TEditorLyrics.Create;
-begin
- inherited;
-end;
-
-destructor TEditorLyrics.Destroy;
-begin
- SetLength(Word, 0);
- inherited;
-end;
-
-procedure TEditorLyrics.SetX(Value: real);
-begin
- XR := Value;
-end;
-
-procedure TEditorLyrics.SetY(Value: real);
-begin
- YR := Value;
-end;
-
-function TEditorLyrics.GetClientX: real;
-begin
- Result := Word[0].X;
-end;
-
-procedure TEditorLyrics.SetAlign(Value: integer);
-begin
- AlignI := Value;
-end;
-
-function TEditorLyrics.GetSize: real;
-begin
- Result := SizeR;
-end;
-
-procedure TEditorLyrics.SetSize(Value: real);
-begin
- SizeR := Value;
-end;
-
-procedure TEditorLyrics.SetSelected(Value: integer);
-var
- W: integer;
-begin
- if (SelectedI > -1) and (SelectedI <= High(Word)) then
- begin
- Word[SelectedI].Selected := false;
- Word[SelectedI].ColR := ColR;
- Word[SelectedI].ColG := ColG;
- Word[SelectedI].ColB := ColB;
- end;
-
- SelectedI := Value;
- if (Value > -1) and (Value <= High(Word)) then
- begin
- Word[Value].Selected := true;
- Word[Value].ColR := ColSR;
- Word[Value].ColG := ColSG;
- Word[Value].ColB := ColSB;
- end;
-
- Refresh;
-end;
-
-procedure TEditorLyrics.SetFStyle(Value: integer);
-begin
- FontStyleI := Value;
-end;
-
-procedure TEditorLyrics.AddWord(Text: string);
-var
- WordNum: integer;
-begin
- WordNum := Length(Word);
- SetLength(Word, WordNum + 1);
- if WordNum = 0 then begin
- Word[WordNum].X := XR;
- end else begin
- Word[WordNum].X := Word[WordNum - 1].X + Word[WordNum - 1].Width;
- end;
-
- Word[WordNum].Y := YR;
- Word[WordNum].Size := SizeR;
- Word[WordNum].FontStyle := FontStyleI;
- SetFontStyle(FontStyleI);
- SetFontSize(SizeR);
- Word[WordNum].Width := glTextWidth(pchar(Text));
- Word[WordNum].Text := Text;
- Word[WordNum].ColR := ColR;
- Word[WordNum].ColG := ColG;
- Word[WordNum].ColB := ColB;
- Word[WordNum].Italic := Italic;
-
- Refresh;
-end;
-
-procedure TEditorLyrics.AddLine(NrLine: integer);
-var
- N: integer;
-begin
- Clear;
- for N := 0 to Lines[0].Line[NrLine].HighNote do begin
- Italic := Lines[0].Line[NrLine].Note[N].NoteType = ntFreestyle;
- AddWord(Lines[0].Line[NrLine].Note[N].Text);
- end;
- Selected := -1;
-end;
-
-procedure TEditorLyrics.Clear;
-begin
- SetLength(Word, 0);
- SelectedI := -1;
-end;
-
-procedure TEditorLyrics.Refresh;
-var
- W: integer;
- TotWidth: real;
-begin
- if AlignI = 1 then begin
- TotWidth := 0;
- for W := 0 to High(Word) do
- TotWidth := TotWidth + Word[W].Width;
-
- Word[0].X := XR - TotWidth / 2;
- for W := 1 to High(Word) do
- Word[W].X := Word[W - 1].X + Word[W - 1].Width;
- end;
-end;
-
-procedure TEditorLyrics.Draw;
-var
- W: integer;
-begin
- for W := 0 to High(Word) do
- begin
- SetFontStyle(Word[W].FontStyle);
- SetFontPos(Word[W].X+ 10*ScreenX, Word[W].Y);
- SetFontSize(Word[W].Size);
- SetFontItalic(Word[W].Italic);
- glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
- glPrint(pchar(Word[W].Text));
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas
deleted file mode 100644
index ca43bb21..00000000
--- a/Game/Code/Classes/UFiles.pas
+++ /dev/null
@@ -1,150 +0,0 @@
-unit UFiles;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-{$I switches.inc}
-
-uses SysUtils,
- ULog,
- UMusic,
- USongs,
- USong;
-
-procedure ResetSingTemp;
-function SaveSong(Song: TSong; Lines: TLines; Name: string; Relative: boolean): boolean;
-
-var
- SongFile: TextFile; // all procedures in this unit operates on this file
- FileLineNo: integer; //Line which is readed at Last, for error reporting
-
- // variables available for all procedures
- Base : array[0..1] of integer;
- Rel : array[0..1] of integer;
- Mult : integer = 1;
- MultBPM : integer = 4;
-
-implementation
-
-uses TextGL,
- UIni,
- UPlatform,
- UMain;
-
-//--------------------
-// Resets the temporary Sentence Arrays for each Player and some other Variables
-//--------------------
-procedure ResetSingTemp;
-var
- Count: integer;
-begin
- SetLength(Lines, Length(Player));
- for Count := 0 to High(Player) do begin
- SetLength(Lines[Count].Line, 1);
- SetLength(Lines[Count].Line[0].Note, 0);
- Lines[Count].Line[0].Lyric := '';
- Lines[Count].Line[0].LyricWidth := 0;
- Player[Count].Score := 0;
- Player[Count].LengthNote := 0;
- Player[Count].HighNote := -1;
- end;
-
- (* FIXME
- //Reset Path and Filename Values to Prevent Errors in Editor
- if assigned( CurrentSong ) then
- begin
- SetLength(CurrentSong.BPM, 0);
- CurrentSong.Path := '';
- CurrentSong.FileName := '';
- end;
- *)
-
-// CurrentSong := nil;
-end;
-
-
-//--------------------
-// Saves a Song
-//--------------------
-function SaveSong(Song: TSong; Lines: TLines; Name: string; Relative: boolean): boolean;
-var
- C: integer;
- N: integer;
- S: string;
- B: integer;
- RelativeSubTime: integer;
- NoteState: String;
-
-begin
-// Relative := true; // override (idea - use shift+S to save with relative)
- AssignFile(SongFile, Name);
- Rewrite(SongFile);
-
- Writeln(SongFile, '#TITLE:' + Song.Title + '');
- Writeln(SongFile, '#ARTIST:' + Song.Artist);
-
- if Song.Creator <> '' then Writeln(SongFile, '#CREATOR:' + Song.Creator);
- if Song.Edition <> 'Unknown' then Writeln(SongFile, '#EDITION:' + Song.Edition);
- if Song.Genre <> 'Unknown' then Writeln(SongFile, '#GENRE:' + Song.Genre);
- if Song.Language <> 'Unknown' then Writeln(SongFile, '#LANGUAGE:' + Song.Language);
-
- Writeln(SongFile, '#MP3:' + Song.Mp3);
-
- if Song.Cover <> '' then Writeln(SongFile, '#COVER:' + Song.Cover);
- if Song.Background <> '' then Writeln(SongFile, '#BACKGROUND:' + Song.Background);
- if Song.Video <> '' then Writeln(SongFile, '#VIDEO:' + Song.Video);
- if Song.VideoGAP <> 0 then Writeln(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP));
- if Song.Resolution <> 4 then Writeln(SongFile, '#RESOLUTION:' + IntToStr(Song.Resolution));
- if Song.NotesGAP <> 0 then Writeln(SongFile, '#NOTESGAP:' + IntToStr(Song.NotesGAP));
- if Song.Start <> 0 then Writeln(SongFile, '#START:' + FloatToStr(Song.Start));
- if Song.Finish <> 0 then Writeln(SongFile, '#END:' + IntToStr(Song.Finish));
- if Relative then Writeln(SongFile, '#RELATIVE:yes');
-
- Writeln(SongFile, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4));
- Writeln(SongFile, '#GAP:' + FloatToStr(Song.GAP));
-
- RelativeSubTime := 0;
- for B := 1 to High(CurrentSong.BPM) do
- Writeln(SongFile, 'B ' + FloatToStr(CurrentSong.BPM[B].StartBeat) + ' ' + FloatToStr(CurrentSong.BPM[B].BPM/4));
-
- for C := 0 to Lines.High do begin
- for N := 0 to Lines.Line[C].HighNote do begin
- with Lines.Line[C].Note[N] do begin
-
-
- //Golden + Freestyle Note Patch
- case Lines.Line[C].Note[N].NoteType of
- ntFreestyle: NoteState := 'F ';
- ntNormal: NoteState := ': ';
- ntGolden: NoteState := '* ';
- end; // case
- S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Length) + ' ' + IntToStr(Tone) + ' ' + Text;
-
-
- Writeln(SongFile, S);
- end; // with
- end; // N
-
- if C < Lines.High then begin // don't write end of last sentence
- if not Relative then
- S := '- ' + IntToStr(Lines.Line[C+1].Start)
- else begin
- S := '- ' + IntToStr(Lines.Line[C+1].Start - RelativeSubTime) +
- ' ' + IntToStr(Lines.Line[C+1].Start - RelativeSubTime);
- RelativeSubTime := Lines.Line[C+1].Start;
- end;
- Writeln(SongFile, S);
- end;
-
- end; // C
-
-
- Writeln(SongFile, 'E');
- CloseFile(SongFile);
-
- Result := true;
-end;
-
-end.
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
deleted file mode 100644
index 2432503c..00000000
--- a/Game/Code/Classes/UGraphic.pas
+++ /dev/null
@@ -1,760 +0,0 @@
-unit UGraphic;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SDL,
- gl,
- glext,
- UTexture,
- TextGL,
- ULog,
- SysUtils,
- ULyrics,
- UImage,
- UMusic,
- UScreenLoading,
- UScreenWelcome,
- UScreenMain,
- UScreenName,
- UScreenLevel,
- UScreenOptions,
- UScreenOptionsGame,
- UScreenOptionsGraphics,
- UScreenOptionsSound,
- UScreenOptionsLyrics,
- UScreenOptionsThemes,
- UScreenOptionsRecord,
- UScreenOptionsAdvanced,
- UScreenSong,
- UScreenSing,
- UScreenScore,
- UScreenTop5,
- UScreenEditSub,
- UScreenEdit,
- UScreenEditConvert,
- UScreenEditHeader,
- UScreenOpen,
- UThemes,
- USkins,
- UScreenSongMenu,
- UScreenSongJumpto,
- {Party Screens}
- UScreenSingModi,
- UScreenPartyNewRound,
- UScreenPartyScore,
- UScreenPartyOptions,
- UScreenPartyWin,
- UScreenPartyPlayer,
- {Stats Screens}
- UScreenStatMain,
- UScreenStatDetail,
- {CreditsScreen}
- UScreenCredits,
- {Popup for errors, etc.}
- UScreenPopup;
-
-type
- TRecR = record
- Top: real;
- Left: real;
- Right: real;
- Bottom: real;
- end;
-
-var
- Screen: PSDL_Surface;
- LoadingThread: PSDL_Thread;
- Mutex: PSDL_Mutex;
-
- RenderW: integer;
- RenderH: integer;
- ScreenW: integer;
- ScreenH: integer;
- Screens: integer;
- ScreenAct: integer;
- ScreenX: integer;
-
- ScreenLoading: TScreenLoading;
- ScreenWelcome: TScreenWelcome;
- ScreenMain: TScreenMain;
- ScreenName: TScreenName;
- ScreenLevel: TScreenLevel;
- ScreenSong: TScreenSong;
- ScreenSing: TScreenSing;
- ScreenScore: TScreenScore;
- ScreenTop5: TScreenTop5;
- ScreenOptions: TScreenOptions;
- ScreenOptionsGame: TScreenOptionsGame;
- ScreenOptionsGraphics: TScreenOptionsGraphics;
- ScreenOptionsSound: TScreenOptionsSound;
- ScreenOptionsLyrics: TScreenOptionsLyrics;
- ScreenOptionsThemes: TScreenOptionsThemes;
- ScreenOptionsRecord: TScreenOptionsRecord;
- ScreenOptionsAdvanced: TScreenOptionsAdvanced;
- ScreenEditSub: TScreenEditSub;
- ScreenEdit: TScreenEdit;
- ScreenEditConvert: TScreenEditConvert;
- ScreenEditHeader: TScreenEditHeader;
- ScreenOpen: TScreenOpen;
-
- ScreenSongMenu: TScreenSongMenu;
- ScreenSongJumpto: TScreenSongJumpto;
-
- //Party Screens
- ScreenSingModi: TScreenSingModi;
- ScreenPartyNewRound: TScreenPartyNewRound;
- ScreenPartyScore: TScreenPartyScore;
- ScreenPartyWin: TScreenPartyWin;
- ScreenPartyOptions: TScreenPartyOptions;
- ScreenPartyPlayer: TScreenPartyPlayer;
-
- //StatsScreens
- ScreenStatMain: TScreenStatMain;
- ScreenStatDetail: TScreenStatDetail;
-
- //CreditsScreen
- ScreenCredits: TScreenCredits;
-
- //popup mod
- ScreenPopupCheck: TScreenPopupCheck;
- ScreenPopupError: TScreenPopupError;
-
- //Notes
- Tex_Left: array[0..6] of TTexture; //rename to tex_note_left
- Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid
- Tex_Right: array[0..6] of TTexture; //rename to tex_note_right
-
- Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left
- Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid
- Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right
-
- Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left
- Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid
- Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right
-
- Tex_Note_Star: TTexture;
- Tex_Note_Perfect_Star: TTexture;
-
-
- Tex_Ball: TTexture;
- Tex_Lyric_Help_Bar: TTexture;
- FullScreen: boolean;
-
- Tex_TimeProgress: TTexture;
-
- //Sing Bar Mod
- Tex_SingBar_Back: TTexture;
- Tex_SingBar_Bar: TTexture;
- Tex_SingBar_Front: TTexture;
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- Tex_SingLineBonusBack: array[0..8] of TTexture;
- //End PhrasenBonus - Line Bonus Mod
-
- //ScoreBG Texs
- Tex_ScoreBG: array [0..5] of TTexture;
-
- //Score Screen Textures
- Tex_Score_NoteBarLevel_Dark : array [1..6] of TTexture;
- Tex_Score_NoteBarRound_Dark : array [1..6] of TTexture;
-
- Tex_Score_NoteBarLevel_Light : array [1..6] of TTexture;
- Tex_Score_NoteBarRound_Light : array [1..6] of TTexture;
-
- Tex_Score_NoteBarLevel_Lightest : array [1..6] of TTexture;
- Tex_Score_NoteBarRound_Lightest : array [1..6] of TTexture;
-
- Tex_Score_Ratings : array [0..7] of TTexture;
-
-const
- Skin_BGColorR = 1;
- Skin_BGColorG = 1;
- Skin_BGColorB = 1;
-
- Skin_SpectrumR = 0;
- Skin_SpectrumG = 0;
- Skin_SpectrumB = 0;
-
- Skin_Spectograph1R = 0.6;
- Skin_Spectograph1G = 0.8;
- Skin_Spectograph1B = 1;
-
- Skin_Spectograph2R = 0;
- Skin_Spectograph2G = 0;
- Skin_Spectograph2B = 0.2;
-
- Skin_SzczytR = 0.8;
- Skin_SzczytG = 0;
- Skin_SzczytB = 0;
-
- Skin_SzczytLimitR = 0;
- Skin_SzczytLimitG = 0.8;
- Skin_SzczytLimitB = 0;
-
- Skin_FontR = 0;
- Skin_FontG = 0;
- Skin_FontB = 0;
-
- Skin_FontHighlightR = 0.3; // 0.3
- Skin_FontHighlightG = 0.3; // 0.3
- Skin_FontHighlightB = 1; // 1
-
- Skin_TimeR = 0.25; //0,0,0
- Skin_TimeG = 0.25;
- Skin_TimeB = 0.25;
-
- Skin_OscR = 0;
- Skin_OscG = 0;
- Skin_OscB = 0;
-
- Skin_LyricsT = 494; // 500 / 510 / 400
- Skin_SpectrumT = 470;
- Skin_SpectrumBot = 570;
- Skin_SpectrumH = 100;
-
- Skin_P1_LinesR = 0.5; // 0.6 0.6 1
- Skin_P1_LinesG = 0.5;
- Skin_P1_LinesB = 0.5;
-
- Skin_P2_LinesR = 0.5; // 1 0.6 0.6
- Skin_P2_LinesG = 0.5;
- Skin_P2_LinesB = 0.5;
-
- Skin_P1_NotesB = 250;
- Skin_P2_NotesB = 430; // 430 / 300
-
- Skin_P1_ScoreT = 50;
- Skin_P1_ScoreL = 20;
-
- Skin_P2_ScoreT = 50;
- Skin_P2_ScoreL = 640;
-
-procedure Initialize3D (Title: string);
-procedure Reinitialize3D;
-procedure SwapBuffers;
-
-procedure LoadTextures;
-procedure InitializeScreen;
-procedure LoadLoadingScreen;
-procedure LoadScreens;
-procedure UnLoadScreens;
-
-function LoadingThreadFunction: integer;
-
-
-implementation
-
-uses
- UMain,
- UIni,
- UDisplay,
- UCommandLine,
- Classes;
-
-procedure LoadFontTextures;
-begin
- Log.LogStatus('Building Fonts', 'LoadTextures');
- BuildFont;
-end;
-
-procedure LoadTextures;
-
-
-var
- P: integer;
- R, G, B: real;
- Col: integer;
-begin
- // zaladowanie tekstur
- Log.LogStatus('Loading Textures', 'LoadTextures');
-
- Tex_Left[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
- Tex_Mid[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_PLAIN, 0); //brauch man die noch?
- Tex_Right[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
-
- Log.LogStatus('Loading Textures - A', 'LoadTextures');
-
- // P1-6
- // TODO... do it once for each player... this is a bit crappy !!
- // can we make it any better !?
- for P := 1 to 6 do
- begin
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
-
- Tex_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_COLORIZED, Col);
-
- Tex_plain_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainLeft'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_plain_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainMid'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_plain_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainRight'), TEXTURE_TYPE_COLORIZED, Col);
-
- Tex_BG_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGLeft'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_BG_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGMid'), TEXTURE_TYPE_COLORIZED, Col);
- Tex_BG_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGRight'), TEXTURE_TYPE_COLORIZED, Col);
- end;
-
- Log.LogStatus('Loading Textures - B', 'LoadTextures');
-
- Tex_Note_Perfect_Star := Texture.LoadTexture(Skin.GetTextureFileName('NotePerfectStar'), TEXTURE_TYPE_TRANSPARENT, 0);
- Tex_Note_Star := Texture.LoadTexture(Skin.GetTextureFileName('NoteStar') , TEXTURE_TYPE_TRANSPARENT, $FFFFFF);
- Tex_Ball := Texture.LoadTexture(Skin.GetTextureFileName('Ball'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- Tex_Lyric_Help_Bar := Texture.LoadTexture(Skin.GetTextureFileName('LyricHelpBar'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
-
-
- //TimeBar mod
- Tex_TimeProgress := Texture.LoadTexture(Skin.GetTextureFileName('TimeBar'));
- //eoa TimeBar mod
-
- //SingBar Mod
- Tex_SingBar_Back := Texture.LoadTexture(Skin.GetTextureFileName('SingBarBack'), TEXTURE_TYPE_PLAIN, 0);
- Tex_SingBar_Bar := Texture.LoadTexture(Skin.GetTextureFileName('SingBarBar'), TEXTURE_TYPE_PLAIN, 0);
- Tex_SingBar_Front := Texture.LoadTexture(Skin.GetTextureFileName('SingBarFront'), TEXTURE_TYPE_PLAIN, 0);
- //end Singbar Mod
-
- Log.LogStatus('Loading Textures - C', 'LoadTextures');
-
- //Line Bonus PopUp
- for P := 0 to 8 do
- begin
- Case P of
- 0: begin
- R := 1;
- G := 0;
- B := 0;
- end;
- 1..3: begin
- R := 1;
- G := (P * 0.25);
- B := 0;
- end;
- 4: begin
- R := 1;
- G := 1;
- B := 0;
- end;
- 5..7: begin
- R := 1-((P-4)*0.25);
- G := 1;
- B := 0;
- end;
- 8: begin
- R := 0;
- G := 1;
- B := 0;
- end;
- End;
-
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), TEXTURE_TYPE_COLORIZED, Col);
- end;
-
-//## backgrounds for the scores ##
- for P := 0 to 5 do begin
- LoadColor(R, G, B, 'P' + IntToStr(P+1) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_ScoreBG[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreBG')), TEXTURE_TYPE_COLORIZED, Col);
- end;
-
-
- Log.LogStatus('Loading Textures - D', 'LoadTextures');
-
-// ######################
-// Score screen textures
-// ######################
-
-//## the bars that visualize the score ##
- for P := 1 to 6 do begin
-//NoteBar ScoreBar
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Dark');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_Score_NoteBarLevel_Dark[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Dark')), TEXTURE_TYPE_COLORIZED, Col);
- Tex_Score_NoteBarRound_Dark[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Dark_Round')), TEXTURE_TYPE_COLORIZED, Col);
-//LineBonus ScoreBar
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_Score_NoteBarLevel_Light[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Light')), TEXTURE_TYPE_COLORIZED, Col);
- Tex_Score_NoteBarRound_Light[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Light_Round')), TEXTURE_TYPE_COLORIZED, Col);
-//GoldenNotes ScoreBar
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Lightest');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_Score_NoteBarLevel_Lightest[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Lightest')), TEXTURE_TYPE_COLORIZED, Col);
- Tex_Score_NoteBarRound_Lightest[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Lightest_Round')), TEXTURE_TYPE_COLORIZED, Col);
- end;
-
-//## rating pictures that show a picture according to your rate ##
- for P := 0 to 7 do begin
- Tex_Score_Ratings[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Rating_'+IntToStr(P))), TEXTURE_TYPE_TRANSPARENT, 0);
- end;
-
- Log.LogStatus('Loading Textures - Done', 'LoadTextures');
-end;
-
-(*
- * Load OpenGL extensions. Must be called after SDL_SetVideoMode() and each
- * time the pixel-format or render-context (RC) changes.
- *)
-procedure LoadOpenGLExtensions;
-begin
- // Load OpenGL 1.2 extensions for OpenGL 1.2 compatibility
- if (not Load_GL_version_1_2()) then
- begin
- Log.LogCritical('Failed loading OpenGL 1.2', 'UGraphic.Initialize3D');
- end;
-
- // Other extensions e.g. OpenGL 1.3-2.0 or Framebuffer-Object might be loaded here
- // ...
- //Load_GL_EXT_framebuffer_object();
-end;
-
-procedure Initialize3D (Title: string);
-var
- Icon: PSDL_Surface;
-begin
- Log.LogStatus('SDL_Init', 'UGraphic.Initialize3D');
- if ( SDL_InitSubSystem(SDL_INIT_VIDEO) = -1 ) then
- begin
- Log.LogError('SDL_Init Failed', 'UGraphic.Initialize3D');
- exit;
- end;
-
- // load icon image (must be 32x32 for win32)
- Icon := LoadImage('WINDOWICON');
- if (Icon <> nil) then
- SDL_WM_SetIcon(Icon, 0);
-
- SDL_WM_SetCaption(PChar(Title), nil);
-
- //Log.BenchmarkStart(2);
-
- InitializeScreen;
-
- //Log.BenchmarkEnd(2);
- //Log.LogBenchmark('--> Setting Screen', 2);
-
- //Log.BenchmarkStart(2);
- Texture := TTextureUnit.Create;
- // FIXME: this does not seem to be correct as Limit is the max. of either
- // width or height.
- Texture.Limit := 1024*1024;
-
- //LoadTextures;
- //Log.BenchmarkEnd(2);
- //Log.LogBenchmark('--> Loading Textures', 2);
-
- {
- Log.BenchmarkStart(2);
- Lyric:= TLyric.Create;
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Fonts', 2);
- }
-
- // Note: do not initialize video modules earlier. They might depend on some
- // SDL video functions or OpenGL extensions initialized in InitializeScreen()
- InitializeVideo();
-
- //Log.BenchmarkStart(2);
-
- Log.LogStatus('TDisplay.Create', 'UGraphic.Initialize3D');
- Display := TDisplay.Create;
-
- //Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2);
-
- //Log.LogStatus('Loading Screens', 'Initialize3D');
- //Log.BenchmarkStart(3);
-
- Log.LogStatus('Loading Font Textures', 'UGraphic.Initialize3D');
- LoadFontTextures();
-
- // Show the Loading Screen -------------
- Log.LogStatus('Loading Loading Screen', 'UGraphic.Initialize3D');
- LoadLoadingScreen;
-
-
- Log.LogStatus(' Loading Textures', 'UGraphic.Initialize3D');
- LoadTextures; // jb
-
-
-
- // now that we have something to display while loading,
- // start thread that loads the rest of ultrastar
- //Mutex := SDL_CreateMutex;
- //SDL_UnLockMutex(Mutex);
-
- // does not work this way because the loading thread tries to access opengl.
- // See comment below
- //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
-
- // this would be run in the loadingthread
- Log.LogStatus(' Loading Screens', 'UGraphic.Initialize3D');
- LoadScreens;
-
-
- // TODO:
- // here should be a loop which
- // * draws the loading screen (form time to time)
- // * controlls the "process of the loading screen
- // * checks if the loadingthread has loaded textures (check mutex) and
- // * load the textures into opengl
- // * tells the loadingthread, that the memory for the texture can be reused
- // to load the netx texture (over another mutex)
- // * runs as long as the loadingthread tells, that everything is loaded and ready (using a third mutex)
- //
- // therefor loadtexture have to be changed, that it, instat of caling some opengl functions
- // for itself, it should change mutex
- // the mainthread have to know somehow what opengl function have to be called with which parameters like
- // texturetype, textureobjekt, textur-buffer-adress, ...
-
- // wait for loading thread to finish
- // currently does not work this way
- // SDL_WaitThread(LoadingThread, I);
- // SDL_DestroyMutex(Mutex);
-
- Display.CurrentScreen^.FadeTo( @ScreenMain );
-
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Screens', 2);
-
- Log.LogStatus('Finish', 'Initialize3D');
-end;
-
-procedure SwapBuffers;
-begin
- SDL_GL_SwapBuffers;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0, RenderW, RenderH, 0, -1, 100);
- glMatrixMode(GL_MODELVIEW);
-end;
-
-procedure Reinitialize3D;
-begin
- InitializeScreen;
-end;
-
-procedure InitializeScreen;
-var
- S: string;
- I: integer;
- W, H: integer;
- Depth: Integer;
-begin
- if (Params.Screens <> -1) then
- Screens := Params.Screens + 1
- else
- Screens := Ini.Screens + 1;
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); // Z-Buffer depth
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- // VSYNC works for windows only at the moment. SDL_GL_SWAP_CONTROL under
- // linux uses GLX_MESA_swap_control which is not supported by nvidea cards.
- // Maybe use glXSwapIntervalSGI(1) from the GLX_SGI_swap_control extension instead.
- //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); // VSYNC (currently Windows only)
-
- // If there is a resolution in Parameters, use it, else use the Ini value
- I := Params.Resolution;
- if (I <> -1) then
- S := IResolution[I]
- else
- S := IResolution[Ini.Resolution];
-
- I := Pos('x', S);
- W := StrToInt(Copy(S, 1, I-1)) * Screens;
- H := StrToInt(Copy(S, I+1, 1000));
-
- if (Params.Depth <> -1) then
- Depth := Params.Depth
- else
- Depth := Ini.Depth;
-
- Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
- //SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
-
- if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
- begin
- Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Windowed');
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE)
- end
- else
- begin
- Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Full Screen');
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN );
- SDL_ShowCursor(0);
- end;
-
- if (screen = nil) then
- begin
- Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D');
- exit;
- end;
-
- LoadOpenGLExtensions();
-
- // define virtual (Render) and real (Screen) screen size
- RenderW := 800;
- RenderH := 600;
- ScreenW := W;
- ScreenH := H;
-
- // clear screen once window is being shown
- // Note: SwapBuffers uses RenderW/H, so they must be defined before
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- SwapBuffers;
-end;
-
-procedure LoadLoadingScreen;
-begin
- ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
-
- Display.CurrentScreen := @ScreenLoading;
-
- swapbuffers;
-
- ScreenLoading.Draw;
- Display.Draw;
-
- SwapBuffers;
-end;
-
-procedure LoadScreens;
-begin
-{ ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
- Display.CurrentScreen := @ScreenLoading;
- ScreenLoading.Draw;
- Display.Draw;
- SwapBuffers;
-}
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
-{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
- ScreenMain := TScreenMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3);
- ScreenName := TScreenName.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3);
- ScreenLevel := TScreenLevel.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3);
- ScreenSong := TScreenSong.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3);
- ScreenSing := TScreenSing.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3);
- ScreenScore := TScreenScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3);
- ScreenTop5 := TScreenTop5.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3);
- ScreenOptions := TScreenOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3);
- ScreenOptionsGame := TScreenOptionsGame.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3);
- ScreenOptionsGraphics := TScreenOptionsGraphics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3);
- ScreenOptionsSound := TScreenOptionsSound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3);
- ScreenOptionsLyrics := TScreenOptionsLyrics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3);
- ScreenOptionsThemes := TScreenOptionsThemes.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3);
- ScreenOptionsRecord := TScreenOptionsRecord.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3);
- ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3);
- ScreenEditSub := TScreenEditSub.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3);
- ScreenEdit := TScreenEdit.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3);
- ScreenEditConvert := TScreenEditConvert.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3);
-// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG);
-// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3);
- ScreenOpen := TScreenOpen.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3);
- ScreenSingModi := TScreenSingModi.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3);
- ScreenSongJumpto := TScreenSongJumpto.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3);
- ScreenPopupCheck := TScreenPopupCheck.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3);
- ScreenPopupError := TScreenPopupError.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3);
- ScreenPartyNewRound := TScreenPartyNewRound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3);
- ScreenPartyScore := TScreenPartyScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3);
- ScreenPartyWin := TScreenPartyWin.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3);
- ScreenPartyOptions := TScreenPartyOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
- ScreenPartyPlayer := TScreenPartyPlayer.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
- ScreenStatMain := TScreenStatMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
- ScreenStatDetail := TScreenStatDetail.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
- ScreenCredits := TScreenCredits.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3);
-
-end;
-
-function LoadingThreadFunction: integer;
-begin
- LoadScreens;
- Result:= 1;
-end;
-
-procedure UnLoadScreens;
-begin
- freeandnil( ScreenMain );
- freeandnil( ScreenName );
- freeandnil( ScreenLevel);
- freeandnil( ScreenSong );
- freeandnil( ScreenSongMenu );
- freeandnil( ScreenSing );
- freeandnil( ScreenScore);
- freeandnil( ScreenTop5 );
- freeandnil( ScreenOptions );
- freeandnil( ScreenOptionsGame );
- freeandnil( ScreenOptionsGraphics );
- freeandnil( ScreenOptionsSound );
- freeandnil( ScreenOptionsLyrics );
-// freeandnil( ScreenOptionsThemes );
- freeandnil( ScreenOptionsRecord );
- freeandnil( ScreenOptionsAdvanced );
- freeandnil( ScreenEditSub );
- freeandnil( ScreenEdit );
- freeandnil( ScreenEditConvert );
- freeandnil( ScreenOpen );
- freeandnil( ScreenSingModi );
- freeandnil( ScreenSongMenu );
- freeandnil( ScreenSongJumpto);
- freeandnil( ScreenPopupCheck );
- freeandnil( ScreenPopupError );
- freeandnil( ScreenPartyNewRound );
- freeandnil( ScreenPartyScore );
- freeandnil( ScreenPartyWin );
- freeandnil( ScreenPartyOptions );
- freeandnil( ScreenPartyPlayer );
- freeandnil( ScreenStatMain );
- freeandnil( ScreenStatDetail );
-end;
-
-end.
diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas
deleted file mode 100644
index b7174991..00000000
--- a/Game/Code/Classes/UGraphicClasses.pas
+++ /dev/null
@@ -1,673 +0,0 @@
-// notes:
-unit UGraphicClasses;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses UTexture,SDL;
-
-const DelayBetweenFrames : Cardinal = 60;
-type
-
- TParticleType=(GoldenNote, PerfectNote, NoteHitTwinkle, PerfectLineTwinkle, ColoredStar, Flare);
-
- TColour3f = Record
- r, g, b: Real;
- end;
-
- TParticle = Class
- X, Y : Real; //Position
- Screen : Integer;
- W, H : Cardinal; //dimensions of particle
- Col : array of TColour3f; // Colour(s) of particle
- Scale : array of Real; // Scaling factors of particle layers
- Frame : Byte; //act. Frame
- Tex : Cardinal; //Tex num from Textur Manager
- Live : Byte; //How many Cycles before Kill
- RecIndex : Integer; //To which rectangle this particle belongs (only GoldenNote)
- StarType : TParticleType; // GoldenNote | PerfectNote | NoteHitTwinkle | PerfectLineTwinkle
- Alpha : Real; // used for fading...
- mX, mY : Real; // movement-vector for PerfectLineTwinkle
- SizeMod : Real; // experimental size modifier
- SurviveSentenceChange : Boolean;
-
- Constructor Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
- Destructor Destroy(); override;
- procedure Draw;
- procedure LiveOn;
- end;
-
- RectanglePositions = Record
- xTop, yTop, xBottom, yBottom : Real;
- TotalStarCount : Integer;
- CurrentStarCount : Integer;
- Screen : Integer;
- end;
-
- PerfectNotePositions = Record
- xPos, yPos : Real;
- Screen : Integer;
- end;
-
- TEffectManager = Class
- Particle : array of TParticle;
- LastTime : Cardinal;
- RecArray : Array of RectanglePositions;
- TwinkleArray : Array[0..5] of Real; // store x-position of last twinkle for every player
- PerfNoteArray : Array of PerfectNotePositions;
-
- FlareTex: TTexture;
-
- constructor Create;
- destructor Destroy; override;
- procedure Draw;
- function Spawn(X, Y: Real;
- Screen: Integer;
- Live: Byte;
- StartFrame: Integer;
- RecArrayIndex: Integer; // this is only used with GoldenNotes
- StarType: TParticleType;
- Player: Cardinal // for PerfectLineTwinkle
- ): Cardinal;
- procedure SpawnRec();
- procedure Kill(index: Cardinal);
- procedure KillAll();
- procedure SentenceChange();
- procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
- procedure SavePerfectNotePos(Xtop, Ytop: Real);
- procedure GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
- procedure SpawnPerfectLineTwinkle();
- end;
-
-var GoldenRec : TEffectManager;
-
-implementation
-
-uses sysutils,
- gl,
- UIni,
- UMain,
- UThemes,
- USkins,
- UGraphic,
- UDrawTexture,
- UCommon,
- math;
-
-//TParticle
-Constructor TParticle.Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
-begin
- inherited Create;
- // in this constructor we set all initial values for our particle
- X := cX;
- Y := cY;
- Screen := cScreen;
- Live := cLive;
- Frame:= cFrame;
- RecIndex := cRecArrayIndex;
- StarType := cStarType;
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- SetLength(Scale,1);
- Scale[0] := 1;
- SurviveSentenceChange := False;
- SizeMod := 1;
- case cStarType of
- GoldenNote:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := 20;
- H := 20;
- SetLength(Scale,4);
- Scale[1]:=0.8;
- Scale[2]:=0.4;
- Scale[3]:=0.3;
- SetLength(Col,4);
- Col[0].r := 1;
- Col[0].g := 0.7;
- Col[0].b := 0.1;
-
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
-
- Col[2].r := 1;
- Col[2].g := 1;
- Col[2].b := 1;
-
- Col[3].r := 1;
- Col[3].g := 1;
- Col[3].b := 1;
- end;
- PerfectNote:
- begin
- Tex := Tex_Note_Perfect_Star.TexNum;
- W := 30;
- H := 30;
- SetLength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := 0.95;
- end;
- NoteHitTwinkle:
- begin
- Tex := Tex_Note_Star.TexNum;
- Alpha := (Live/16); // linear fade-out
- W := 15;
- H := 15;
- Setlength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := RandomRange(10*Live,100)/90; //0.9;
- end;
- PerfectLineTwinkle:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := RandomRange(10,20);
- H := W;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- SurviveSentenceChange:=True;
- // assign colours according to player given
- SetLength(Scale,3);
- Scale[1]:=0.3;
- Scale[2]:=0.2;
- SetLength(Col,3);
- case Player of
- 0: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
- 1: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P2Light');
- 2: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P3Light');
- 3: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P4Light');
- 4: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P5Light');
- 5: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P6Light');
- else LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
- end;
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
- Col[2].r:=Col[0].r+0.5;
- Col[2].g:=Col[0].g+0.5;
- Col[2].b:=Col[0].b+0.5;
- mX := RandomRange(-5,5);
- mY := RandomRange(-5,5);
- end;
- ColoredStar:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := RandomRange(10,20);
- H := W;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- SurviveSentenceChange:=True;
- // assign colours according to player given
- SetLength(Scale,1);
- SetLength(Col,1);
- Col[0].b := (Player and $ff)/255;
- Col[0].g := ((Player shr 8) and $ff)/255;
- Col[0].r := ((Player shr 16) and $ff)/255;
- mX := 0;
- mY := 0;
- end;
- Flare:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := 7;
- H := 7;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- mX := RandomRange(-5,5);
- mY := RandomRange(-5,5);
- SetLength(Scale,4);
- Scale[1]:=0.8;
- Scale[2]:=0.4;
- Scale[3]:=0.3;
- SetLength(Col,4);
- Col[0].r := 1;
- Col[0].g := 0.7;
- Col[0].b := 0.1;
-
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
-
- Col[2].r := 1;
- Col[2].g := 1;
- Col[2].b := 1;
-
- Col[3].r := 1;
- Col[3].g := 1;
- Col[3].b := 1;
-
- end;
- else // just some random default values
- begin
- Tex := Tex_Note_Star.TexNum;
- Alpha := 1;
- W := 20;
- H := 20;
- SetLength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := 1;
- end;
- end;
-end;
-
-Destructor TParticle.Destroy();
-begin
- SetLength(Scale,0);
- SetLength(Col,0);
- inherited;
-end;
-
-procedure TParticle.LiveOn;
-begin
- //Live = 0 => Live forever ?? but if this is 0 they would be killed in the Manager at Draw
- if (Live > 0) then
- Dec(Live);
-
- // animate frames
- Frame := ( Frame + 1 ) mod 16;
-
- // make our particles do funny stuff (besides being animated)
- // changes of any particle-values throughout its life are done here
- case StarType of
- GoldenNote:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- PerfectNote:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- NoteHitTwinkle:
- begin
- Alpha := (Live/10); // linear fade-out
- end;
- PerfectLineTwinkle:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- // move around
- X := X + mX;
- Y := Y + mY;
- end;
- ColoredStar:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- Flare:
- begin
- Alpha := (-cos((Frame+1)/16*1.7*pi+0.3*pi)+1); // neat fade-in-and-out
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- // move around
- X := X + mX;
- Y := Y + mY;
- mY:=mY+1.8;
-// mX:=mX/2;
- end;
- end;
-end;
-
-procedure TParticle.Draw;
-var L: Cardinal;
-begin
- if ScreenAct = Screen then
- // this draws (multiple) texture(s) of our particle
- for L:=0 to High(Col) do
- begin
- glColor4f(Col[L].r, Col[L].g, Col[L].b, Alpha);
-
- glBindTexture(GL_TEXTURE_2D, Tex);
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- begin
- glBegin(GL_QUADS);
- glTexCoord2f((1/16) * Frame, 0); glVertex2f(X-W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame, 1); glVertex2f(X+W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
- glEnd;
- end;
- end;
- glcolor4f(1,1,1,1);
-end;
-// end of TParticle
-
-// TEffectManager
-
-constructor TEffectManager.Create;
-var c: Cardinal;
-begin
- inherited;
- LastTime := SDL_GetTicks();
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0;
- end;
-end;
-
-destructor TEffectManager.Destroy;
-begin
- Killall;
- inherited;
-end;
-
-
-procedure TEffectManager.Draw;
-var
- I: Integer;
- CurrentTime: Cardinal;
-//const
-// DelayBetweenFrames : Cardinal = 100;
-begin
-
- CurrentTime := SDL_GetTicks();
- //Manage particle life
- if (CurrentTime - LastTime) > DelayBetweenFrames then
- begin
- LastTime := CurrentTime;
- for I := 0 to high(Particle) do
- Particle[I].LiveOn;
- end;
-
- I := 0;
- //Kill dead particles
- while (I <= High(Particle)) do
- begin
- if (Particle[I].Live <= 0) then
- begin
- kill(I);
- end
- else
- begin
- inc(I);
- end;
- end;
-
- //Draw
- for I := 0 to high(Particle) do
- begin
- Particle[I].Draw;
- end;
-end;
-
-// this method creates just one particle
-function TEffectManager.Spawn(X, Y: Real; Screen: Integer; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : TParticleType; Player: Cardinal): Cardinal;
-begin
- Result := Length(Particle);
- SetLength(Particle, (Result + 1));
- Particle[Result] := TParticle.Create(X, Y, Screen, Live, StartFrame, RecArrayIndex, StarType, Player);
-end;
-
-// manage Sparkling of GoldenNote Bars
-procedure TEffectManager.SpawnRec();
-Var
- Xkatze, Ykatze : Real;
- RandomFrame : Integer;
- P : Integer; // P as seen on TV as Positionman
-begin
-//Spawn a random amount of stars within the given coordinates
-//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame
-for P:= 0 to high(RecArray) do
- begin
- while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do
- begin
- Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom));
- Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom));
- RandomFrame := RandomRange(0,14);
- // Spawn a GoldenNote Particle
- Spawn(Xkatze, Ykatze, RecArray[P].Screen, 16 - RandomFrame, RandomFrame, P, GoldenNote, 0);
- inc(RecArray[P].CurrentStarCount);
- end;
- end;
- draw;
-end;
-
-// kill one particle (with given index in our particle array)
-procedure TEffectManager.Kill(Index: Cardinal);
-var
- LastParticleIndex : Integer;
-begin
-// delete particle indexed by Index,
-// overwrite it's place in our particle-array with the particle stored at the last array index,
-// shorten array
- LastParticleIndex := high(Particle);
- if not(LastParticleIndex = -1) then // is there still a particle to delete?
- begin
- if not(Particle[Index].RecIndex = -1) then // if it is a GoldenNote particle...
- dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); // take care of its associated GoldenRec
- // now get rid of that particle
- Particle[Index].Destroy;
- Particle[Index] := Particle[LastParticleIndex];
- SetLength(Particle, LastParticleIndex);
- end;
-end;
-
-// clean up all particles and management structures
-procedure TEffectManager.KillAll();
-var c: Cardinal;
-begin
-//It's the kill all kennies rotuine
- while Length(Particle) > 0 do // kill all existing particles
- Kill(0);
- SetLength(RecArray,0); // remove GoldenRec positions
- SetLength(PerfNoteArray,0); // remove PerfectNote positions
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0; // reset GoldenNoteHit memory
- end;
-end;
-
-procedure TEffectManager.SentenceChange();
-var c: Cardinal;
-begin
- c:=0;
- while c <= High(Particle) do
- begin
- if Particle[c].SurviveSentenceChange then
- inc(c)
- else
- Kill(c);
- end;
- SetLength(RecArray,0); // remove GoldenRec positions
- SetLength(PerfNoteArray,0); // remove PerfectNote positions
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0; // reset GoldenNoteHit memory
- end;
-end;
-
-procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
-//Twinkle stars while golden note hit
-// this is called from UDraw.pas, SingDrawPlayerCzesc
-var
- C, P, XKatze, YKatze, LKatze: Integer;
- H: Real;
-begin
- // make sure we spawn only one time at one position
- if (TwinkleArray[Player] < Right) then
- For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle?
- begin
- H := (Top+Bottom)/2; // helper...
- with RecArray[P] do
- if ((xBottom >= Right) and (xTop <= Right) and
- (yTop <= H) and (yBottom >= H))
- and (Screen = ScreenAct) then
- begin
- TwinkleArray[Player] := Right; // remember twinkle position for this player
- for C := 1 to 10 do
- begin
- Ykatze := RandomRange(ceil(Top) , ceil(Bottom));
- XKatze := RandomRange(-7,3);
- LKatze := RandomRange(7,13);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Top)-6 , ceil(Top));
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(4,7);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Bottom), ceil(Bottom)+6);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(4,7);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Top)-10 , ceil(Top)-6);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(1,4);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Bottom)+6 , ceil(Bottom)+10);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(1,4);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
-
- exit; // found a matching GoldenRec, did spawning stuff... done
- end;
- end;
-end;
-
-procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
-var
- P : Integer; // P like used in Positions
- NewIndex : Integer;
-begin
- For P := 0 to high(RecArray) do // Do we already have that "new" position?
- begin
- if (ceil(RecArray[P].xTop) = ceil(Xtop)) and
- (ceil(RecArray[P].yTop) = ceil(Ytop)) and
- (ScreenAct = RecArray[p].Screen) then
- exit; // it's already in the array, so we don't have to create a new one
- end;
-
- // we got a new position, add the new positions to our array
- NewIndex := Length(RecArray);
- SetLength(RecArray, NewIndex + 1);
- RecArray[NewIndex].xTop := Xtop;
- RecArray[NewIndex].yTop := Ytop;
- RecArray[NewIndex].xBottom := Xbottom;
- RecArray[NewIndex].yBottom := Ybottom;
- RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3;
- RecArray[NewIndex].CurrentStarCount := 0;
- RecArray[NewIndex].Screen := ScreenAct;
-end;
-
-procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real);
-var
- P : Integer; // P like used in Positions
- NewIndex : Integer;
- RandomFrame : Integer;
- Xkatze, Ykatze : Integer;
-begin
- For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position?
- begin
- with PerfNoteArray[P] do
- if (ceil(xPos) = ceil(Xtop)) and (ceil(yPos) = ceil(Ytop)) and
- (Screen = ScreenAct) then
- exit; // it's already in the array, so we don't have to create a new one
- end; //for
-
- // we got a new position, add the new positions to our array
- NewIndex := Length(PerfNoteArray);
- SetLength(PerfNoteArray, NewIndex + 1);
- PerfNoteArray[NewIndex].xPos := Xtop;
- PerfNoteArray[NewIndex].yPos := Ytop;
- PerfNoteArray[NewIndex].Screen := ScreenAct;
-
- for P:= 0 to 2 do
- begin
- Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10);
- Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10);
- RandomFrame := RandomRange(0,14);
- Spawn(Xkatze, Ykatze, ScreenAct, 16 - RandomFrame, RandomFrame, -1, PerfectNote, 0);
- end; //for
-
-end;
-
-procedure TEffectManager.SpawnPerfectLineTwinkle();
-var
- P,I,Life: Cardinal;
- Left, Right, Top, Bottom: Cardinal;
- cScreen: Integer;
-begin
-// calculation of coordinates done with hardcoded values like in UDraw.pas
-// might need to be adjusted if drawing of SingScreen is modified
-// coordinates may still be a bit weird and need adjustment
- if Ini.SingWindow = 0 then begin
- Left := 130;
- end else begin
- Left := 30;
- end;
- Right := 770;
- // spawn effect for every player with a perfect line
- for P:=0 to PlayersPlay-1 do
- if Player[P].LastSentencePerfect then
- begin
- // calculate area where notes of this player are drawn
- case PlayersPlay of
- 1: begin
- Bottom:=Skin_P2_NotesB+10;
- Top:=Bottom-105;
- cScreen:=1;
- end;
- 2,4: begin
- case P of
- 0,2: begin
- Bottom:=Skin_P1_NotesB+10;
- Top:=Bottom-105;
- end;
- else begin
- Bottom:=Skin_P2_NotesB+10;
- Top:=Bottom-105;
- end;
- end;
- case P of
- 0,1: cScreen:=1;
- else cScreen:=2;
- end;
- end;
- 3,6: begin
- case P of
- 0,3: begin
- Top:=130;
- Bottom:=Top+85;
- end;
- 1,4: begin
- Top:=255;
- Bottom:=Top+85;
- end;
- 2,5: begin
- Top:=380;
- Bottom:=Top+85;
- end;
- end;
- case P of
- 0,1,2: cScreen:=1;
- else cScreen:=2;
- end;
- end;
- end;
- // spawn Sparkling Stars inside calculated coordinates
- for I:= 0 to 80 do
- begin
- Life:=RandomRange(8,16);
- Spawn(RandomRange(Left,Right), RandomRange(Top,Bottom), cScreen, Life, 16-Life, -1, PerfectLineTwinkle, P);
- end;
- end;
-end;
-
-end.
-
diff --git a/Game/Code/Classes/UHooks.pas b/Game/Code/Classes/UHooks.pas
deleted file mode 100644
index f0ba3276..00000000
--- a/Game/Code/Classes/UHooks.pas
+++ /dev/null
@@ -1,434 +0,0 @@
-unit UHooks;
-
-{*********************
- THookManager
- Class for saving, managing and calling of Hooks.
- Saves all hookable events and their subscribers
-*********************}
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses uPluginDefs,
- SysUtils;
-
-type
- //Record that saves info from Subscriber
- PSubscriberInfo = ^TSubscriberInfo;
- TSubscriberInfo = record
- Self: THandle; //ID of this Subscription (First Word: ID of Subscription; 2nd Word: ID of Hook)
- Next: PSubscriberInfo; //Pointer to next Item in HookChain
-
- Owner: Integer; //For Error Handling and Plugin Unloading.
-
- //Here is s/t tricky
- //To avoid writing of Wrapping Functions to Hook an Event with a Class
- //We save a Normal Proc or a Method of a Class
- Case isClass: boolean of
- False: (Proc: TUS_Hook); //Proc that will be called on Event
- True: (ProcOfClass: TUS_Hook_of_Object);
- end;
-
- TEventInfo = record
- Name: String[60]; //Name of Event
- FirstSubscriber: PSubscriberInfo; //First subscriber in chain
- LastSubscriber: PSubscriberInfo; //Last " (for easier subscriber adding
- end;
-
- THookManager = class
- private
- Events: array of TEventInfo;
- SpaceinEvents: Word; //Number of empty Items in Events Array. (e.g. Deleted Items)
-
- Procedure FreeSubscriber(const EventIndex: Word; const Last, Cur: PSubscriberInfo);
- public
- constructor Create(const SpacetoAllocate: Word);
-
- Function AddEvent (const EventName: PChar): THandle;
- Function DelEvent (hEvent: THandle): Integer;
-
- Function AddSubscriber (const EventName: PChar; const Proc: TUS_Hook = nil; const ProcOfClass: TUS_Hook_of_Object = nil): THandle;
- Function DelSubscriber (const hSubscriber: THandle): Integer;
-
- Function CallEventChain (const hEvent: THandle; const wParam: TwParam; lParam: TlParam): Integer;
- Function EventExists (const EventName: PChar): Integer;
-
- Procedure DelbyOwner(const Owner: Integer);
- end;
-
-function HookTest(wParam: TwParam; lParam: TlParam): integer; stdcall;
-
-var
- HookManager: THookManager;
-
-implementation
-uses
- ULog,
- UCore;
-
-//------------
-// Create - Creates Class and Set Standard Values
-//------------
-constructor THookManager.Create(const SpacetoAllocate: Word);
-var I: Integer;
-begin
- inherited Create();
-
- //Get the Space and "Zero" it
- SetLength (Events, SpacetoAllocate);
- For I := 0 to SpacetoAllocate-1 do
- Events[I].Name[1] := chr(0);
-
- SpaceinEvents := SpacetoAllocate;
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Succesful Created.');
- {$ENDIF}
-end;
-
-//------------
-// AddEvent - Adds an Event and return the Events Handle or 0 on Failure
-//------------
-Function THookManager.AddEvent (const EventName: PChar): THandle;
-var I: Integer;
-begin
- Result := 0;
-
- if (EventExists(EventName) = 0) then
- begin
- If (SpaceinEvents > 0) then
- begin
- //There is already Space available
- //Go Search it!
- For I := 0 to High(Events) do
- If (Events[I].Name[1] = chr(0)) then
- begin //Found Space
- Result := I;
- Dec(SpaceinEvents);
- Break;
- end;
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Found Space for Event at Handle: ''' + InttoStr(Result+1) + '');
- {$ENDIF}
- end
- else
- begin //There is no Space => Go make some!
- Result := Length(Events);
- SetLength(Events, Result + 1);
- end;
-
- //Set Events Data
- Events[Result].Name := EventName;
- Events[Result].FirstSubscriber := nil;
- Events[Result].LastSubscriber := nil;
-
- //Handle is Index + 1
- Inc(Result);
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Add Event succesful: ''' + EventName + '');
- {$ENDIF}
- end
- {$IFDEF DEBUG}
- else
- debugWriteLn('HookManager: Trying to ReAdd Event: ''' + EventName + '');
- {$ENDIF}
-end;
-
-//------------
-// DelEvent - Deletes an Event by Handle Returns False on Failure
-//------------
-Function THookManager.DelEvent (hEvent: THandle): Integer;
-var
- Cur, Last: PSubscriberInfo;
-begin
- hEvent := hEvent - 1; //Arrayindex is Handle - 1
- Result := -1;
-
-
- If (Length(Events) > hEvent) AND (Events[hEvent].Name[1] <> chr(0)) then
- begin //Event exists
- //Free the Space for all Subscribers
- Cur := Events[hEvent].FirstSubscriber;
-
- While (Cur <> nil) do
- begin
- Last := Cur;
- Cur := Cur.Next;
- FreeMem(Last, SizeOf(TSubscriberInfo));
- end;
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Removed Event succesful: ''' + Events[hEvent].Name + '');
- {$ENDIF}
-
- //Free the Event
- Events[hEvent].Name[1] := chr(0);
- Inc(SpaceinEvents); //There is one more space for new events
- end
-
- {$IFDEF DEBUG}
- else
- debugWriteLn('HookManager: Try to Remove not Existing Event. Handle: ''' + InttoStr(hEvent) + '');
- {$ENDIF}
-end;
-
-//------------
-// AddSubscriber - Adds an Subscriber to the Event by Name
-// Returns Handle of the Subscribtion or 0 on Failure
-//------------
-Function THookManager.AddSubscriber (const EventName: PChar; const Proc: TUS_Hook; const ProcOfClass: TUS_Hook_of_Object): THandle;
-var
- EventHandle: THandle;
- EventIndex: Cardinal;
- Cur: PSubscriberInfo;
-begin
- Result := 0;
-
- If (@Proc <> nil) or (@ProcOfClass <> nil) then
- begin
- EventHandle := EventExists(EventName);
-
- If (EventHandle <> 0) then
- begin
- EventIndex := EventHandle - 1;
-
- //Get Memory
- GetMem(Cur, SizeOf(TSubscriberInfo));
-
- //Fill it with Data
- Cur.Next := nil;
-
- //Add Owner
- Cur.Owner := Core.CurExecuted;
-
- If (@Proc = nil) then
- begin //Use the ProcofClass Method
- Cur.isClass := True;
- Cur.ProcOfClass := ProcofClass;
- end
- else //Use the normal Proc
- begin
- Cur.isClass := False;
- Cur.Proc := Proc;
- end;
-
- //Create Handle (1st Word: Handle of Event; 2nd Word: unique ID
- If (Events[EventIndex].LastSubscriber = nil) then
- begin
- If (Events[EventIndex].FirstSubscriber = nil) then
- begin
- Result := (EventHandle SHL 16);
- Events[EventIndex].FirstSubscriber := Cur;
- end
- Else
- begin
- Result := Events[EventIndex].FirstSubscriber.Self + 1;
- end;
- end
- Else
- begin
- Result := Events[EventIndex].LastSubscriber.Self + 1;
- Events[EventIndex].LastSubscriber.Next := Cur;
- end;
-
- Cur.Self := Result;
-
- //Add to Chain
- Events[EventIndex].LastSubscriber := Cur;
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Add Subscriber to Event ''' + Events[EventIndex].Name + ''' succesful. Handle: ''' + InttoStr(Result) + ''' Owner: ' + InttoStr(Cur.Owner));
- {$ENDIF}
- end;
- end;
-end;
-
-//------------
-// FreeSubscriber - Helper for DelSubscriber. Prevents Loss of Chain Items. Frees Memory.
-//------------
-Procedure THookManager.FreeSubscriber(const EventIndex: Word; const Last, Cur: PSubscriberInfo);
-begin
- //Delete from Chain
- If (Last <> nil) then
- begin
- Last.Next := Cur.Next;
- end
- else //Was first Popup
- begin
- Events[EventIndex].FirstSubscriber := Cur.Next;
- end;
-
- //Was this Last subscription ?
- If (Cur = Events[EventIndex].LastSubscriber) then
- begin //Change Last Subscriber
- Events[EventIndex].LastSubscriber := Last;
- end;
-
- //Free Space:
- FreeMem(Cur, SizeOf(TSubscriberInfo));
-end;
-
-//------------
-// DelSubscriber - Deletes a Subscribtion by Handle, return non Zero on Failure
-//------------
-Function THookManager.DelSubscriber (const hSubscriber: THandle): Integer;
-var
- EventIndex: Cardinal;
- Cur, Last: PSubscriberInfo;
-begin
- Result := -1;
- EventIndex := ((hSubscriber AND (High(THandle) xor High(Word))) SHR 16) - 1;
-
- //Existing Event ?
- If (EventIndex < Length(Events)) AND (Events[EventIndex].Name[1] <> chr(0)) then
- begin
- Result := -2; //Return -1 on not existing Event, -2 on not existing Subscription
-
- //Search for Subscription
- Cur := Events[EventIndex].FirstSubscriber;
- Last := nil;
-
- //go through the chain ...
- While (Cur <> nil) do
- begin
- If (Cur.Self = hSubscriber) then
- begin //Found Subscription we searched for
- FreeSubscriber(EventIndex, Last, Cur);
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Del Subscriber from Event ''' + Events[EventIndex].Name + ''' succesful. Handle: ''' + InttoStr(hSubscriber) + '');
- {$ENDIF}
-
- //Set Result and Break the Loop
- Result := 0;
- Break;
- end;
-
- Last := Cur;
- Cur := Cur.Next;
- end;
-
- end;
-end;
-
-
-//------------
-// CallEventChain - Calls the Chain of a specified EventHandle
-// Returns: -1: Handle doesn't Exist, 0 Chain is called until the End
-//------------
-Function THookManager.CallEventChain (const hEvent: THandle; const wParam: TwParam; lParam: TlParam): Integer;
-var
- EventIndex: Cardinal;
- Cur: PSubscriberInfo;
- CurExecutedBackup: Integer; //backup of Core.CurExecuted Attribute
-begin
- Result := -1;
- EventIndex := hEvent - 1;
-
- If ((EventIndex <= High(Events)) AND (Events[EventIndex].Name[1] <> chr(0))) then
- begin //Existing Event
- //Backup CurExecuted
- CurExecutedBackup := Core.CurExecuted;
-
- //Start calling the Chain !!!11
- Cur := Events[EventIndex].FirstSubscriber;
- Result := 0;
- //Call Hooks until the Chain is at the End or breaked
- While ((Cur <> nil) AND (Result = 0)) do
- begin
- //Set CurExecuted
- Core.CurExecuted := Cur.Owner;
- if (Cur.isClass) then
- Result := Cur.ProcOfClass(wParam, lParam)
- else
- Result := Cur.Proc(wParam, lParam);
-
- Cur := Cur.Next;
- end;
-
- //Restore CurExecuted
- Core.CurExecuted := CurExecutedBackup;
- end;
-
- {$IFDEF DEBUG}
- debugWriteLn('HookManager: Called Chain from Event ''' + Events[EventIndex].Name + ''' succesful. Result: ''' + InttoStr(Result) + '');
- {$ENDIF}
-end;
-
-//------------
-// EventExists - Returns non Zero if an Event with the given Name exists
-//------------
-Function THookManager.EventExists (const EventName: PChar): Integer;
-var
- I: Integer;
- Name: String[60];
-begin
- Result := 0;
- //If (Length(EventName) <
- Name := String(EventName);
-
- //Sure not to search for empty space
- If (Name[1] <> chr(0)) then
- begin
- //Search for Event
- For I := 0 to High(Events) do
- If (Events[I].Name = Name) then
- begin //Event found
- Result := I + 1;
- Break;
- end;
- end;
-end;
-
-//------------
-// DelbyOwner - Dels all Subscriptions by a specific Owner. (For Clean Plugin/Module unloading)
-//------------
-Procedure THookManager.DelbyOwner(const Owner: Integer);
-var
- I: Integer;
- Cur, Last: PSubscriberInfo;
-begin
- //Search for Owner in all Hooks Chains
- For I := 0 to High(Events) do
- begin
- If (Events[I].Name[1] <> chr(0)) then
- begin
-
- Last := nil;
- Cur := Events[I].FirstSubscriber;
- //Went Through Chain
- While (Cur <> nil) do
- begin
- If (Cur.Owner = Owner) then
- begin //Found Subscription by Owner -> Delete
- FreeSubscriber(I, Last, Cur);
- If (Last <> nil) then
- Cur := Last.Next
- else
- Cur := Events[I].FirstSubscriber;
- end
- Else
- begin
- //Next Item:
- Last := Cur;
- Cur := Cur.Next;
- end;
- end;
- end;
- end;
-end;
-
-
-function HookTest(wParam: TwParam; lParam: TlParam): integer; stdcall;
-begin
- Result := 0; //Don't break the chain
- Core.ShowMessage(CORE_SM_INFO, PChar(String(PChar(Pointer(lParam))) + ': ' + String(PChar(Pointer(wParam)))));
-end;
-
-end.
diff --git a/Game/Code/Classes/UImage.pas b/Game/Code/Classes/UImage.pas
deleted file mode 100644
index d33c0d38..00000000
--- a/Game/Code/Classes/UImage.pas
+++ /dev/null
@@ -1,993 +0,0 @@
-unit UImage;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SDL;
-
-{$DEFINE HavePNG}
-{$DEFINE HaveBMP}
-{$DEFINE HaveJPG}
-
-const
- PixelFmt_RGBA: TSDL_Pixelformat = (
- palette: nil;
- BitsPerPixel: 32;
- BytesPerPixel: 4;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 0;
- Gshift: 8;
- Bshift: 16;
- Ashift: 24;
- Rmask: $000000ff;
- Gmask: $0000ff00;
- Bmask: $00ff0000;
- Amask: $ff000000;
- ColorKey: 0;
- Alpha: 255
- );
-
- PixelFmt_RGB: TSDL_Pixelformat = (
- palette: nil;
- BitsPerPixel: 24;
- BytesPerPixel: 3;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 0;
- Gshift: 8;
- Bshift: 16;
- Ashift: 0;
- Rmask: $000000ff;
- Gmask: $0000ff00;
- Bmask: $00ff0000;
- Amask: $00000000;
- ColorKey: 0;
- Alpha: 255
- );
-
- PixelFmt_BGRA: TSDL_Pixelformat = (
- palette: nil;
- BitsPerPixel: 32;
- BytesPerPixel: 4;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 16;
- Gshift: 8;
- Bshift: 0;
- Ashift: 24;
- Rmask: $00ff0000;
- Gmask: $0000ff00;
- Bmask: $000000ff;
- Amask: $ff000000;
- ColorKey: 0;
- Alpha: 255
- );
-
- PixelFmt_BGR: TSDL_Pixelformat = (
- palette: nil;
- BitsPerPixel: 24;
- BytesPerPixel: 3;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 16;
- Gshift: 8;
- Bshift: 0;
- Ashift: 0;
- Rmask: $00ff0000;
- Gmask: $0000ff00;
- Bmask: $000000ff;
- Amask: $00000000;
- ColorKey: 0;
- Alpha: 255
- );
-
-type
- TImagePixelFmt = (
- ipfRGBA, ipfRGB, ipfBGRA, ipfBGR
- );
-
-(*******************************************************
- * Image saving
- *******************************************************)
-
-{$IFDEF HavePNG}
-function WritePNGImage(const FileName: string; Surface: PSDL_Surface): boolean;
-{$ENDIF}
-{$IFDEF HaveBMP}
-function WriteBMPImage(const FileName: string; Surface: PSDL_Surface): boolean;
-{$ENDIF}
-{$IFDEF HaveJPG}
-function WriteJPGImage(const FileName: string; Surface: PSDL_Surface; Quality: integer): boolean;
-{$ENDIF}
-
-(*******************************************************
- * Image loading
- *******************************************************)
-
-function LoadImage(const Identifier: string): PSDL_Surface;
-
-(*******************************************************
- * Image manipulation
- *******************************************************)
-
-function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
-procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
-
-
-implementation
-
-uses
- SysUtils,
- Classes,
- Math,
- {$IFDEF MSWINDOWS}
- Windows,
- {$ENDIF}
- {$IFDEF HaveJPG}
- {$IFDEF Delphi}
- Graphics,
- jpeg,
- {$ELSE}
- jpeglib,
- jerror,
- jcparam,
- jdatadst, jcapimin, jcapistd,
- {$ENDIF}
- {$ENDIF}
- {$IFDEF HavePNG}
- png,
- {$ENDIF}
- zlib,
- sdl_image,
- sdlutils,
- UCommon,
- ULog;
-
-
-function IsRGBSurface(pixelFmt: PSDL_PixelFormat): boolean;
-begin
- Result := (pixelFmt.BitsPerPixel = 24) and
- (pixelFmt.RMask = $0000FF) and
- (pixelFmt.GMask = $00FF00) and
- (pixelFmt.BMask = $FF0000);
-end;
-
-function IsRGBASurface(pixelFmt: PSDL_PixelFormat): boolean;
-begin
- Result := (pixelFmt.BitsPerPixel = 32) and
- (pixelFmt.RMask = $000000FF) and
- (pixelFmt.GMask = $0000FF00) and
- (pixelFmt.BMask = $00FF0000) and
- (pixelFmt.AMask = $FF000000);
-end;
-
-function IsBGRSurface(pixelFmt: PSDL_PixelFormat): boolean;
-begin
- Result := (pixelFmt.BitsPerPixel = 24) and
- (pixelFmt.BMask = $0000FF) and
- (pixelFmt.GMask = $00FF00) and
- (pixelFmt.RMask = $FF0000);
-end;
-
-function IsBGRASurface(pixelFmt: PSDL_PixelFormat): boolean;
-begin
- Result := (pixelFmt.BitsPerPixel = 32) and
- (pixelFmt.BMask = $000000FF) and
- (pixelFmt.GMask = $0000FF00) and
- (pixelFmt.RMask = $00FF0000) and
- (pixelFmt.AMask = $FF000000);
-end;
-
-// Converts alpha-formats to BGRA, non-alpha to BGR, and leaves BGR(A) as is
-// sets converted to true if the surface needed to be converted
-function ConvertToBGR_BGRASurface(Surface: PSDL_Surface; out Converted: boolean): PSDL_Surface;
-var
- pixelFmt: PSDL_PixelFormat;
-begin
- pixelFmt := Surface.format;
- if (IsBGRSurface(pixelFmt) or IsBGRASurface(pixelFmt)) then
- begin
- Converted := false;
- Result := Surface;
- end
- else
- begin
- // invalid format -> needs conversion
- if (pixelFmt.AMask <> 0) then
- Result := SDL_ConvertSurface(Surface, @PixelFmt_BGRA, SDL_SWSURFACE)
- else
- Result := SDL_ConvertSurface(Surface, @PixelFmt_BGR, SDL_SWSURFACE);
- Converted := true;
- end;
-end;
-
-// Converts alpha-formats to RGBA, non-alpha to RGB, and leaves RGB(A) as is
-// sets converted to true if the surface needed to be converted
-function ConvertToRGB_RGBASurface(Surface: PSDL_Surface; out Converted: boolean): PSDL_Surface;
-var
- pixelFmt: PSDL_PixelFormat;
-begin
- pixelFmt := Surface.format;
- if (IsRGBSurface(pixelFmt) or IsRGBASurface(pixelFmt)) then
- begin
- Converted := false;
- Result := Surface;
- end
- else
- begin
- // invalid format -> needs conversion
- if (pixelFmt.AMask <> 0) then
- Result := SDL_ConvertSurface(Surface, @PixelFmt_RGBA, SDL_SWSURFACE)
- else
- Result := SDL_ConvertSurface(Surface, @PixelFmt_RGB, SDL_SWSURFACE);
- Converted := true;
- end;
-end;
-
-
-(*******************************************************
- * Image saving
- *******************************************************)
-
-(***************************
- * PNG section
- *****************************)
-
-{$IFDEF HavePNG}
-
-// delphi does not support setjmp()/longjmp() -> define our own error-handler
-procedure user_error_fn(png_ptr: png_structp; error_msg: png_const_charp); cdecl;
-begin
- raise Exception.Create(error_msg);
-end;
-
-procedure user_read_data(png_ptr: png_structp; data: png_bytep; length: png_size_t); cdecl;
-var
- inFile: TFileStream;
-begin
- inFile := TFileStream(png_get_io_ptr(png_ptr));
- inFile.Read(data^, length);
-end;
-
-procedure user_write_data(png_ptr: png_structp; data: png_bytep; length: png_size_t); cdecl;
-var
- outFile: TFileStream;
-begin
- outFile := TFileStream(png_get_io_ptr(png_ptr));
- outFile.Write(data^, length);
-end;
-
-procedure user_flush_data(png_ptr: png_structp); cdecl;
-//var
-// outFile: TFileStream;
-begin
- // binary files are flushed automatically, Flush() works with Text-files only
- //outFile := TFileStream(png_get_io_ptr(png_ptr));
- //outFile.Flush();
-end;
-
-procedure DateTimeToPngTime(time: TDateTime; var pngTime: png_time);
-var
- year, month, day: word;
- hour, minute, second, msecond: word;
-begin
- DecodeDate(time, year, month, day);
- pngTime.year := year;
- pngTime.month := month;
- pngTime.day := day;
- DecodeTime(time, hour, minute, second, msecond);
- pngTime.hour := hour;
- pngTime.minute := minute;
- pngTime.second := second;
-end;
-
-(*
- * ImageData must be in RGB-format
- *)
-function WritePNGImage(const FileName: string; Surface: PSDL_Surface): boolean;
-var
- png_ptr: png_structp;
- info_ptr: png_infop;
- pngFile: TFileStream;
- row: integer;
- rowData: array of png_bytep;
-// rowStride: integer;
- converted: boolean;
- colorType: integer;
-// time: png_time;
-begin
- Result := false;
-
- // open file for writing
- try
- pngFile := TFileStream.Create(FileName, fmCreate);
- except
- Log.LogError('Could not open file: "' + FileName + '"', 'WritePngImage');
- Exit;
- end;
-
- // only 24bit (RGB) or 32bit (RGBA) data is supported, so convert to it
- Surface := ConvertToRGB_RGBASurface(Surface, converted);
-
- png_ptr := nil;
-
- try
- // initialize png (and enable a user-defined error-handler that throws an exception on error)
- png_ptr := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, @user_error_fn, nil);
- // the error-handler is called if png_create_write_struct() fails, so png_ptr should always be <> nil
- if (png_ptr = nil) then
- begin
- Log.LogError('png_create_write_struct() failed', 'WritePngImage');
- if (converted) then
- SDL_FreeSurface(Surface);
- Exit;
- end;
-
- info_ptr := png_create_info_struct(png_ptr);
-
- if (Surface^.format^.BitsPerPixel = 24) then
- colorType := PNG_COLOR_TYPE_RGB
- else
- colorType := PNG_COLOR_TYPE_RGBA;
-
- // define write IO-functions (POSIX-style FILE-pointers are not available in Delphi)
- png_set_write_fn(png_ptr, pngFile, @user_write_data, @user_flush_data);
- png_set_IHDR(
- png_ptr, info_ptr,
- Surface.w, Surface.h,
- 8,
- colorType,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT
- );
-
- // TODO: do we need the modification time?
- //DateTimeToPngTime(Now, time);
- //png_set_tIME(png_ptr, info_ptr, @time);
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_LockSurface(Surface);
-
- // setup data
- SetLength(rowData, Surface.h);
- for row := 0 to Surface.h-1 do
- begin
- // set rowData-elements to beginning of each image row
- // Note: the byte-count of a row is pitch (which is not width*bitsPerPixel if the image is aligned)
- rowData[row] := @PChar(Surface.pixels)[(Surface.h-row-1) * Surface.pitch];
- end;
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_UnlockSurface(Surface);
-
- png_write_info(png_ptr, info_ptr);
- png_write_image(png_ptr, png_bytepp(rowData));
- png_write_end(png_ptr, nil);
-
- Result := true;
- except on E: Exception do
- Log.LogError(E.message, 'WritePngImage');
- end;
-
- // free row-data
- SetLength(rowData, 0);
-
- // free png-resources
- if (png_ptr <> nil) then
- png_destroy_write_struct(@png_ptr, nil);
-
- if (converted) then
- SDL_FreeSurface(Surface);
-
- // close file
- pngFile.Free;
-end;
-
-{$ENDIF}
-
-(***************************
- * BMP section
- *****************************)
-
-{$IFDEF HaveBMP}
-
-{$IFNDEF MSWINDOWS}
-const
- (* constants for the biCompression field *)
- BI_RGB = 0;
- BI_RLE8 = 1;
- BI_RLE4 = 2;
- BI_BITFIELDS = 3;
- BI_JPEG = 4;
- BI_PNG = 5;
-
-type
- BITMAPINFOHEADER = record
- biSize: longword;
- biWidth: longint;
- biHeight: longint;
- biPlanes: word;
- biBitCount: word;
- biCompression: longword;
- biSizeImage: longword;
- biXPelsPerMeter: longint;
- biYPelsPerMeter: longint;
- biClrUsed: longword;
- biClrImportant: longword;
- end;
- LPBITMAPINFOHEADER = ^BITMAPINFOHEADER;
- TBITMAPINFOHEADER = BITMAPINFOHEADER;
- PBITMAPINFOHEADER = ^BITMAPINFOHEADER;
-
- RGBTRIPLE = record
- rgbtBlue: byte;
- rgbtGreen: byte;
- rgbtRed: byte;
- end;
- tagRGBTRIPLE = RGBTRIPLE;
- TRGBTRIPLE = RGBTRIPLE;
- PRGBTRIPLE = ^RGBTRIPLE;
-
- RGBQUAD = record
- rgbBlue: byte;
- rgbGreen: byte;
- rgbRed: byte;
- rgbReserved: byte;
- end;
- tagRGBQUAD = RGBQUAD;
- TRGBQUAD = RGBQUAD;
- PRGBQUAD = ^RGBQUAD;
-
- BITMAPINFO = record
- bmiHeader: BITMAPINFOHEADER;
- bmiColors: array[0..0] of RGBQUAD;
- end;
- LPBITMAPINFO = ^BITMAPINFO;
- PBITMAPINFO = ^BITMAPINFO;
- TBITMAPINFO = BITMAPINFO;
-
- {$PACKRECORDS 2}
- BITMAPFILEHEADER = record
- bfType: word;
- bfSize: longword;
- bfReserved1: word;
- bfReserved2: word;
- bfOffBits: longword;
- end;
- {$PACKRECORDS DEFAULT}
-{$ENDIF}
-
-(*
- * ImageData must be in BGR-format
- *)
-function WriteBMPImage(const FileName: string; Surface: PSDL_Surface): boolean;
-var
- bmpFile: TFileStream;
- FileInfo: BITMAPINFOHEADER;
- FileHeader: BITMAPFILEHEADER;
- Converted: boolean;
- Row: integer;
- RowSize: integer;
-begin
- Result := false;
-
- // open file for writing
- try
- bmpFile := TFileStream.Create(FileName, fmCreate);
- except
- Log.LogError('Could not open file: "' + FileName + '"', 'WriteBMPImage');
- Exit;
- end;
-
- // only 24bit (BGR) or 32bit (BGRA) data is supported, so convert to it
- Surface := ConvertToBGR_BGRASurface(Surface, Converted);
-
- // aligned (4-byte) row-size in bytes
- RowSize := ((Surface.w * Surface.format.BytesPerPixel + 3) div 4) * 4;
-
- // initialize bitmap info
- FillChar(FileInfo, SizeOf(BITMAPINFOHEADER), 0);
- with FileInfo do
- begin
- biSize := SizeOf(BITMAPINFOHEADER);
- biWidth := Surface.w;
- biHeight := Surface.h;
- biPlanes := 1;
- biBitCount := Surface^.format^.BitsPerPixel;
- biCompression := BI_RGB;
- biSizeImage := RowSize * Surface.h;
- end;
-
- // initialize header-data
- FillChar(FileHeader, SizeOf(BITMAPFILEHEADER), 0);
- with FileHeader do
- begin
- bfType := $4D42; // = 'BM'
- bfOffBits := SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER);
- bfSize := bfOffBits + FileInfo.biSizeImage;
- end;
-
- // and move the whole stuff into the file ;-)
- try
- // write headers
- bmpFile.Write(FileHeader, SizeOf(BITMAPFILEHEADER));
- bmpFile.Write(FileInfo, SizeOf(BITMAPINFOHEADER));
-
- // write image-data
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_LockSurface(Surface);
-
- // BMP needs 4-byte alignment
- if (Surface.pitch mod 4 = 0) then
- begin
- // aligned correctly -> write whole image at once
- bmpFile.Write(Surface.pixels^, FileInfo.biSizeImage);
- end
- else
- begin
- // misaligned -> write each line separately
- // Note: for the last line unassigned memory (> last Surface.pixels element)
- // will be copied to the padding area (last bytes of a row),
- // but we do not care because the content of padding data is ignored anyhow.
- for Row := 0 to Surface.h do
- bmpFile.Write(PChar(Surface.pixels)[Row * Surface.pitch], RowSize);
- end;
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_UnlockSurface(Surface);
-
- Result := true;
- finally
- Log.LogError('Could not write file: "' + FileName + '"', 'WriteBMPImage');
- end;
-
- if (Converted) then
- SDL_FreeSurface(Surface);
-
- // close file
- bmpFile.Free;
-end;
-
-{$ENDIF}
-
-(***************************
- * JPG section
- *****************************)
-
-{$IFDEF HaveJPG}
-
-function WriteJPGImage(const FileName: string; Surface: PSDL_Surface; Quality: integer): boolean;
-var
- {$IFDEF Delphi}
- Bitmap: TBitmap;
- BitmapInfo: TBitmapInfo;
- Jpeg: TJpegImage;
- row: integer;
- {$ELSE}
- cinfo: jpeg_compress_struct;
- jerr : jpeg_error_mgr;
- jpgFile: TFileStream;
- rowPtr: array[0..0] of JSAMPROW;
- {$ENDIF}
- converted: boolean;
-begin
- Result := false;
-
- {$IFDEF Delphi}
- // only 24bit (BGR) data is supported, so convert to it
- if (IsBGRSurface(Surface.format)) then
- converted := false
- else
- begin
- Surface := SDL_ConvertSurface(Surface, @PixelFmt_BGR, SDL_SWSURFACE);
- converted := true;
- end;
-
- // create and setup bitmap
- Bitmap := TBitmap.Create;
- Bitmap.PixelFormat := pf24bit;
- Bitmap.Width := Surface.w;
- Bitmap.Height := Surface.h;
-
- // setup bitmap info on source image (Surface parameter)
- ZeroMemory(@BitmapInfo, SizeOf(BitmapInfo));
- with BitmapInfo.bmiHeader do
- begin
- biSize := SizeOf(BITMAPINFOHEADER);
- biWidth := Surface.w;
- biHeight := Surface.h;
- biPlanes := 1;
- biBitCount := 24;
- biCompression := BI_RGB;
- end;
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_LockSurface(Surface);
-
- // use fast Win32-API functions to copy data instead of Bitmap.Canvas.Pixels
- if (Surface.pitch mod 4 = 0) then
- begin
- // if the image is aligned (to a 4-byte boundary) -> copy all data at once
- // Note: surfaces created with SDL (e.g. with SDL_ConvertSurface) are aligned
- SetDIBits(0, Bitmap.Handle, 0, Bitmap.Height, Surface.pixels, BitmapInfo, DIB_RGB_COLORS);
- end
- else
- begin
- // wrong alignment -> copy each line separately.
- // Note: for the last line unassigned memory (> last Surface.pixels element)
- // will be copied to the padding area (last bytes of a row),
- // but we do not care because the content of padding data is ignored anyhow.
- for row := 0 to Surface.h do
- begin
- SetDIBits(0, Bitmap.Handle, row, 1, @PChar(Surface.pixels)[row * Surface.pitch],
- BitmapInfo, DIB_RGB_COLORS);
- end;
- end;
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_UnlockSurface(Surface);
-
- // assign Bitmap to JPEG and store the latter
- Jpeg := TJPEGImage.Create;
- Jpeg.Assign(Bitmap);
- Bitmap.Free;
- Jpeg.CompressionQuality := Quality;
- try
- // compress image (don't forget this line, otherwise it won't be compressed)
- Jpeg.Compress();
- Jpeg.SaveToFile(FileName);
- except
- Log.LogError('Could not save file: "' + FileName + '"', 'WriteJPGImage');
- Exit;
- end;
- Jpeg.Free;
- {$ELSE}
- // based on example.pas in FPC's packages/base/pasjpeg directory
-
- // only 24bit (RGB) data is supported, so convert to it
- if (IsRGBSurface(Surface.format)) then
- converted := false
- else
- begin
- Surface := SDL_ConvertSurface(Surface, @PixelFmt_RGB, SDL_SWSURFACE);
- converted := true;
- end;
-
- // allocate and initialize JPEG compression object
- cinfo.err := jpeg_std_error(jerr);
- // msg_level that will be displayed. (Nomssi)
- //jerr.trace_level := 3;
- // initialize the JPEG compression object
- jpeg_create_compress(@cinfo);
-
- // open file for writing
- try
- jpgFile := TFileStream.Create(FileName, fmCreate);
- except
- Log.LogError('Could not open file: "' + FileName + '"', 'WriteJPGImage');
- Exit;
- end;
-
- // specify data destination
- jpeg_stdio_dest(@cinfo, @jpgFile);
-
- // set parameters for compression
- cinfo.image_width := Surface.w;
- cinfo.image_height := Surface.h;
- cinfo.in_color_space := JCS_RGB;
- cinfo.input_components := 3;
- cinfo.data_precision := 8;
-
- // set default compression parameters
- jpeg_set_defaults(@cinfo);
- jpeg_set_quality(@cinfo, quality, true);
-
- // start compressor
- jpeg_start_compress(@cinfo, true);
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_LockSurface(Surface);
-
- while (cinfo.next_scanline < cinfo.image_height) do
- begin
- // Note: the byte-count of a row is pitch (which is not width*bitsPerPixel if the image is aligned)
- rowPtr[0] := JSAMPROW(@PChar(Surface.pixels)[(Surface.h-cinfo.next_scanline-1) * Surface.pitch]);
- jpeg_write_scanlines(@cinfo, JSAMPARRAY(@rowPtr), 1);
- end;
-
- if (SDL_MUSTLOCK(Surface)) then
- SDL_UnlockSurface(Surface);
-
- // finish compression
- jpeg_finish_compress(@cinfo);
- // close the output file
- jpgFile.Free;
-
- // release JPEG compression object
- jpeg_destroy_compress(@cinfo);
- {$ENDIF}
-
- if (converted) then
- SDL_FreeSurface(Surface);
-
- Result := true;
-end;
-
-{$ENDIF}
-
-
-(*******************************************************
- * Image loading
- *******************************************************)
-
-
-(*
- * Loads an image from the given file or resource
- *)
-function LoadImage(const Identifier: string): PSDL_Surface;
-var
- TexRWops: PSDL_RWops;
- TexStream: TStream;
- FileName: string;
-begin
- Result := nil;
- TexRWops := nil;
-
- if Identifier = '' then
- exit;
-
- //Log.LogStatus( Identifier, 'LoadImage' );
-
- FileName := Identifier;
-
- if (FileExistsInsensitive(FileName)) then
- begin
- // load from file
- //Log.LogStatus( 'Is File ( Loading : '+FileName+')', ' LoadImage' );
- try
- Result := IMG_Load(PChar(FileName));
- //Log.LogStatus( ' '+inttostr( integer( Result ) ), ' LoadImage' );
- except
- Log.LogError('Could not load from file "'+FileName+'"', 'LoadImage');
- Exit;
- end;
- end
- else
- begin
- //Log.LogStatus( 'IS Resource, because file does not exist.('+Identifier+')', ' LoadImage' );
-
- TexStream := GetResourceStream(Identifier, 'TEX');
- if (not assigned(TexStream)) then
- begin
- Log.LogError( 'Invalid file or resource "'+ Identifier+'"', 'LoadImage');
- Exit;
- end;
-
- TexRWops := RWopsFromStream(TexStream);
- if (TexRWops = nil) then
- begin
- Log.LogError( 'Could not assign resource "'+Identifier+'"', 'LoadImage');
- TexStream.Free();
- Exit;
- end;
-
- //Log.LogStatus( 'resource Assigned....' , Identifier);
- try
- Result := IMG_Load_RW(TexRWops, 0);
- except
- Log.LogError( 'Could not read resource "'+Identifier+'"', 'LoadImage');
- end;
-
- SDL_FreeRW(TexRWops);
- TexStream.Free();
- end;
-end;
-
-
-(*******************************************************
- * Image manipulation
- *******************************************************)
-
-
-function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
-begin
- if (fmt1^.BitsPerPixel = fmt2^.BitsPerPixel) and
- (fmt1^.BytesPerPixel = fmt2^.BytesPerPixel) and
- (fmt1^.Rloss = fmt2^.Rloss) and (fmt1^.Gloss = fmt2^.Gloss) and
- (fmt1^.Bloss = fmt2^.Bloss) and (fmt1^.Rmask = fmt2^.Rmask) and
- (fmt1^.Gmask = fmt2^.Gmask) and (fmt1^.Bmask = fmt2^.Bmask) and
- (fmt1^.Rshift = fmt2^.Rshift) and (fmt1^.Gshift = fmt2^.Gshift) and
- (fmt1^.Bshift = fmt2^.Bshift)
- then
- Result := true
- else
- Result := false;
-end;
-
-procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-var
- TempSurface: PSDL_Surface;
-begin
- TempSurface := ImgSurface;
- ImgSurface := SDL_ScaleSurfaceRect(TempSurface,
- 0, 0, TempSurface^.W,TempSurface^.H,
- Width, Height);
- SDL_FreeSurface(TempSurface);
-end;
-
-procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-var
- TempSurface: PSDL_Surface;
- ImgFmt: PSDL_PixelFormat;
-begin
- TempSurface := ImgSurface;
-
- // create a new surface with given width and height
- ImgFmt := TempSurface^.format;
- ImgSurface := SDL_CreateRGBSurface(
- SDL_SWSURFACE, Width, Height, ImgFmt^.BitsPerPixel,
- ImgFmt^.RMask, ImgFmt^.GMask, ImgFmt^.BMask, ImgFmt^.AMask);
-
- // copy image from temp- to new surface
- SDL_SetAlpha(ImgSurface, 0, 255);
- SDL_SetAlpha(TempSurface, 0, 255);
- SDL_BlitSurface(TempSurface, nil, ImgSurface, nil);
-
- SDL_FreeSurface(TempSurface);
-end;
-
-(*
-// Old slow floating point version of ColorizeTexture.
-// For an easier understanding of the faster fixed point version below.
-procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal);
-var
- clr: array[0..2] of Double; // [0: R, 1: G, 2: B]
- hsv: array[0..2] of Double; // [0: H(ue), 1: S(aturation), 2: V(alue)]
- delta, f, p, q, t: Double;
- max: Double;
-begin
- clr[0] := PixelColors[0]/255;
- clr[1] := PixelColors[1]/255;
- clr[2] := PixelColors[2]/255;
- max := maxvalue(clr);
- delta := max - minvalue(clr);
-
- hsv[0] := DestinationHue; // set H(ue)
- hsv[2] := max; // set V(alue)
- // calc S(aturation)
- if (max = 0.0) then
- hsv[1] := 0.0
- else
- hsv[1] := delta/max;
-
- //ColorizePixel(PByteArray(Pixel), DestinationHue);
- h_int := trunc(hsv[0]); // h_int = |_h_|
- f := hsv[0]-h_int; // f = h-h_int
- p := hsv[2]*(1.0-hsv[1]); // p = v*(1-s)
- q := hsv[2]*(1.0-(hsv[1]*f)); // q = v*(1-s*f)
- t := hsv[2]*(1.0-(hsv[1]*(1.0-f))); // t = v*(1-s*(1-f))
- case h_int of
- 0: begin clr[0] := hsv[2]; clr[1] := t; clr[2] := p; end; // (v,t,p)
- 1: begin clr[0] := q; clr[1] := hsv[2]; clr[2] := p; end; // (q,v,p)
- 2: begin clr[0] := p; clr[1] := hsv[2]; clr[2] := t; end; // (p,v,t)
- 3: begin clr[0] := p; clr[1] := q; clr[2] := hsv[2]; end; // (p,q,v)
- 4: begin clr[0] := t; clr[1] := p; clr[2] := hsv[2]; end; // (t,p,v)
- 5: begin clr[0] := hsv[2]; clr[1] := p; clr[2] := q; end; // (v,p,q)
- end;
-
- // and store new rgb back into the image
- PixelColors[0] := trunc(255*clr[0]);
- PixelColors[1] := trunc(255*clr[1]);
- PixelColors[2] := trunc(255*clr[2]);
-end;
-*)
-
-procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
-
- //returns hue within range [0.0-6.0)
- function col2hue(Color:Cardinal): double;
- var
- clr: array[0..2] of double;
- hue, max, delta: double;
- begin
- clr[0] := ((Color and $ff0000) shr 16)/255; // R
- clr[1] := ((Color and $ff00) shr 8)/255; // G
- clr[2] := (Color and $ff) /255; // B
- max := maxvalue(clr);
- delta := max - minvalue(clr);
- // calc hue
- if (delta = 0.0) then hue := 0
- else if (clr[0] = max) then hue := (clr[1]-clr[2])/delta
- else if (clr[1] = max) then hue := 2.0+(clr[2]-clr[0])/delta
- else if (clr[2] = max) then hue := 4.0+(clr[0]-clr[1])/delta;
- if (hue < 0.0) then
- hue := hue + 6.0;
- Result := hue;
- end;
-
-var
- DestinationHue: Double;
- PixelIndex: Cardinal;
- Pixel: PByte;
- PixelColors: PByteArray;
- clr: array[0..2] of UInt32; // [0: R, 1: G, 2: B]
- hsv: array[0..2] of UInt32; // [0: H(ue), 1: S(aturation), 2: V(alue)]
- dhue: UInt32;
- h_int: Cardinal;
- delta, f, p, q, t: Longint;
- max: Uint32;
-begin
- DestinationHue := col2hue(NewColor);
-
- dhue := Trunc(DestinationHue*1024);
-
- Pixel := ImgSurface^.Pixels;
-
- for PixelIndex := 0 to (ImgSurface^.W * ImgSurface^.H)-1 do
- begin
- PixelColors := PByteArray(Pixel);
- // inlined colorize per pixel
-
- // uses fixed point math
- // get color values
- clr[0] := PixelColors[0] shl 10;
- clr[1] := PixelColors[1] shl 10;
- clr[2] := PixelColors[2] shl 10;
- //calculate luminance and saturation from rgb
-
- max := clr[0];
- if clr[1] > max then max := clr[1];
- if clr[2] > max then max := clr[2];
- delta := clr[0];
- if clr[1] < delta then delta := clr[1];
- if clr[2] < delta then delta := clr[2];
- delta := max-delta;
- hsv[0] := dhue; // shl 8
- hsv[2] := max; // shl 8
- if (max = 0) then
- hsv[1] := 0
- else
- hsv[1] := (delta shl 10) div max; // shl 8
- h_int := hsv[0] and $fffffC00;
- f := hsv[0]-h_int; //shl 10
- p := (hsv[2]*(1024-hsv[1])) shr 10;
- q := (hsv[2]*(1024-(hsv[1]*f) shr 10)) shr 10;
- t := (hsv[2]*(1024-(hsv[1]*(1024-f)) shr 10)) shr 10;
- h_int := h_int shr 10;
- case h_int of
- 0: begin clr[0] := hsv[2]; clr[1] := t; clr[2] := p; end; // (v,t,p)
- 1: begin clr[0] := q; clr[1] := hsv[2]; clr[2] := p; end; // (q,v,p)
- 2: begin clr[0] := p; clr[1] := hsv[2]; clr[2] := t; end; // (p,v,t)
- 3: begin clr[0] := p; clr[1] := q; clr[2] := hsv[2]; end; // (p,q,v)
- 4: begin clr[0] := t; clr[1] := p; clr[2] := hsv[2]; end; // (t,p,v)
- 5: begin clr[0] := hsv[2]; clr[1] := p; clr[2] := q; end; // (v,p,q)
- end;
-
- PixelColors[0] := clr[0] shr 10;
- PixelColors[1] := clr[1] shr 10;
- PixelColors[2] := clr[2] shr 10;
-
- Inc(Pixel, ImgSurface^.format.BytesPerPixel);
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas
deleted file mode 100644
index b286c917..00000000
--- a/Game/Code/Classes/UIni.pas
+++ /dev/null
@@ -1,928 +0,0 @@
-unit UIni;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Classes,
- IniFiles,
- ULog,
- SysUtils;
-
-type
- // TInputDeviceConfig stores the configuration for an input device.
- // Configurations will be stored in the InputDeviceConfig array.
- // Note that not all devices listed in InputDeviceConfig are active devices.
- // Some might be unplugged and hence unavailable.
- // Available devices are held in TAudioInputProcessor.DeviceList. Each
- // TAudioInputDevice listed there has a CfgIndex field which is the index to
- // its configuration in the InputDeviceConfig array.
- // Name:
- // the name of the input device
- // Input:
- // the index of the input source to use for recording
- // ChannelToPlayerMap:
- // mapping of recording channels to players, e.g. ChannelToPlayerMap[0] = 2
- // maps the channel 0 (left) to player 2. A player index of 0 means that
- // the channel is not assigned to a player.
- PInputDeviceConfig = ^TInputDeviceConfig;
- TInputDeviceConfig = record
- Name: string;
- Input: integer;
- ChannelToPlayerMap: array of integer;
- end;
-
-type
-
-//Options
-
- TVisualizerOption = (voOff, voWhenNoVideo, voOn);
- TBackgroundMusicOption = (bmoOff, bmoOn);
- TIni = class
- private
- function RemoveFileExt(FullName: string): string;
- function ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
- function GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
- function GetArrayIndex(const SearchArray: array of string; Value: string; CaseInsensitiv: Boolean = False): integer;
- function ReadArrayIndex(const SearchArray: array of string; IniFile: TCustomIniFile;
- IniSection: string; IniProperty: string; Default: integer): integer;
-
- procedure LoadInputDeviceCfg(IniFile: TMemIniFile);
- procedure SaveInputDeviceCfg(IniFile: TIniFile);
- procedure LoadThemes(IniFile: TCustomIniFile);
- procedure LoadPaths(IniFile: TCustomIniFile);
- procedure LoadScreenModes(IniFile: TCustomIniFile);
-
- public
- Name: array[0..11] of string;
-
- // Templates for Names Mod
- NameTeam: array[0..2] of string;
- NameTemplate: array[0..11] of string;
-
- //Filename of the opened iniFile
- Filename: string;
-
- // Game
- Players: integer;
- Difficulty: integer;
- Language: integer;
- Tabs: integer;
- Tabs_at_startup:integer; //Tabs at Startup fix
- Sorting: integer;
- Debug: integer;
-
- // Graphics
- Screens: integer;
- Resolution: integer;
- Depth: integer;
- VisualizerOption:integer;
- FullScreen: integer;
- TextureSize: integer;
- SingWindow: integer;
- Oscilloscope: integer;
- Spectrum: integer;
- Spectrograph: integer;
- MovieSize: integer;
-
- // Sound
- MicBoost: integer;
- ClickAssist: integer;
- BeatClick: integer;
- SavePlayback: integer;
- ThresholdIndex: integer;
- AudioOutputBufferSizeIndex:integer;
- VoicePassthrough:integer;
-
- //Song Preview
- PreviewVolume: integer;
- PreviewFading: integer;
-
- // Lyrics
- LyricsFont: integer;
- LyricsEffect: integer;
- Solmization: integer;
- NoteLines: integer;
-
- // Themes
- Theme: integer;
- SkinNo: integer;
- Color: integer;
- BackgroundMusicOption:integer;
-
- // Record
- InputDeviceConfig: array of TInputDeviceConfig;
-
- // Advanced
- LoadAnimation: integer;
- EffectSing: integer;
- ScreenFade: integer;
- AskBeforeDel: integer;
- OnSongClick: integer;
- LineBonus: integer;
- PartyPopup: integer;
-
- // Controller
- Joypad: integer;
-
- procedure Load();
- procedure Save();
- procedure SaveNames;
- procedure SaveLevel;
- end;
-
-var
- Ini: TIni;
- IResolution: array of string;
- ILanguage: array of string;
- ITheme: array of string;
- ISkin: array of string;
-
-
-
-const
- IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
- IPlayersVals: array[0..4] of integer = ( 1 , 2 , 3 , 4 , 6 );
-
- IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
- ITabs: array[0..1] of string = ('Off', 'On');
-
- ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
- sEdition = 0;
- sGenre = 1;
- sLanguage = 2;
- sFolder = 3;
- sTitle = 4;
- sArtist = 5;
- sTitle2 = 6;
- sArtist2 = 7;
-
- IDebug: array[0..1] of string = ('Off', 'On');
-
- IScreens: array[0..1] of string = ('1', '2');
- IFullScreen: array[0..1] of string = ('Off', 'On');
- IDepth: array[0..1] of string = ('16 bit', '32 bit');
- IVisualizer: array[0..2] of string = ('Off', 'WhenNoVideo','On');
-
- IBackgroundMusic: array[0..1] of string = ('Off', 'On');
-
-
- ITextureSize: array[0..2] of string = ('128', '256', '512');
- ITextureSizeVals: array[0..2] of integer = ( 128, 256, 512);
-
- ISingWindow: array[0..1] of string = ('Small', 'Big');
-
- //SingBar Mod
- IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
-//IOscilloscope: array[0..1] of string = ('Off', 'On');
-
- ISpectrum: array[0..1] of string = ('Off', 'On');
- ISpectrograph: array[0..1] of string = ('Off', 'On');
- IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]');
-
- IClickAssist: array[0..1] of string = ('Off', 'On');
- IBeatClick: array[0..1] of string = ('Off', 'On');
- ISavePlayback: array[0..1] of string = ('Off', 'On');
-
- IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
- IThresholdVals: array[0..3] of single = (0.05, 0.10, 0.15, 0.20);
-
- IVoicePassthrough: array[0..1] of string = ('Off', 'On');
-
- IAudioOutputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
- IAudioOutputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
-
- IAudioInputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
- IAudioInputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
-
- //Song Preview
- IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%');
- IPreviewVolumeVals: array[0..10] of single = ( 0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00 );
-
- IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs');
- IPreviewFadingVals: array[0..5] of integer = ( 0, 1, 2, 3, 4, 5 );
-
-
- ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2');
- ILyricsEffect: array[0..4] of string = ('Simple', 'Zoom', 'Slide', 'Ball', 'Shift');
- ISolmization: array[0..3] of string = ('Off', 'Euro', 'Jap', 'American');
- INoteLines: array[0..1] of string = ('Off', 'On');
-
- IColor: array[0..8] of string = ('Blue', 'Green', 'Pink', 'Red', 'Violet', 'Orange', 'Yellow', 'Brown', 'Black');
-
- // Advanced
- ILoadAnimation: array[0..1] of string = ('Off', 'On');
- IEffectSing: array[0..1] of string = ('Off', 'On');
- IScreenFade: array[0..1] of string =('Off', 'On');
- IAskbeforeDel: array[0..1] of string = ('Off', 'On');
- IOnSongClick: array[0..2] of string = ('Sing', 'Select Players', 'Open Menu');
- ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes');
- IPartyPopup: array[0..1] of string = ('Off', 'On');
-
- IJoypad: array[0..1] of string = ('Off', 'On');
-
- // Recording options
- IChannelPlayer: array[0..6] of string = ('Off', '1', '2', '3', '4', '5', '6');
- IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
-
-implementation
-
-uses
- StrUtils,
- UMain,
- SDL,
- ULanguage,
- UPlatform,
- USkins,
- URecord,
- UCommandLine;
-
-(**
- * Returns the filename without its fileextension
- *)
-function TIni.RemoveFileExt(FullName: string): string;
-begin
- Result := ChangeFileExt(FullName, '');
-end;
-
-(**
- * Extracts an index of a key that is surrounded by a Prefix/Suffix pair.
- * Example: ExtractKeyIndex('MyKey[1]', '[', ']') will return 1.
- *)
-function TIni.ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
-var
- Value: string;
- Start: integer;
-begin
- Result := -1;
-
- if Pos(Prefix, Key) > -1 then
- begin
- Start := Pos(Prefix, Key) + Length(Prefix);
-
- // copy all between prefix and suffix
- Value := Copy(Key, Start, Pos(Suffix, Key)-1 - Start);
- Result := StrToIntDef(Value, -1);
- end;
-end;
-
-(**
- * Finds the maximum key-index in a key-list.
- * The indexes of the list are surrounded by Prefix/Suffix,
- * e.g. MyKey[1] (Prefix='[', Suffix=']')
- *)
-function TIni.GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
-var
- i: integer;
- KeyIndex: integer;
-begin
- Result := -1;
-
- for i := 0 to Keys.Count-1 do
- begin
- KeyIndex := ExtractKeyIndex(Keys[i], Prefix, Suffix);
- if (KeyIndex > Result) then
- Result := KeyIndex;
- end;
-end;
-
-(**
- * Returns the index of Value in SearchArray
- * or -1 if Value is not in SearchArray.
- *)
-function TIni.GetArrayIndex(const SearchArray: array of string; Value: string;
- CaseInsensitiv: Boolean = False): integer;
-var
- i: integer;
-begin
- Result := -1;
-
- for i := 0 to High(SearchArray) do
- begin
- if (SearchArray[i] = Value) or
- (CaseInsensitiv and (UpperCase(SearchArray[i]) = UpperCase(Value))) then
- begin
- Result := i;
- Break;
- end;
- end;
-end;
-
-(**
- * Reads the property IniSeaction:IniProperty from IniFile and
- * finds its corresponding index in SearchArray.
- * If SearchArray does not contain the property value, the default value is
- * returned.
- *)
-function TIni.ReadArrayIndex(const SearchArray: array of string; IniFile: TCustomIniFile;
- IniSection: string; IniProperty: string; Default: integer): integer;
-var
- StrValue: string;
-begin
- StrValue := IniFile.ReadString(IniSection, IniProperty, SearchArray[Default]);
- Result := GetArrayIndex(SearchArray, StrValue);
- if (Result = -1) then
- begin
- Result := Default;
- end;
-end;
-
-
-procedure TIni.LoadInputDeviceCfg(IniFile: TMemIniFile);
-var
- DeviceCfg: PInputDeviceConfig;
- DeviceIndex: integer;
- ChannelCount: integer;
- ChannelIndex: integer;
- RecordKeys: TStringList;
- i: integer;
-begin
- RecordKeys := TStringList.Create();
-
- // read all record-keys for filtering
- IniFile.ReadSection('Record', RecordKeys);
-
- SetLength(InputDeviceConfig, 0);
-
- for i := 0 to RecordKeys.Count-1 do
- begin
- // find next device-name
- DeviceIndex := ExtractKeyIndex(RecordKeys[i], 'DeviceName[', ']');
- if (DeviceIndex >= 0) then
- begin
- if not IniFile.ValueExists('Record', Format('DeviceName[%d]', [DeviceIndex])) then
- break;
-
- // resize list
- SetLength(InputDeviceConfig, Length(InputDeviceConfig)+1);
-
- // read an input device's config.
- // Note: All devices are appended to the list whether they exist or not.
- // Otherwise an external device's config will be lost if it is not
- // connected (e.g. singstar mics or USB-Audio devices).
- DeviceCfg := @InputDeviceConfig[High(InputDeviceConfig)];
- DeviceCfg.Name := IniFile.ReadString('Record', Format('DeviceName[%d]', [DeviceIndex]), '');
- DeviceCfg.Input := IniFile.ReadInteger('Record', Format('Input[%d]', [DeviceIndex]), 0);
-
- // find the largest channel-number of the current device in the ini-file
- ChannelCount := GetMaxKeyIndex(RecordKeys, 'Channel', Format('[%d]', [DeviceIndex]));
- if (ChannelCount < 0) then
- ChannelCount := 0;
-
- SetLength(DeviceCfg.ChannelToPlayerMap, ChannelCount);
-
- // read channel-to-player mapping for every channel of the current device
- // or set non-configured channels to no player (=0).
- for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
- begin
- DeviceCfg.ChannelToPlayerMap[ChannelIndex] :=
- IniFile.ReadInteger('Record', Format('Channel%d[%d]', [ChannelIndex+1, DeviceIndex]), 0);
- end;
- end;
- end;
-
- RecordKeys.Free();
-
- // MicBoost
- //MicBoost := GetArrayIndex(IMicBoost, IniFile.ReadString('Record', 'MicBoost', 'Off'));
- // Threshold
- // ThresholdIndex := GetArrayIndex(IThreshold, IniFile.ReadString('Record', 'Threshold', IThreshold[1]));
-end;
-
-procedure TIni.SaveInputDeviceCfg(IniFile: TIniFile);
-var
- DeviceIndex: integer;
- ChannelIndex: integer;
-begin
- for DeviceIndex := 0 to High(InputDeviceConfig) do
- begin
- // DeviceName and DeviceInput
- IniFile.WriteString('Record', Format('DeviceName[%d]', [DeviceIndex+1]),
- InputDeviceConfig[DeviceIndex].Name);
- IniFile.WriteInteger('Record', Format('Input[%d]', [DeviceIndex+1]),
- InputDeviceConfig[DeviceIndex].Input);
-
- // Channel-to-Player Mapping
- for ChannelIndex := 0 to High(InputDeviceConfig[DeviceIndex].ChannelToPlayerMap) do
- begin
- IniFile.WriteInteger('Record',
- Format('Channel%d[%d]', [ChannelIndex+1, DeviceIndex+1]),
- InputDeviceConfig[DeviceIndex].ChannelToPlayerMap[ChannelIndex]);
- end;
- end;
-
- // MicBoost
- //IniFile.WriteString('Record', 'MicBoost', IMicBoost[MicBoost]);
- // Threshold
- //IniFile.WriteString('Record', 'Threshold', IThreshold[ThresholdIndex]);
-end;
-
-procedure TIni.LoadPaths(IniFile: TCustomIniFile);
-var
- PathStrings: TStringList;
- I: integer;
-begin
- PathStrings := TStringList.Create;
- IniFile.ReadSection('Directories', PathStrings);
-
- // Load song-paths
- for I := 0 to PathStrings.Count-1 do
- begin
- if (AnsiStartsText('SongDir', PathStrings[I])) then
- begin
- AddSongPath(IniFile.ReadString('Directories', PathStrings[I], ''));
- end;
- end;
-
- PathStrings.Free;
-end;
-
-procedure TIni.LoadThemes(IniFile: TCustomIniFile);
-var
- SearchResult: TSearchRec;
- ThemeIni: TMemIniFile;
- ThemeName: string;
- I: integer;
-begin
- // Theme
- SetLength(ITheme, 0);
- Log.LogStatus('Searching for Theme : ' + ThemePath + '*.ini', 'Theme');
-
- FindFirst(ThemePath + '*.ini',faAnyFile, SearchResult);
- Repeat
- Log.LogStatus('Found Theme: ' + SearchResult.Name, 'Theme');
-
- //Read Themename from Theme
- ThemeIni := TMemIniFile.Create(SearchResult.Name);
- ThemeName := UpperCase(ThemeIni.ReadString('Theme','Name', RemoveFileExt(SearchResult.Name)));
- ThemeIni.Free;
-
- //Search for Skins for this Theme
- for I := Low(Skin.Skin) to High(Skin.Skin) do
- begin
- if UpperCase(Skin.Skin[I].Theme) = ThemeName then
- begin
- SetLength(ITheme, Length(ITheme)+1);
- ITheme[High(ITheme)] := RemoveFileExt(SearchResult.Name);
- break;
- end;
- end;
- until FindNext(SearchResult) <> 0;
- FindClose(SearchResult);
-
- // No Theme Found
- if (Length(ITheme) = 0) then
- begin
- Log.CriticalError('Could not find any valid Themes.');
- end;
-
- Theme := GetArrayIndex(ITheme, IniFile.ReadString('Themes', 'Theme', 'DELUXE'), true);
- if (Theme = -1) then
- Theme := 0;
-
- // Skin
- Skin.onThemeChange;
-
- SkinNo := GetArrayIndex(ISkin, IniFile.ReadString('Themes', 'Skin', ISkin[0]));
-end;
-
-procedure TIni.LoadScreenModes(IniFile: TCustomIniFile);
-
- // swap two strings
- procedure swap(var s1, s2: string);
- var
- s3: string;
- begin
- s3 := s1;
- s1 := s2;
- s2 := s3;
- end;
-
-var
- Modes: PPSDL_Rect;
- I: integer;
-begin
- // Screens
- Screens := GetArrayIndex(IScreens, IniFile.ReadString('Graphics', 'Screens', IScreens[0]));
-
- // FullScreen
- FullScreen := GetArrayIndex(IFullScreen, IniFile.ReadString('Graphics', 'FullScreen', 'On'));
-
- // Resolution
- SetLength(IResolution, 0);
-
- // Check if there are any modes available
- // TODO: we should seperate windowed and fullscreen modes. Otherwise it is not
- // possible to select a reasonable fullscreen mode when in windowed mode
- if IFullScreen[FullScreen] = 'On' then
- Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN or SDL_RESIZABLE)
- else
- Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_RESIZABLE) ;
-
- if (Modes = nil) then
- begin
- Log.LogStatus( 'No resolutions Found' , 'Video');
- end
- else if (Modes = PPSDL_Rect(-1)) then
- begin
- // Fallback to some standard resolutions
- SetLength(IResolution, 10);
- IResolution[0] := '640x480';
- IResolution[1] := '800x600';
- IResolution[2] := '1024x768';
- IResolution[3] := '1152x864';
- IResolution[4] := '1280x800';
- IResolution[5] := '1280x960';
- IResolution[6] := '1400x1050';
- IResolution[7] := '1440x900';
- IResolution[8] := '1600x1200';
- IResolution[9] := '1680x1050';
-
- Resolution := GetArrayIndex(IResolution, IniFile.ReadString('Graphics', 'Resolution', '800x600'));
- if Resolution = -1 then
- begin
- SetLength(IResolution, Length(IResolution) + 1);
- IResolution[High(IResolution)] := IniFile.ReadString('Graphics', 'Resolution', '800x600');
- Resolution := High(IResolution);
- end;
- end
- else
- begin
- while assigned( Modes^ ) do //this should solve the biggest wine problem | THANKS Linnex (11.11.07)
- begin
- Log.LogStatus( 'Found Video Mode : ' + IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h) , 'Video');
- SetLength(IResolution, Length(IResolution) + 1);
- IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h);
- Inc(Modes);
- end;
-
- // reverse order
- for I := 0 to (Length(IResolution) div 2) - 1 do
- begin
- swap(IResolution[I], IResolution[High(IResolution)-I]);
- end;
- Resolution := GetArrayIndex(IResolution, IniFile.ReadString('Graphics', 'Resolution', '800x600'));
-
- if Resolution = -1 then
- begin
- Resolution := GetArrayIndex(IResolution, '800x600');
- if Resolution = -1 then
- Resolution := 0;
- end;
- end;
-
- // if no modes were set, then failback to 800x600
- // as per http://sourceforge.net/forum/message.php?msg_id=4544965
- // THANKS : linnex at users.sourceforge.net
- if Length(IResolution) < 1 then
- begin
- Log.LogStatus( 'Found Video Mode : NONE !!! ( Defaulted to 800 x 600 )', 'Video');
- SetLength(IResolution, 1);
- IResolution[0] := '800x600';
- Resolution := 0;
- Log.LogStatus('SDL_ListModes Defaulted Res To : ' + IResolution[0] , 'Graphics - Resolutions');
-
- // Default to fullscreen OFF, in this case !
- FullScreen := 0;
- end;
-
- // Depth
- Depth := GetArrayIndex(IDepth, IniFile.ReadString('Graphics', 'Depth', '32 bit'));
-end;
-
-procedure TIni.Load();
-var
- IniFile: TMemIniFile;
- I: integer;
-begin
- GamePath := Platform.GetGameUserPath;
-
- Log.LogStatus( 'GamePath : ' +GamePath , '' );
-
- if (Params.ConfigFile <> '') then
- try
- FileName := Params.ConfigFile;
- except
- FileName := GamePath + 'config.ini';
- end
- else
- FileName := GamePath + 'config.ini';
-
- Log.LogStatus( 'Using config : ' + FileName , 'Ini');
- IniFile := TMemIniFile.Create( FileName );
-
- // Name
- for I := 0 to 11 do
- Name[I] := IniFile.ReadString('Name', 'P'+IntToStr(I+1), 'Player'+IntToStr(I+1));
-
- // Templates for Names Mod
- for I := 0 to 2 do
- NameTeam[I] := IniFile.ReadString('NameTeam', 'T'+IntToStr(I+1), 'Team'+IntToStr(I+1));
- for I := 0 to 11 do
- NameTemplate[I] := IniFile.ReadString('NameTemplate', 'Name'+IntToStr(I+1), 'Template'+IntToStr(I+1));
-
- // Players
- Players := GetArrayIndex(IPlayers, IniFile.ReadString('Game', 'Players', IPlayers[0]));
-
- // Difficulty
- Difficulty := GetArrayIndex(IDifficulty, IniFile.ReadString('Game', 'Difficulty', 'Easy'));
-
- // Language
- Language := GetArrayIndex(ILanguage, IniFile.ReadString('Game', 'Language', 'English'));
- //Language.ChangeLanguage(ILanguage[Language]);
-
- // Tabs
- Tabs := GetArrayIndex(ITabs, IniFile.ReadString('Game', 'Tabs', ITabs[0]));
- Tabs_at_startup := Tabs; //Tabs at Startup fix
-
- // Song Sorting
- Sorting := GetArrayIndex(ISorting, IniFile.ReadString('Game', 'Sorting', ISorting[0]));
-
- // Debug
- Debug := GetArrayIndex(IDebug, IniFile.ReadString('Game', 'Debug', IDebug[0]));
-
- LoadScreenModes(IniFile);
-
- // TextureSize
- TextureSize := GetArrayIndex(ITextureSize, IniFile.ReadString('Graphics', 'TextureSize', ITextureSize[1]));
-
- // SingWindow
- SingWindow := GetArrayIndex(ISingWindow, IniFile.ReadString('Graphics', 'SingWindow', 'Big'));
-
- // Oscilloscope
- Oscilloscope := GetArrayIndex(IOscilloscope, IniFile.ReadString('Graphics', 'Oscilloscope', 'Bar'));
-
- // Spectrum
- Spectrum := GetArrayIndex(ISpectrum, IniFile.ReadString('Graphics', 'Spectrum', 'Off'));
-
- // Spectrograph
- Spectrograph := GetArrayIndex(ISpectrograph, IniFile.ReadString('Graphics', 'Spectrograph', 'Off'));
-
- // MovieSize
- MovieSize := GetArrayIndex(IMovieSize, IniFile.ReadString('Graphics', 'MovieSize', IMovieSize[2]));
-
- // ClickAssist
- ClickAssist := GetArrayIndex(IClickAssist, IniFile.ReadString('Sound', 'ClickAssist', 'Off'));
-
- // BeatClick
- BeatClick := GetArrayIndex(IBeatClick, IniFile.ReadString('Sound', 'BeatClick', IBeatClick[0]));
-
- // SavePlayback
- SavePlayback := GetArrayIndex(ISavePlayback, IniFile.ReadString('Sound', 'SavePlayback', ISavePlayback[0]));
-
- // AudioOutputBufferSize
- AudioOutputBufferSizeIndex := ReadArrayIndex(IAudioOutputBufferSize, IniFile, 'Sound', 'AudioOutputBufferSize', 0);
-
- //Preview Volume
- PreviewVolume := GetArrayIndex(IPreviewVolume, IniFile.ReadString('Sound', 'PreviewVolume', IPreviewVolume[7]));
-
- //Preview Fading
- PreviewFading := GetArrayIndex(IPreviewFading, IniFile.ReadString('Sound', 'PreviewFading', IPreviewFading[1]));
-
- //AudioRepeat aka VoicePassthrough
- VoicePassthrough := GetArrayIndex(IVoicePassthrough, IniFile.ReadString('Sound', 'VoicePassthrough', IVoicePassthrough[0]));
-
- // Lyrics Font
- LyricsFont := GetArrayIndex(ILyricsFont, IniFile.ReadString('Lyrics', 'LyricsFont', ILyricsFont[1]));
-
- // Lyrics Effect
- LyricsEffect := GetArrayIndex(ILyricsEffect, IniFile.ReadString('Lyrics', 'LyricsEffect', ILyricsEffect[1]));
-
- // Solmization
- Solmization := GetArrayIndex(ISolmization, IniFile.ReadString('Lyrics', 'Solmization', ISolmization[0]));
-
- // NoteLines
- NoteLines := GetArrayIndex(INoteLines, IniFile.ReadString('Lyrics', 'NoteLines', INoteLines[1]));
-
- LoadThemes(IniFile);
-
- // Color
- Color := GetArrayIndex(IColor, IniFile.ReadString('Themes', 'Color', IColor[0]));
-
- LoadInputDeviceCfg(IniFile);
-
- // LoadAnimation
- LoadAnimation := GetArrayIndex(ILoadAnimation, IniFile.ReadString('Advanced', 'LoadAnimation', 'On'));
-
- // ScreenFade
- ScreenFade := GetArrayIndex(IScreenFade, IniFile.ReadString('Advanced', 'ScreenFade', 'On'));
-
- // Visualizations
- // this could be of use later..
- // VisualizerOption :=
- // TVisualizerOption(GetEnumValue(TypeInfo(TVisualizerOption),
- // IniFile.ReadString('Graphics', 'Visualization', 'Off')));
- // || VisualizerOption := TVisualizerOption(GetArrayIndex(IVisualizer, IniFile.ReadString('Graphics', 'Visualization', 'Off')));
- VisualizerOption := GetArrayIndex(IVisualizer, IniFile.ReadString('Graphics', 'Visualization', 'Off'));
-
-{**
- * Background music
- *}
- BackgroundMusicOption := GetArrayIndex(IBackgroundMusic, IniFile.ReadString('Sound', 'BackgroundMusic', 'Off'));
-
- // EffectSing
- EffectSing := GetArrayIndex(IEffectSing, IniFile.ReadString('Advanced', 'EffectSing', 'On'));
-
- // AskbeforeDel
- AskBeforeDel := GetArrayIndex(IAskbeforeDel, IniFile.ReadString('Advanced', 'AskbeforeDel', 'On'));
-
- // OnSongClick
- OnSongClick := GetArrayIndex(IOnSongClick, IniFile.ReadString('Advanced', 'OnSongClick', 'Sing'));
-
- // Linebonus
- LineBonus := GetArrayIndex(ILineBonus, IniFile.ReadString('Advanced', 'LineBonus', 'At Score'));
-
- // PartyPopup
- PartyPopup := GetArrayIndex(IPartyPopup, IniFile.ReadString('Advanced', 'PartyPopup', 'On'));
-
- // Joypad
- Joypad := GetArrayIndex(IJoypad, IniFile.ReadString('Controller', 'Joypad', IJoypad[0]));
-
- LoadPaths(IniFile);
-
- IniFile.Free;
-end;
-
-procedure TIni.Save;
-var
- IniFile: TIniFile;
-begin
- if (FileExists(Filename) and FileIsReadOnly(Filename)) then
- begin
- Log.LogError('Config-file is read-only', 'TIni.Save');
- Exit;
- end;
-
- IniFile := TIniFile.Create(Filename);
-
- // Players
- IniFile.WriteString('Game', 'Players', IPlayers[Players]);
-
- // Difficulty
- IniFile.WriteString('Game', 'Difficulty', IDifficulty[Difficulty]);
-
- // Language
- IniFile.WriteString('Game', 'Language', ILanguage[Language]);
-
- // Tabs
- IniFile.WriteString('Game', 'Tabs', ITabs[Tabs]);
-
- // Sorting
- IniFile.WriteString('Game', 'Sorting', ISorting[Sorting]);
-
- // Debug
- IniFile.WriteString('Game', 'Debug', IDebug[Debug]);
-
- // Screens
- IniFile.WriteString('Graphics', 'Screens', IScreens[Screens]);
-
- // FullScreen
- IniFile.WriteString('Graphics', 'FullScreen', IFullScreen[FullScreen]);
-
- // Visualization
- IniFile.WriteString('Graphics', 'Visualization', IVisualizer[VisualizerOption]);
-
- // Resolution
- IniFile.WriteString('Graphics', 'Resolution', IResolution[Resolution]);
-
- // Depth
- IniFile.WriteString('Graphics', 'Depth', IDepth[Depth]);
-
- // TextureSize
- IniFile.WriteString('Graphics', 'TextureSize', ITextureSize[TextureSize]);
-
- // Sing Window
- IniFile.WriteString('Graphics', 'SingWindow', ISingWindow[SingWindow]);
-
- // Oscilloscope
- IniFile.WriteString('Graphics', 'Oscilloscope', IOscilloscope[Oscilloscope]);
-
- // Spectrum
- IniFile.WriteString('Graphics', 'Spectrum', ISpectrum[Spectrum]);
-
- // Spectrograph
- IniFile.WriteString('Graphics', 'Spectrograph', ISpectrograph[Spectrograph]);
-
- // Movie Size
- IniFile.WriteString('Graphics', 'MovieSize', IMovieSize[MovieSize]);
-
- // ClickAssist
- IniFile.WriteString('Sound', 'ClickAssist', IClickAssist[ClickAssist]);
-
- // BeatClick
- IniFile.WriteString('Sound', 'BeatClick', IBeatClick[BeatClick]);
-
- // AudioOutputBufferSize
- IniFile.WriteString('Sound', 'AudioOutputBufferSize', IAudioOutputBufferSize[AudioOutputBufferSizeIndex]);
-
- // Background music
- IniFile.WriteString('Sound', 'BackgroundMusic', IBackgroundMusic[BackgroundMusicOption]);
-
- // Song Preview
- IniFile.WriteString('Sound', 'PreviewVolume', IPreviewVolume[PreviewVolume]);
-
- // PreviewFading
- IniFile.WriteString('Sound', 'PreviewFading', IPreviewFading[PreviewFading]);
-
- // SavePlayback
- IniFile.WriteString('Sound', 'SavePlayback', ISavePlayback[SavePlayback]);
-
- // VoicePasstrough
- IniFile.WriteString('Sound', 'VoicePassthrough', IVoicePassthrough[VoicePassthrough]);
-
- // Lyrics Font
- IniFile.WriteString('Lyrics', 'LyricsFont', ILyricsFont[LyricsFont]);
-
- // Lyrics Effect
- IniFile.WriteString('Lyrics', 'LyricsEffect', ILyricsEffect[LyricsEffect]);
-
- // Solmization
- IniFile.WriteString('Lyrics', 'Solmization', ISolmization[Solmization]);
-
- // NoteLines
- IniFile.WriteString('Lyrics', 'NoteLines', INoteLines[NoteLines]);
-
- // Theme
- IniFile.WriteString('Themes', 'Theme', ITheme[Theme]);
-
- // Skin
- IniFile.WriteString('Themes', 'Skin', ISkin[SkinNo]);
-
- // Color
- IniFile.WriteString('Themes', 'Color', IColor[Color]);
-
- SaveInputDeviceCfg(IniFile);
-
- //LoadAnimation
- IniFile.WriteString('Advanced', 'LoadAnimation', ILoadAnimation[LoadAnimation]);
-
- //EffectSing
- IniFile.WriteString('Advanced', 'EffectSing', IEffectSing[EffectSing]);
-
- //ScreenFade
- IniFile.WriteString('Advanced', 'ScreenFade', IScreenFade[ScreenFade]);
-
- //AskbeforeDel
- IniFile.WriteString('Advanced', 'AskbeforeDel', IAskbeforeDel[AskBeforeDel]);
-
- //OnSongClick
- IniFile.WriteString('Advanced', 'OnSongClick', IOnSongClick[OnSongClick]);
-
- //Line Bonus
- IniFile.WriteString('Advanced', 'LineBonus', ILineBonus[LineBonus]);
-
- //Party Popup
- IniFile.WriteString('Advanced', 'PartyPopup', IPartyPopup[PartyPopup]);
-
- // Joypad
- IniFile.WriteString('Controller', 'Joypad', IJoypad[Joypad]);
-
- // Directories (add a template if section is missing)
- if (not IniFile.SectionExists('Directories')) then
- IniFile.WriteString('Directories', 'SongDir1', '');
-
- IniFile.Free;
-end;
-
-procedure TIni.SaveNames;
-var
- IniFile: TIniFile;
- I: integer;
-begin
- if not FileIsReadOnly(Filename) then
- begin
- IniFile := TIniFile.Create(Filename);
-
- //Name Templates for Names Mod
- for I := 1 to 12 do
- IniFile.WriteString('Name', 'P' + IntToStr(I), Name[I-1]);
- for I := 1 to 3 do
- IniFile.WriteString('NameTeam', 'T' + IntToStr(I), NameTeam[I-1]);
- for I := 1 to 12 do
- IniFile.WriteString('NameTemplate', 'Name' + IntToStr(I), NameTemplate[I-1]);
-
- IniFile.Free;
- end;
-end;
-
-procedure TIni.SaveLevel;
-var
- IniFile: TIniFile;
-begin
- if not FileIsReadOnly(Filename) then
- begin
- IniFile := TIniFile.Create(Filename);
-
- // Difficulty
- IniFile.WriteString('Game', 'Difficulty', IDifficulty[Difficulty]);
-
- IniFile.Free;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UJoystick.pas b/Game/Code/Classes/UJoystick.pas
deleted file mode 100644
index 0ca7ba09..00000000
--- a/Game/Code/Classes/UJoystick.pas
+++ /dev/null
@@ -1,282 +0,0 @@
-unit UJoystick;
-
-interface
-
-{$I switches.inc}
-
-
-uses SDL;
-
-type
- TJoyButton = record
- State: integer;
- Enabled: boolean;
- Type_: byte;
- Sym: cardinal;
- end;
-
- TJoyHatState = record
- State: Boolean;
- LastTick: Cardinal;
- Enabled: boolean;
- Type_: byte;
- Sym: cardinal;
- end;
-
- TJoyUnit = record
- Button: array[0..15] of TJoyButton;
- HatState: Array[0..3] of TJoyHatState;
- end;
-
- TJoy = class
- constructor Create;
- procedure Update;
- end;
-
-var
- Joy: TJoy;
- JoyUnit: TJoyUnit;
- SDL_Joy: PSDL_Joystick;
- JoyEvent: TSDL_Event;
-
-implementation
-
-uses SysUtils,
- ULog;
-
-constructor TJoy.Create;
-var
- B, N: integer;
-begin
- inherited;
-
- //Old Corvus5 Method
- {// joystick support
- SDL_JoystickEventState(SDL_IGNORE);
- SDL_InitSubSystem(SDL_INIT_JOYSTICK);
- if SDL_NumJoysticks <> 1 then
- Log.LogStatus('Joystick count <> 1', 'TJoy.Create');
-
- SDL_Joy := SDL_JoystickOpen(0);
- if SDL_Joy = nil then
- Log.LogError('SDL_JoystickOpen failed', 'TJoy.Create');
-
- if SDL_JoystickNumButtons(SDL_Joy) <> 16 then
- Log.LogStatus('Joystick button count <> 16', 'TJoy.Create');
-
-// SDL_JoystickEventState(SDL_ENABLE);
- // Events don't work - thay hang the whole application with SDL_JoystickEventState(SDL_ENABLE)
-
- // clear states
- for B := 0 to 15 do
- JoyUnit.Button[B].State := 1;
-
- // mapping
- JoyUnit.Button[1].Enabled := true;
- JoyUnit.Button[1].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[1].Sym := SDLK_RETURN;
- JoyUnit.Button[2].Enabled := true;
- JoyUnit.Button[2].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[2].Sym := SDLK_ESCAPE;
-
- JoyUnit.Button[12].Enabled := true;
- JoyUnit.Button[12].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[12].Sym := SDLK_LEFT;
- JoyUnit.Button[13].Enabled := true;
- JoyUnit.Button[13].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[13].Sym := SDLK_DOWN;
- JoyUnit.Button[14].Enabled := true;
- JoyUnit.Button[14].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[14].Sym := SDLK_RIGHT;
- JoyUnit.Button[15].Enabled := true;
- JoyUnit.Button[15].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[15].Sym := SDLK_UP;
- }
- //New Sarutas method
- SDL_JoystickEventState(SDL_IGNORE);
- SDL_InitSubSystem(SDL_INIT_JOYSTICK);
- if SDL_NumJoysticks < 1 then
- begin
- Log.LogError('No Joystick found');
- exit;
- end;
-
-
- SDL_Joy := SDL_JoystickOpen(0);
- if SDL_Joy = nil then
- begin
- Log.LogError('Could not Init Joystick');
- exit;
- end;
- N := SDL_JoystickNumButtons(SDL_Joy);
- //if N < 6 then Log.LogStatus('Joystick button count < 6', 'TJoy.Create');
-
- for B := 0 to 5 do begin
- JoyUnit.Button[B].Enabled := true;
- JoyUnit.Button[B].State := 1;
- JoyUnit.Button[B].Type_ := SDL_KEYDOWN;
- end;
-
- JoyUnit.Button[0].Sym := SDLK_Return;
- JoyUnit.Button[1].Sym := SDLK_Escape;
- JoyUnit.Button[2].Sym := SDLK_M;
- JoyUnit.Button[3].Sym := SDLK_R;
-
- JoyUnit.Button[4].Sym := SDLK_RETURN;
- JoyUnit.Button[5].Sym := SDLK_ESCAPE;
-
- //Set HatState
- for B := 0 to 3 do begin
- JoyUnit.HatState[B].Enabled := true;
- JoyUnit.HatState[B].State := False;
- JoyUnit.HatState[B].Type_ := SDL_KEYDOWN;
- end;
-
- JoyUnit.HatState[0].Sym := SDLK_UP;
- JoyUnit.HatState[1].Sym := SDLK_RIGHT;
- JoyUnit.HatState[2].Sym := SDLK_DOWN;
- JoyUnit.HatState[3].Sym := SDLK_LEFT;
-end;
-
-procedure TJoy.Update;
-var
- B: integer;
- State: UInt8;
- Tick: Cardinal;
- Axes: Smallint;
-begin
- SDL_JoystickUpdate;
-
- //Manage Buttons
- for B := 0 to 15 do begin
- if (JoyUnit.Button[B].Enabled) and (JoyUnit.Button[B].State <> SDL_JoystickGetButton(SDL_Joy, B)) and (JoyUnit.Button[B].State = 0) then begin
- JoyEvent.type_ := JoyUnit.Button[B].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.Button[B].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end;
-
-
- for B := 0 to 15 do begin
- JoyUnit.Button[B].State := SDL_JoystickGetButton(SDL_Joy, B);
- end;
-
- //Get Tick
- Tick := SDL_GetTicks();
-
- //Get CoolieHat
- if (SDL_JoystickNumHats(SDL_Joy)>=1) then
- State := SDL_JoystickGetHat(SDL_Joy, 0)
- else
- State := 0;
-
- //Get Axis
- if (SDL_JoystickNumAxes(SDL_Joy)>=2) then
- begin
- //Down - Up (X- Axis)
- Axes := SDL_JoystickGetAxis(SDL_Joy, 1);
- If Axes >= 15000 then
- State := State or SDL_HAT_Down
- Else If Axes <= -15000 then
- State := State or SDL_HAT_UP;
-
- //Left - Right (Y- Axis)
- Axes := SDL_JoystickGetAxis(SDL_Joy, 0);
- If Axes >= 15000 then
- State := State or SDL_HAT_Right
- Else If Axes <= -15000 then
- State := State or SDL_HAT_Left;
- end;
-
- //Manage Hat and joystick Events
- if (SDL_JoystickNumHats(SDL_Joy)>=1) OR (SDL_JoystickNumAxes(SDL_Joy)>=2) then
- begin
-
- //Up Button
- If (JoyUnit.HatState[0].Enabled) and ((SDL_HAT_UP AND State) = SDL_HAT_UP) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
- if (JoyUnit.HatState[0].State = False) OR (JoyUnit.HatState[0].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[0].State then
- JoyUnit.HatState[0].Lasttick := Tick + 200
- else
- JoyUnit.HatState[0].Lasttick := Tick + 500;
-
- JoyUnit.HatState[0].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[0].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[0].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[0].State := False;
-
- //Right Button
- If (JoyUnit.HatState[1].Enabled) and ((SDL_HAT_RIGHT AND State) = SDL_HAT_RIGHT) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
- if (JoyUnit.HatState[1].State = False) OR (JoyUnit.HatState[1].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[1].State then
- JoyUnit.HatState[1].Lasttick := Tick + 200
- else
- JoyUnit.HatState[1].Lasttick := Tick + 500;
-
- JoyUnit.HatState[1].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[1].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[1].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[1].State := False;
-
- //Down button
- If (JoyUnit.HatState[2].Enabled) and ((SDL_HAT_DOWN AND State) = SDL_HAT_DOWN) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
- if (JoyUnit.HatState[2].State = False) OR (JoyUnit.HatState[2].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[2].State then
- JoyUnit.HatState[2].Lasttick := Tick + 200
- else
- JoyUnit.HatState[2].Lasttick := Tick + 500;
-
- JoyUnit.HatState[2].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[2].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[2].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[2].State := False;
-
- //Left Button
- If (JoyUnit.HatState[3].Enabled) and ((SDL_HAT_LEFT AND State) = SDL_HAT_LEFT) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
- if (JoyUnit.HatState[3].State = False) OR (JoyUnit.HatState[3].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[3].State then
- JoyUnit.HatState[3].Lasttick := Tick + 200
- else
- JoyUnit.HatState[3].Lasttick := Tick + 500;
-
- JoyUnit.HatState[3].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[3].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[3].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[3].State := False;
- end;
-
-end;
-
-end.
diff --git a/Game/Code/Classes/ULCD.pas b/Game/Code/Classes/ULCD.pas
deleted file mode 100644
index 82f7ba2f..00000000
--- a/Game/Code/Classes/ULCD.pas
+++ /dev/null
@@ -1,304 +0,0 @@
-unit ULCD;
-
-interface
-
-{$I switches.inc}
-
-type
- TLCD = class
- private
- Enabled: boolean;
- Text: array[1..6] of string;
- StartPos: integer;
- LineBR: integer;
- Position: integer;
- procedure WriteCommand(B: byte);
- procedure WriteData(B: byte);
- procedure WriteString(S: string);
- public
- HalfInterface: boolean;
- constructor Create;
- procedure Enable;
- procedure Clear;
- procedure WriteText(Line: integer; S: string);
- procedure MoveCursor(Line, Pos: integer);
- procedure ShowCursor;
- procedure HideCursor;
-
- // for 2x16
- procedure AddTextBR(S: string);
- procedure MoveCursorBR(Pos: integer);
- procedure ScrollUpBR;
- procedure AddTextArray(Line:integer; S: string);
- end;
-
-var
- LCD: TLCD;
-
-const
- Data = $378; // domyœlny adres portu
- Status = Data + 1;
- Control = Data + 2;
-
-implementation
-
-uses
- SysUtils,
- {$IFDEF UseSerialPort}
- zlportio,
- {$ENDIF}
- SDL,
- UTime;
-
-procedure TLCD.WriteCommand(B: Byte);
-// Wysylanie komend sterujacych
-begin
-{$IFDEF UseSerialPort}
- if not HalfInterface then
- begin
- zlioportwrite(Control, 0, $02);
- zlioportwrite(Data, 0, B);
- zlioportwrite(Control, 0, $03);
- end
- else
- begin
- zlioportwrite(Control, 0, $02);
- zlioportwrite(Data, 0, B and $F0);
- zlioportwrite(Control, 0, $03);
-
- SDL_Delay( 100 );
-
- zlioportwrite(Control, 0, $02);
- zlioportwrite(Data, 0, (B * 16) and $F0);
- zlioportwrite(Control, 0, $03);
- end;
-
- if (B=1) or (B=2) then
- Sleep(2)
- else
- SDL_Delay( 100 );
-{$ENDIF}
-end;
-
-procedure TLCD.WriteData(B: Byte);
-// Wysylanie danych
-begin
-{$IFDEF UseSerialPort}
- if not HalfInterface then
- begin
- zlioportwrite(Control, 0, $06);
- zlioportwrite(Data, 0, B);
- zlioportwrite(Control, 0, $07);
- end
- else
- begin
- zlioportwrite(Control, 0, $06);
- zlioportwrite(Data, 0, B and $F0);
- zlioportwrite(Control, 0, $07);
-
- SDL_Delay( 100 );
-
- zlioportwrite(Control, 0, $06);
- zlioportwrite(Data, 0, (B * 16) and $F0);
- zlioportwrite(Control, 0, $07);
- end;
-
- SDL_Delay( 100 );
- Inc(Position);
-{$ENDIF}
-end;
-
-procedure TLCD.WriteString(S: string);
-// Wysylanie slow
-var
- I: integer;
-begin
- for I := 1 to Length(S) do
- WriteData(Ord(S[I]));
-end;
-
-constructor TLCD.Create;
-begin
- inherited;
-end;
-
-procedure TLCD.Enable;
-{var
- A: byte;
- B: byte;}
-begin
- Enabled := true;
- if not HalfInterface then
- WriteCommand($38)
- else begin
- WriteCommand($33);
- WriteCommand($32);
- WriteCommand($28);
- end;
-
-// WriteCommand($06);
-// WriteCommand($0C);
-// sleep(10);
-end;
-
-procedure TLCD.Clear;
-begin
- if Enabled then begin
- WriteCommand(1);
- WriteCommand(2);
- Text[1] := '';
- Text[2] := '';
- Text[3] := '';
- Text[4] := '';
- Text[5] := '';
- Text[6] := '';
- StartPos := 1;
- LineBR := 1;
- end;
-end;
-
-procedure TLCD.WriteText(Line: integer; S: string);
-begin
- if Enabled then begin
- if Line <= 2 then begin
- MoveCursor(Line, 1);
- WriteString(S);
- end;
-
- Text[Line] := '';
- AddTextArray(Line, S);
- end;
-end;
-
-procedure TLCD.MoveCursor(Line, Pos: integer);
-var
- I: integer;
-begin
- if Enabled then begin
- Pos := Pos + (Line-1) * 40;
-
- if Position > Pos then begin
- WriteCommand(2);
- for I := 1 to Pos-1 do
- WriteCommand(20);
- end;
-
- if Position < Pos then
- for I := 1 to Pos - Position do
- WriteCommand(20);
-
- Position := Pos;
- end;
-end;
-
-procedure TLCD.ShowCursor;
-begin
- if Enabled then begin
- WriteCommand(14);
- end;
-end;
-
-procedure TLCD.HideCursor;
-begin
- if Enabled then begin
- WriteCommand(12);
- end;
-end;
-
-procedure TLCD.AddTextBR(S: string);
-var
- Word: string;
-// W: integer;
- P: integer;
- L: integer;
-begin
- if Enabled then begin
- if LineBR <= 6 then begin
- L := LineBR;
- P := Pos(' ', S);
-
- if L <= 2 then
- MoveCursor(L, 1);
-
- while (L <= 6) and (P > 0) do begin
- Word := Copy(S, 1, P);
- if (Length(Text[L]) + Length(Word)-1) > 16 then begin
- L := L + 1;
- if L <= 2 then
- MoveCursor(L, 1);
- end;
-
- if L <= 6 then begin
- if L <= 2 then
- WriteString(Word);
- AddTextArray(L, Word);
- end;
-
- Delete(S, 1, P);
- P := Pos(' ', S)
- end;
-
- LineBR := L + 1;
- end;
- end;
-end;
-
-procedure TLCD.MoveCursorBR(Pos: integer);
-{var
- I: integer;
- L: integer;}
-begin
- if Enabled then begin
- Pos := Pos - (StartPos-1);
- if Pos <= Length(Text[1]) then
- MoveCursor(1, Pos);
-
- if Pos > Length(Text[1]) then begin
- // bez zawijania
-// Pos := Pos - Length(Text[1]);
-// MoveCursor(2, Pos);
-
- // z zawijaniem
- Pos := Pos - Length(Text[1]);
- ScrollUpBR;
- MoveCursor(1, Pos);
- end;
- end;
-end;
-
-procedure TLCD.ScrollUpBR;
-var
- T: array[1..5] of string;
- SP: integer;
- LBR: integer;
-begin
- if Enabled then begin
- T[1] := Text[2];
- T[2] := Text[3];
- T[3] := Text[4];
- T[4] := Text[5];
- T[5] := Text[6];
- SP := StartPos + Length(Text[1]);
- LBR := LineBR;
-
- Clear;
-
- StartPos := SP;
- WriteText(1, T[1]);
- WriteText(2, T[2]);
- WriteText(3, T[3]);
- WriteText(4, T[4]);
- WriteText(5, T[5]);
- LineBR := LBR-1;
- end;
-end;
-
-procedure TLCD.AddTextArray(Line: integer; S: string);
-begin
- if Enabled then begin
- Text[Line] := Text[Line] + S;
- end;
-end;
-
-end.
-
diff --git a/Game/Code/Classes/ULanguage.pas b/Game/Code/Classes/ULanguage.pas
deleted file mode 100644
index d534b4e1..00000000
--- a/Game/Code/Classes/ULanguage.pas
+++ /dev/null
@@ -1,240 +0,0 @@
-unit ULanguage;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-type
- TLanguageEntry = record
- ID: string;
- Text: string;
- end;
-
- TLanguageList = record
- Name: string;
- {FileName: string; }
- end;
-
- TLanguage = class
- public
- Entry: array of TLanguageEntry; //Entrys of Chosen Language
- SEntry: array of TLanguageEntry; //Entrys of Standard Language
- CEntry: array of TLanguageEntry; //Constant Entrys e.g. Version
- Implode_Glue1, Implode_Glue2: String;
- public
- List: array of TLanguageList;
-
- constructor Create;
- procedure LoadList;
- function Translate(Text: String): String;
- procedure ChangeLanguage(Language: String);
- procedure AddConst(ID, Text: String);
- procedure ChangeConst(ID, Text: String);
- function Implode(Pieces: Array of String): String;
- end;
-
-var
- Language: TLanguage;
-
-implementation
-
-uses UMain,
- // UFiles,
- UIni,
- IniFiles,
- Classes,
- SysUtils,
- {$IFDEF win32}
- windows,
- {$ENDIF}
- ULog;
-
-//----------
-//Create - Construct Class then LoadList + Standard Language + Set Standard Implode Glues
-//----------
-constructor TLanguage.Create;
-var
- I, J: Integer;
-begin
- inherited;
-
- LoadList;
-
- //Set Implode Glues for Backward Compatibility
- Implode_Glue1 := ', ';
- Implode_Glue2 := ' and ';
-
- if (Length(List) = 0) then //No Language Files Loaded -> Abort Loading
- Log.CriticalError('Could not load any Language File');
-
- //Standard Language (If a Language File is Incomplete)
- //Then use English Language
- for I := 0 to high(List) do //Search for English Language
- begin
- //English Language Found -> Load
- if Uppercase(List[I].Name) = 'ENGLISH' then
- begin
- ChangeLanguage('English');
-
- SetLength(SEntry, Length(Entry));
- for J := low(Entry) to high(Entry) do
- SEntry[J] := Entry[J];
-
- SetLength(Entry, 0);
-
- Break;
- end;
-
- if (I = high(List)) then
- Log.LogError('English Languagefile missing! No standard Translation loaded');
- end;
- //Standard Language END
-
-end;
-
-//----------
-//LoadList - Parse the Language Dir searching Translations
-//----------
-procedure TLanguage.LoadList;
-var
- SR: TSearchRec; // for parsing directory
-begin
- SetLength(List, 0);
- SetLength(ILanguage, 0);
-
- if FindFirst(LanguagesPath + '*.ini', 0, SR) = 0 then begin
- repeat
- SetLength(List, Length(List)+1);
- SetLength(ILanguage, Length(ILanguage)+1);
- SR.Name := ChangeFileExt(SR.Name, '');
-
- List[High(List)].Name := SR.Name;
- ILanguage[High(ILanguage)] := SR.Name;
-
- until FindNext(SR) <> 0;
- SysUtils.FindClose(SR);
- end; // if FindFirst
-end;
-
-//----------
-//ChangeLanguage - Load the specified LanguageFile
-//----------
-procedure TLanguage.ChangeLanguage(Language: String);
-var
- IniFile: TIniFile;
- E: integer; // entry
- S: TStringList;
-begin
- SetLength(Entry, 0);
- IniFile := TIniFile.Create(LanguagesPath + Language + '.ini');
- S := TStringList.Create;
-
- IniFile.ReadSectionValues('Text', S);
- SetLength(Entry, S.Count);
- for E := 0 to high(Entry) do
- begin
- if S.Names[E] = 'IMPLODE_GLUE1' then
- Implode_Glue1 := S.ValueFromIndex[E]+ ' '
- else if S.Names[E] = 'IMPLODE_GLUE2' then
- Implode_Glue2 := ' ' + S.ValueFromIndex[E] + ' ';
-
- Entry[E].ID := S.Names[E];
- Entry[E].Text := S.ValueFromIndex[E];
- end;
-
- S.Free;
- IniFile.Free;
-end;
-
-//----------
-//Translate - Translate the Text
-//----------
-Function TLanguage.Translate(Text: String): String;
-var
- E: integer; // entry
-begin
- Result := Text;
- Text := Uppercase(Result);
-
- //Const Mod
- for E := 0 to high(CEntry) do
- if Text = CEntry[E].ID then
- begin
- Result := CEntry[E].Text;
- exit;
- end;
- //Const Mod End
-
- for E := 0 to high(Entry) do
- if Text = Entry[E].ID then
- begin
- Result := Entry[E].Text;
- exit;
- end;
-
- //Standard Language (If a Language File is Incomplete)
- //Then use Standard Language
- for E := low(SEntry) to high(SEntry) do
- if Text = SEntry[E].ID then
- begin
- Result := SEntry[E].Text;
- Break;
- end;
- //Standard Language END
-end;
-
-//----------
-//AddConst - Add a Constant ID that will be Translated but not Loaded from the LanguageFile
-//----------
-procedure TLanguage.AddConst (ID, Text: String);
-begin
- SetLength (CEntry, Length(CEntry) + 1);
- CEntry[high(CEntry)].ID := ID;
- CEntry[high(CEntry)].Text := Text;
-end;
-
-//----------
-//ChangeConst - Change a Constant Value by ID
-//----------
-procedure TLanguage.ChangeConst(ID, Text: String);
-var
- I: Integer;
-begin
- for I := 0 to high(CEntry) do
- begin
- if CEntry[I].ID = ID then
- begin
- CEntry[I].Text := Text;
- Break;
- end;
- end;
-end;
-
-//----------
-//Implode - Connect an Array of Strings with ' and ' or ', ' to one String
-//----------
-function TLanguage.Implode(Pieces: Array of String): String;
-var
- I: Integer;
-begin
- Result := '';
- //Go through Pieces
- for I := low(Pieces) to high(Pieces) do
- begin
- //Add Value
- Result := Result + Pieces[I];
-
- //Add Glue
- if (I < high(Pieces) - 1) then
- Result := Result + Implode_Glue1
- else if (I < high(Pieces)) then
- Result := Result + Implode_Glue2;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/ULight.pas b/Game/Code/Classes/ULight.pas
deleted file mode 100644
index a0a399ab..00000000
--- a/Game/Code/Classes/ULight.pas
+++ /dev/null
@@ -1,145 +0,0 @@
-unit ULight;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-type
- TLight = class
- private
- Enabled: boolean;
- Light: array[0..7] of boolean;
- LightTime: array[0..7] of real; // time to stop, need to call update to change state
- LastTime: real;
- public
- constructor Create;
- procedure Enable;
- procedure SetState(State: integer);
- procedure AutoSetState;
- procedure TurnOn;
- procedure TurnOff;
- procedure LightOne(Number: integer; Time: real);
- procedure Refresh;
- end;
-
-var
- Light: TLight;
-
-const
- Data = $378; // default port address
- Status = Data + 1;
- Control = Data + 2;
-
-implementation
-
-uses
- SysUtils,
- {$IFDEF UseSerialPort}
- zlportio,
- {$ENDIF}
- UTime;
-
-{$IFDEF FPC}
-
- function GetTime: TDateTime;
- var
- SystemTime: TSystemTime;
- begin
- GetLocalTime(SystemTime);
- with SystemTime do
- begin
- {$IFDEF UNIX}
- Result := EncodeTime(Hour, Minute, Second, MilliSecond);
- {$ELSE}
- Result := EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
- {$ENDIF}
- end;
- end;
-
-{$ENDIF}
-
-
-constructor TLight.Create;
-begin
- inherited;
- Enabled := false;
-end;
-
-procedure TLight.Enable;
-begin
- Enabled := true;
- LastTime := GetTime;
-end;
-
-procedure TLight.SetState(State: integer);
-begin
- {$IFDEF UseSerialPort}
- if Enabled then
- PortWriteB($378, State);
- {$ENDIF}
-end;
-
-procedure TLight.AutoSetState;
-var
- State: integer;
-begin
- if Enabled then begin
- State := 0;
- if Light[0] then State := State + 2;
- if Light[1] then State := State + 1;
- // etc
- SetState(State);
- end;
-end;
-
-procedure TLight.TurnOn;
-begin
- if Enabled then
- SetState(3);
-end;
-
-procedure TLight.TurnOff;
-begin
- if Enabled then
- SetState(0);
-end;
-
-procedure TLight.LightOne(Number: integer; Time: real);
-begin
- if Enabled then begin
- if Light[Number] = false then begin
- Light[Number] := true;
- AutoSetState;
- end;
-
- LightTime[Number] := GetTime + Time/1000; // [s]
- end;
-end;
-
-procedure TLight.Refresh;
-var
- Time: real;
- L: integer;
-begin
- if Enabled then begin
- Time := GetTime;
- for L := 0 to 7 do begin
- if Light[L] = true then begin
- if LightTime[L] > Time then begin
- end else begin
- Light[L] := false;
- end;
- end;
- end;
- LastTime := Time;
- AutoSetState;
- end;
-end;
-
-end.
-
-
diff --git a/Game/Code/Classes/ULog.pas b/Game/Code/Classes/ULog.pas
deleted file mode 100644
index a9a2f3c4..00000000
--- a/Game/Code/Classes/ULog.pas
+++ /dev/null
@@ -1,417 +0,0 @@
-unit ULog;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Classes;
-
-(*
- * LOG_LEVEL_[TYPE] defines the "minimum" index for logs of type TYPE. Each
- * level greater than this BUT less or equal than LOG_LEVEL_[TYPE]_MAX is of this type.
- * This means a level "LOG_LEVEL_ERROR >= Level <= LOG_LEVEL_ERROR_MAX" e.g.
- * "Level := LOG_LEVEL_ERROR+2" is considered an error level.
- * This is nice for debugging if you have more or less important debug messages.
- * For example you can assign LOG_LEVEL_DEBUG+10 for the more important ones and
- * LOG_LEVEL_DEBUG+20 for less important ones and so on. By changing the log-level
- * you can hide the less important ones.
- *)
-const
- LOG_LEVEL_DEBUG_MAX = MaxInt;
- LOG_LEVEL_DEBUG = 50;
- LOG_LEVEL_INFO_MAX = LOG_LEVEL_DEBUG-1;
- LOG_LEVEL_INFO = 40;
- LOG_LEVEL_STATUS_MAX = LOG_LEVEL_INFO-1;
- LOG_LEVEL_STATUS = 30;
- LOG_LEVEL_WARN_MAX = LOG_LEVEL_STATUS-1;
- LOG_LEVEL_WARN = 20;
- LOG_LEVEL_ERROR_MAX = LOG_LEVEL_WARN-1;
- LOG_LEVEL_ERROR = 10;
- LOG_LEVEL_CRITICAL_MAX = LOG_LEVEL_ERROR-1;
- LOG_LEVEL_CRITICAL = 0;
- LOG_LEVEL_NONE = -1;
-
- // define level that Log(File)Level is initialized with
- LOG_LEVEL_DEFAULT = LOG_LEVEL_WARN;
- LOG_FILE_LEVEL_DEFAULT = LOG_LEVEL_ERROR;
-
-type
- TLog = class
- private
- LogFile: TextFile;
- LogFileOpened: boolean;
- BenchmarkFile: TextFile;
- BenchmarkFileOpened: boolean;
-
- LogLevel: integer;
- // level of messages written to the log-file
- LogFileLevel: integer;
-
- procedure LogToFile(const Text: string);
- public
- BenchmarkTimeStart: array[0..31] of real;
- BenchmarkTimeLength: array[0..31] of real;//TDateTime;
-
- Title: String; //Application Title
-
- // Write log message to log-file
- FileOutputEnabled: Boolean;
-
- constructor Create;
-
- // destuctor
- destructor Destroy; override;
-
- // benchmark
- procedure BenchmarkStart(Number: integer);
- procedure BenchmarkEnd(Number: integer);
- procedure LogBenchmark(const Text: string; Number: integer);
-
- procedure SetLogLevel(Level: integer);
- function GetLogLevel(): integer;
-
- procedure LogMsg(const Text: string; Level: integer); overload;
- procedure LogMsg(const Msg, Context: string; Level: integer); overload; {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogDebug(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogInfo(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogStatus(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogWarn(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogError(const Text: string); overload; {$IFDEF HasInline}inline;{$ENDIF}
- procedure LogError(const Msg, Context: string); overload; {$IFDEF HasInline}inline;{$ENDIF}
- //Critical Error (Halt + MessageBox)
- procedure LogCritical(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
- procedure CriticalError(const Text: string); {$IFDEF HasInline}inline;{$ENDIF}
-
- // voice
- procedure LogVoice(SoundNr: integer);
- // buffer
- procedure LogBuffer(const buf : Pointer; const bufLength : Integer; const filename : string);
- end;
-
-procedure DebugWriteln(const aString: String);
-
-var
- Log: TLog;
-
-implementation
-
-uses
- SysUtils,
- DateUtils,
- URecord,
- UMain,
- UTime,
- UCommon,
- UCommandLine;
-
-(*
- * Write to console if in debug mode (Thread-safe).
- * If debug-mode is disabled nothing is done.
- *)
-procedure DebugWriteln(const aString: string);
-begin
- {$IFNDEF DEBUG}
- if Params.Debug then
- begin
- {$ENDIF}
- ConsoleWriteLn(aString);
- {$IFNDEF DEBUG}
- end;
- {$ENDIF}
-end;
-
-
-constructor TLog.Create;
-begin
- inherited;
- LogLevel := LOG_LEVEL_DEFAULT;
- LogFileLevel := LOG_FILE_LEVEL_DEFAULT;
- FileOutputEnabled := true;
-end;
-
-destructor TLog.Destroy;
-begin
- if BenchmarkFileOpened then
- CloseFile(BenchmarkFile);
- //if AnalyzeFileOpened then
- // CloseFile(AnalyzeFile);
- if LogFileOpened then
- CloseFile(LogFile);
- inherited;
-end;
-
-procedure TLog.BenchmarkStart(Number: integer);
-begin
- BenchmarkTimeStart[Number] := USTime.GetTime; //Time;
-end;
-
-procedure TLog.BenchmarkEnd(Number: integer);
-begin
- BenchmarkTimeLength[Number] := USTime.GetTime {Time} - BenchmarkTimeStart[Number];
-end;
-
-procedure TLog.LogBenchmark(const Text: string; Number: integer);
-var
- Minutes: integer;
- Seconds: integer;
- Miliseconds: integer;
-
- MinutesS: string;
- SecondsS: string;
- MilisecondsS: string;
-
- ValueText: string;
-begin
- if (FileOutputEnabled and Params.Benchmark) then
- begin
- if not BenchmarkFileOpened then
- begin
- BenchmarkFileOpened := true;
- AssignFile(BenchmarkFile, LogPath + 'Benchmark.log');
- {$I-}
- Rewrite(BenchmarkFile);
- if IOResult = 0 then
- BenchmarkFileOpened := true;
- {$I+}
-
- //If File is opened write Date to Benchmark File
- If (BenchmarkFileOpened) then
- begin
- WriteLn(BenchmarkFile, Title + ' Benchmark File');
- WriteLn(BenchmarkFile, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
- WriteLn(BenchmarkFile, '-------------------');
-
- Flush(BenchmarkFile);
- end;
- end;
-
- if BenchmarkFileOpened then
- begin
- Miliseconds := Trunc(Frac(BenchmarkTimeLength[Number]) * 1000);
- Seconds := Trunc(BenchmarkTimeLength[Number]) mod 60;
- Minutes := Trunc((BenchmarkTimeLength[Number] - Seconds) / 60);
- //ValueText := FloatToStr(BenchmarkTimeLength[Number]);
-
- {
- ValueText := FloatToStr(SecondOf(BenchmarkTimeLength[Number]) +
- MilliSecondOf(BenchmarkTimeLength[Number])/1000);
- if MinuteOf(BenchmarkTimeLength[Number]) >= 1 then
- ValueText := IntToStr(MinuteOf(BenchmarkTimeLength[Number])) + ':' + ValueText;
- WriteLn(FileBenchmark, Text + ': ' + ValueText + ' seconds');
- }
-
- if (Minutes = 0) and (Seconds = 0) then begin
- MilisecondsS := IntToStr(Miliseconds);
- ValueText := MilisecondsS + ' miliseconds';
- end;
-
- if (Minutes = 0) and (Seconds >= 1) then begin
- MilisecondsS := IntToStr(Miliseconds);
- while Length(MilisecondsS) < 3 do
- MilisecondsS := '0' + MilisecondsS;
-
- SecondsS := IntToStr(Seconds);
-
- ValueText := SecondsS + ',' + MilisecondsS + ' seconds';
- end;
-
- if Minutes >= 1 then begin
- MilisecondsS := IntToStr(Miliseconds);
- while Length(MilisecondsS) < 3 do
- MilisecondsS := '0' + MilisecondsS;
-
- SecondsS := IntToStr(Seconds);
- while Length(SecondsS) < 2 do
- SecondsS := '0' + SecondsS;
-
- MinutesS := IntToStr(Minutes);
-
- ValueText := MinutesS + ':' + SecondsS + ',' + MilisecondsS + ' minutes';
- end;
-
- WriteLn(BenchmarkFile, Text + ': ' + ValueText);
- Flush(BenchmarkFile);
- end;
- end;
-end;
-
-procedure TLog.LogToFile(const Text: string);
-begin
- if (FileOutputEnabled and not LogFileOpened) then
- begin
- AssignFile(LogFile, LogPath + 'Error.log');
- {$I-}
- Rewrite(LogFile);
- if IOResult = 0 then
- LogFileOpened := true;
- {$I+}
-
- //If File is opened write Date to Error File
- if (LogFileOpened) then
- begin
- WriteLn(LogFile, Title + ' Error Log');
- WriteLn(LogFile, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
- WriteLn(LogFile, '-------------------');
-
- Flush(LogFile);
- end;
- end;
-
- if LogFileOpened then
- begin
- try
- WriteLn(LogFile, Text);
- Flush(LogFile);
- except
- LogFileOpened := false;
- end;
- end;
-end;
-
-procedure TLog.SetLogLevel(Level: integer);
-begin
- LogLevel := Level;
-end;
-
-function TLog.GetLogLevel(): integer;
-begin
- Result := LogLevel;
-end;
-
-procedure TLog.LogMsg(const Text: string; Level: integer);
-var
- LogMsg: string;
-begin
- // TODO: what if (LogFileLevel < LogLevel)? Log to file without printing to
- // console or do not log at all? At the moment nothing is logged.
- if (Level <= LogLevel) then
- begin
- if (Level <= LOG_LEVEL_CRITICAL_MAX) then
- LogMsg := 'CRITICAL: ' + Text
- else if (Level <= LOG_LEVEL_ERROR_MAX) then
- LogMsg := 'ERROR: ' + Text
- else if (Level <= LOG_LEVEL_WARN_MAX) then
- LogMsg := 'WARN: ' + Text
- else if (Level <= LOG_LEVEL_STATUS_MAX) then
- LogMsg := 'STATUS: ' + Text
- else if (Level <= LOG_LEVEL_INFO_MAX) then
- LogMsg := 'INFO: ' + Text
- else
- LogMsg := 'DEBUG: ' + Text;
-
- // output log-message
- if (Level <= LogLevel) then
- begin
- DebugWriteLn(LogMsg);
- end;
-
- // write message to log-file
- if (Level <= LogFileLevel) then
- begin
- LogToFile(LogMsg);
- end;
- end;
-
- // exit application on criticial errors (cannot be turned off)
- if (Level <= LOG_LEVEL_CRITICAL_MAX) then
- begin
- // Show information (window)
- ShowMessage(Text, mtError);
- Halt;
- end;
-end;
-
-procedure TLog.LogMsg(const Msg, Context: string; Level: integer);
-begin
- LogMsg(Msg + ' ['+Context+']', Level);
-end;
-
-procedure TLog.LogDebug(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_DEBUG);
-end;
-
-procedure TLog.LogInfo(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_INFO);
-end;
-
-procedure TLog.LogStatus(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_STATUS);
-end;
-
-procedure TLog.LogWarn(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_WARN);
-end;
-
-procedure TLog.LogError(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_ERROR);
-end;
-
-procedure TLog.LogError(const Text: string);
-begin
- LogMsg(Text, LOG_LEVEL_ERROR);
-end;
-
-procedure TLog.CriticalError(const Text: string);
-begin
- LogMsg(Text, LOG_LEVEL_CRITICAL);
-end;
-
-procedure TLog.LogCritical(const Msg, Context: string);
-begin
- LogMsg(Msg, Context, LOG_LEVEL_CRITICAL);
-end;
-
-procedure TLog.LogVoice(SoundNr: integer);
-var
- FS: TFileStream;
- FileName: string;
- Num: integer;
-begin
- for Num := 1 to 9999 do begin
- FileName := IntToStr(Num);
- while Length(FileName) < 4 do
- FileName := '0' + FileName;
- FileName := LogPath + 'Voice' + FileName + '.raw';
- if not FileExists(FileName) then
- break
- end;
-
- FS := TFileStream.Create(FileName, fmCreate);
-
- AudioInputProcessor.Sound[SoundNr].LogBuffer.Seek(0, soBeginning);
- FS.CopyFrom(AudioInputProcessor.Sound[SoundNr].LogBuffer, AudioInputProcessor.Sound[SoundNr].LogBuffer.Size);
-
- FS.Free;
-end;
-
-procedure TLog.LogBuffer(const buf: Pointer; const bufLength: Integer; const filename: string);
-var
- f : TFileStream;
-begin
- f := nil;
-
- try
- f := TFileStream.Create( filename, fmCreate);
- f.Write( buf^, bufLength);
- f.Free;
- except
- on e : Exception do begin
- Log.LogError('TLog.LogBuffer: Failed to log buffer into file "' + filename + '". ErrMsg: ' + e.Message);
- f.Free;
- end;
- end;
-end;
-
-end.
-
-
diff --git a/Game/Code/Classes/ULyrics.pas b/Game/Code/Classes/ULyrics.pas
deleted file mode 100644
index 305cb91f..00000000
--- a/Game/Code/Classes/ULyrics.pas
+++ /dev/null
@@ -1,884 +0,0 @@
-unit ULyrics;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- gl,
- glext,
- UTexture,
- UThemes,
- UMusic;
-
-type
- // stores two textures for enabled/disabled states
- TPlayerIconTex = array [0..1] of TTexture;
-
- PLyricWord = ^TLyricWord;
- TLyricWord = record
- X: Real; // left corner
- Width: Real; // width
- Start: Cardinal; // start of the word in quarters (beats)
- Length: Cardinal; // length of the word in quarters
- Text: String; // text
- Freestyle: Boolean; // is freestyle?
- end;
- ALyricWord = array of TLyricWord;
-
- TLyricLine = class
- public
- Text: String; // text
- Tex: glUInt; // texture of the text
- Width: Real; // width
- Size: Byte; // fontsize
- Words: ALyricWord; // words in this line
- CurWord: Integer; // current active word idx (only valid if line is active)
- Start: Integer; // start of this line in quarters (Note: negative start values are possible due to gap)
- StartNote: Integer; // start of the first note of this line in quarters
- Length: Integer; // length in quarters (from start of first to the end of the last note)
- HasFreestyle: Boolean; // one or more word are freestyle?
- CountFreestyle: Integer; // how often there is a change from freestyle to non freestyle in this line
- Players: Byte; // players that should sing that line (bitset, Player1: 1, Player2: 2, Player3: 4)
- LastLine: Boolean; // is this the last line of the song?
-
- constructor Create();
- destructor Destroy(); override;
- procedure Reset();
- end;
-
- TLyricEngine = class
- private
- LastDrawBeat: Real;
- UpperLine: TLyricLine; // first line displayed (top)
- LowerLine: TLyricLine; // second lind displayed (bottom)
- QueueLine: TLyricLine; // third line (will be displayed when lower line is finished)
-
- IndicatorTex: TTexture; // texture for lyric indikator
- BallTex: TTexture; // texture of the ball for the lyric effect
-
- QueueFull: Boolean; // set to true if the queue is full and a line will be replaced with the next AddLine
- LCounter: Word; // line counter
-
- // duet mode - textures for player icons
- // FIXME: do not use a fixed player count, use MAX_PLAYERS instead
- PlayerIconTex: array[0..5] of TPlayerIconTex;
-
- //Some helper Procedures for Lyric Drawing
- procedure DrawLyrics (Beat: Real);
- procedure DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real);
- procedure DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real);
- procedure DrawBall(XBall, YBall, Alpha:Real);
-
- public
- // positions, line specific settings
- UpperLineX: Real; //X Start Pos of UpperLine
- UpperLineW: Real; //Width of UpperLine with Icon(s) and Text
- UpperLineY: Real; //Y Start Pos of UpperLine
- UpperLineSize: Byte; //Max Size of Lyrics Text in UpperLine
-
- LowerLineX: Real; //X Start Pos of LowerLine
- LowerLineW: Real; //Width of LowerLine with Icon(s) and Text
- LowerLineY: Real; //Y Start Pos of LowerLine
- LowerLineSize: Byte; //Max Size of Lyrics Text in LowerLine
-
- // display propertys
- LineColor_en: TRGBA; //Color of Words in an Enabled Line
- LineColor_dis: TRGBA; //Color of Words in a Disabled Line
- LineColor_act: TRGBA; //Color of teh active Word
- FontStyle: Byte; //Font for the Lyric Text
- FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen
-
- { // currently not used
- FadeInEffect: Byte; //Effect for Line Fading in: 0: No Effect; 1: Fade Effect; 2: Move Upwards from Bottom to Pos
- FadeOutEffect: Byte; //Effect for Line Fading out: 0: No Effect; 1: Fade Effect; 2: Move Upwards
- }
-
- UseLinearFilter: Boolean; //Should Linear Tex Filter be used
-
- // song specific settings
- BPM: Real;
- Resolution: Integer;
-
- // properties to easily read options of this class
- property IsQueueFull: Boolean read QueueFull; // line in queue?
- property LineCounter: Word read LCounter; // lines that were progressed so far (after last clear)
-
- procedure AddLine(Line: PLine); // adds a line to the queue, if there is space
- procedure Draw (Beat: Real); // draw the current (active at beat) lyrics
-
- // clears all cached song specific information
- procedure Clear(cBPM: Real = 0; cResolution: Integer = 0);
-
- function GetUpperLine(): TLyricLine;
- function GetLowerLine(): TLyricLine;
-
- function GetUpperLineIndex(): Integer;
-
- constructor Create; overload;
- constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS: Real); overload;
- procedure LoadTextures;
- destructor Destroy; override;
- end;
-
-implementation
-
-uses SysUtils,
- USkins,
- TextGL,
- UGraphic,
- UDisplay,
- ULog,
- math,
- UIni;
-
-//-----------
-//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else
-//-----------
-procedure glColorRGB(Color: TRGB); overload;
-begin
- glColor3f(Color.R, Color.G, Color.B);
-end;
-
-procedure glColorRGB(Color: TRGB; Alpha: Real); overload;
-begin
- glColor4f(Color.R, Color.G, Color.B, Alpha);
-end;
-
-procedure glColorRGB(Color: TRGBA); overload;
-begin
- glColor4f(Color.R, Color.G, Color.B, Color.A);
-end;
-
-procedure glColorRGB(Color: TRGBA; Alpha: Real); overload;
-begin
- glColor4f(Color.R, Color.G, Color.B, Min(Color.A, Alpha));
-end;
-
-{ TLyricLine }
-
-constructor TLyricLine.Create();
-begin
- inherited;
- Reset();
-end;
-
-destructor TLyricLine.Destroy();
-begin
- SetLength(Words, 0);
- inherited;
-end;
-
-procedure TLyricLine.Reset();
-begin
- Start := 0;
- StartNote := 0;
- Length := 0;
- LastLine := False;
-
- Text := '';
- Width := 0;
-
- // duet mode: players of that line (default: all)
- Players := $FF;
-
- SetLength(Words, 0);
- CurWord := -1;
-
- HasFreestyle := False;
- CountFreestyle := 0;
-end;
-
-
-{ TLyricEngine }
-
-//---------------
-// Create - Constructor, just get Memory
-//---------------
-constructor TLyricEngine.Create;
-begin
- inherited;
-
- BPM := 0;
- Resolution := 0;
- LCounter := 0;
- QueueFull := False;
-
- UpperLine := TLyricLine.Create;
- LowerLine := TLyricLine.Create;
- QueueLine := TLyricLine.Create;
-
- UseLinearFilter := True;
- LastDrawBeat := 0;
-end;
-
-constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real);
-begin
- Create;
-
- UpperLineX := ULX;
- UpperLineW := ULW;
- UpperLineY := ULY;
- UpperLineSize := Trunc(ULS);
-
- LowerLineX := LLX;
- LowerLineW := LLW;
- LowerLineY := LLY;
- LowerLineSize := Trunc(LLS);
-
- LoadTextures;
-end;
-
-
-//---------------
-// Destroy - Frees Memory
-//---------------
-destructor TLyricEngine.Destroy;
-begin
- UpperLine.Free;
- LowerLine.Free;
- QueueLine.Free;
- inherited;
-end;
-
-//---------------
-// Clear - Clears all cached Song specific Information
-//---------------
-procedure TLyricEngine.Clear(cBPM: Real; cResolution: Integer);
-begin
- BPM := cBPM;
- Resolution := cResolution;
- LCounter := 0;
- QueueFull := False;
-
- LastDrawBeat:=0;
-end;
-
-
-//---------------
-// LoadTextures - Load Player Textures and Create Lyric Textures
-//---------------
-procedure TLyricEngine.LoadTextures;
-var
- I: Integer;
-
- function CreateLineTex: glUint;
- begin
- // generate and bind Texture
- glGenTextures(1, @Result);
- glBindTexture(GL_TEXTURE_2D, Result);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if UseLinearFilter then
- begin
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- end;
- end;
-
-begin
-
- // lyric indicator (bar that indicates when the line start)
- IndicatorTex := Texture.LoadTexture(Skin.GetTextureFileName('LyricHelpBar'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
-
- // ball for current word hover in ball effect
- BallTex := Texture.LoadTexture(Skin.GetTextureFileName('Ball'), TEXTURE_TYPE_TRANSPARENT, 0);
-
- // duet mode: load player icon
- for I := 0 to 5 do
- begin
- PlayerIconTex[I][0] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0);
- PlayerIconTex[I][1] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0);
- end;
-
- // create line textures
- UpperLine.Tex := CreateLineTex;
- LowerLine.Tex := CreateLineTex;
- QueueLine.Tex := CreateLineTex;
-end;
-
-
-//---------------
-// AddLine - Adds LyricLine to queue
-// The LyricEngine stores three lines in its queue:
-// UpperLine: the upper line displayed in the lyrics
-// LowerLine: the lower line displayed in the lyrics
-// QueueLine: an offscreen line that precedes LowerLine
-// If the queue is full the next call to AddLine will replace UpperLine with
-// LowerLine, LowerLine with QueueLine and QueueLine with the Line parameter.
-//---------------
-procedure TLyricEngine.AddLine(Line: PLine);
-var
- LyricLine: TLyricLine;
- PosX: Real;
- I: Integer;
- CurWord: PLyricWord;
- RenderPass: Integer;
-
- function CalcWidth(LyricLine: TLyricLine): Real;
- begin
- Result := glTextWidth(PChar(LyricLine.Text));
-
- Result := Result + (LyricLine.CountFreestyle * 10);
-
- // if the line ends with a freestyle not, then leave the place to finish to draw the text italic
- if (LyricLine.Words[High(LyricLine.Words)].Freestyle) then
- Result := Result + 12;
- end;
-
-begin
- // only add lines, if there is space
- if not IsQueueFull then
- begin
- // set LyricLine to line to write to
- if (LineCounter = 0) then
- LyricLine := UpperLine
- else if (LineCounter = 1) then
- LyricLine := LowerLine
- else
- begin
- // now the queue is full
- LyricLine := QueueLine;
- QueueFull := True;
- end;
- end
- else
- begin // rotate lines (round-robin-like)
- LyricLine := UpperLine;
- UpperLine := LowerLine;
- LowerLine := QueueLine;
- QueueLine := LyricLine;
- end;
-
- // reset line state
- LyricLine.Reset();
-
- // check if sentence has notes
- if (Line <> nil) and (Length(Line.Note) > 0) then
- begin
- // copy values from SongLine to LyricLine
- LyricLine.Start := Line.Start;
- LyricLine.StartNote := Line.Note[0].Start;
- LyricLine.Length := Line.Note[High(Line.Note)].Start +
- Line.Note[High(Line.Note)].Length -
- Line.Note[0].Start;
- LyricLine.LastLine := Line.LastLine;
-
- // copy words
- SetLength(LyricLine.Words, Length(Line.Note));
- for I := 0 to High(Line.Note) do
- begin
- LyricLine.Words[I].Start := Line.Note[I].Start;
- LyricLine.Words[I].Length := Line.Note[I].Length;
- LyricLine.Words[I].Text := Line.Note[I].Text;
- LyricLine.Words[I].Freestyle := Line.Note[I].NoteType = ntFreestyle;
-
- LyricLine.HasFreestyle := LyricLine.HasFreestyle or LyricLine.Words[I].Freestyle;
- LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text;
-
- if (I > 0) and
- LyricLine.Words[I-1].Freestyle and
- not LyricLine.Words[I].Freestyle then
- begin
- Inc(LyricLine.CountFreestyle);
- end;
- end;
-
- // set font params
- SetFontStyle(FontStyle);
- SetFontPos(0, 0);
- LyricLine.Size := UpperLineSize;
- SetFontSize(LyricLine.Size);
- SetFontItalic(False);
- SetFontReflection(False, 0);
- glColor4f(1, 1, 1, 1);
-
- // change fontsize to fit the screen
- LyricLine.Width := CalcWidth(LyricLine);
- while (LyricLine.Width > UpperLineW) do
- begin
- Dec(LyricLine.Size);
-
- if (LyricLine.Size <=1) then
- Break;
-
- SetFontSize(LyricLine.Size);
- LyricLine.Width := CalcWidth(LyricLine);
- end;
-
- // Offscreen rendering of LyricTexture:
- // First we will create a white transparent background to draw on.
- // If the text was simply drawn to the screen with blending, the translucent
- // parts of the text would be merged with the current color of the background.
- // This would result in a texture that partly contains the screen we are
- // drawing on. This will be visible in the fonts outline when the LyricTexture
- // is drawn to the screen later.
- // So we have to draw the text in TWO passes.
- // At the first pass we copy the characters to the back-buffer in such a way
- // that preceding characters are not repainted by following chars (otherwise
- // some characters would be blended twice in the 2nd pass).
- // To achieve this we disable blending and enable the depth-test. The z-buffer
- // is used as a mask or replacement for the missing stencil-buffer. A z-value
- // of 1 means the pixel was not assigned yet, whereas 0 stands for a pixel
- // that was already drawn on. In addition we set the depth-func in such a way
- // that assigned pixels (0) will not be drawn a second time.
- // At the second pass we draw the text with blending and without depth-test.
- // This will blend overlapping characters but not the background as it was
- // repainted in the first pass.
-
- glPushAttrib(GL_VIEWPORT_BIT or GL_DEPTH_BUFFER_BIT);
- glViewPort(0, 0, 800, 600);
- glClearColor(0, 0, 0, 0);
- glDepthRange(0, 1);
- glClearDepth(1);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- SetFontZ(0);
-
- // assure blending is off and the correct depth-func is enabled
- glDisable(GL_BLEND);
- glDepthFunc(GL_LESS);
-
- // we need two passes to draw the font onto the screen.
- for RenderPass := 0 to 1 do
- begin
- if (RenderPass = 0) then
- begin
- // first pass: simply copy each character to the screen without overlapping.
- SetFontBlend(false);
- glEnable(GL_DEPTH_TEST);
- end
- else
- begin
- // second pass: now we will blend overlapping characters.
- SetFontBlend(true);
- glDisable(GL_DEPTH_TEST);
- end;
-
- PosX := 0;
-
- // set word positions and line size and draw the line to the back-buffer
- for I := 0 to High(LyricLine.Words) do
- begin
- CurWord := @LyricLine.Words[I];
-
- SetFontItalic(CurWord.Freestyle);
-
- CurWord.X := PosX;
-
- // Draw Lyrics
- SetFontPos(PosX, 0);
- glPrint(PChar(CurWord.Text));
-
- CurWord.Width := glTextWidth(PChar(CurWord.Text));
- if CurWord.Freestyle then
- begin
- if (I < High(LyricLine.Words)) and not LyricLine.Words[I+1].Freestyle then
- CurWord.Width := CurWord.Width + 10
- else if (I = High(LyricLine.Words)) then
- CurWord.Width := CurWord.Width + 12;
- end;
- PosX := PosX + CurWord.Width;
- end;
- end;
-
- // copy back-buffer to texture
- glBindTexture(GL_TEXTURE_2D, LyricLine.Tex);
- // FIXME: this does not work this way
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 600-64, 1024, 64, 0);
- if (glGetError() <> GL_NO_ERROR) then
- Log.LogError('Creation of Lyrics-texture failed', 'TLyricEngine.AddLine');
-
- // restore OpenGL state
- glPopAttrib();
-
- // clear buffer (use white to avoid flimmering if no cover/video is available)
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end; // if (Line <> nil) and (Length(Line.Note) > 0)
-
- // increase the counter
- Inc(LCounter);
-end;
-
-
-//---------------
-// Draw - Procedure Draws Lyrics; Beat is curent Beat in Quarters
-// Draw just manage the Lyrics, drawing is done by a call of DrawLyrics
-//---------------
-procedure TLyricEngine.Draw(Beat: Real);
-begin
- DrawLyrics(Beat);
- LastDrawBeat := Beat;
-end;
-
-//---------------
-// DrawLyrics(private) - Helper for Draw; main Drawing procedure
-//---------------
-procedure TLyricEngine.DrawLyrics(Beat: Real);
-begin
- DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat);
- DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat);
-end;
-
-//---------------
-// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon
-//---------------
-procedure TLyricEngine.DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real);
-var
- IEnabled: Byte;
-begin
- if Enabled then
- IEnabled := 0
- else
- IEnabled := 1;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, PlayerIconTex[Player][IEnabled].TexNum);
-
- glColor4f(1, 1, 1, Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y + Size);
- glTexCoord2f(1, 1); glVertex2f(X + Size, Y + Size);
- glTexCoord2f(1, 0); glVertex2f(X + Size, Y);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-//---------------
-// DrawBall(private) - Helper for Draw; Draws the Ball over the LyricLine if needed
-//---------------
-procedure TLyricEngine.DrawBall(XBall, YBall, Alpha: Real);
-begin
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, BallTex.TexNum);
-
- glColor4f(1, 1, 1, Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(XBall - 10, YBall);
- glTexCoord2f(0, 1); glVertex2f(XBall - 10, YBall + 20);
- glTexCoord2f(1, 1); glVertex2f(XBall + 10, YBall + 20);
- glTexCoord2f(1, 0); glVertex2f(XBall + 10, YBall);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-//---------------
-// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine
-//---------------
-procedure TLyricEngine.DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real);
-var
- CurWordStart, CurWordEnd: Real; // screen coordinates of current word and the rest of the sentence
- FreestyleDiff: Integer; // difference between top and bottom coordiantes for freestyle lyrics
- Progress: Real; // progress of singing the current word
- LyricX: Real; // left
- LyricX2: Real; // right
- LyricY: Real; // top
- LyricsHeight: Real; // height the lyrics are displayed
- Alpha: Real; // alphalevel to fade out at end
- CurWord, LastWord: PLyricWord; // current word
-
- {// duet mode
- IconSize: Real; // size of player icons
- IconAlpha: Real; // alpha level of player icons
- }
-begin
- // do not draw empty lines
- // Note: lines with no words in it do not have a valid texture
- if (Length(Line.Words) = 0) or
- (Line.Width <= 0) then
- begin
- Exit;
- end;
-
- // this is actually a bit more than the real font size
- // it helps adjusting the "zoom-center"
- LyricsHeight := 30.5 * (Line.Size/10);
-
- {
- // duet mode
- IconSize := (2 * Size);
- IconAlpha := Frac(Beat/(Resolution*4));
-
- DrawPlayerIcon (0, True, X, Y + (42 - IconSize) / 2 , IconSize, IconAlpha);
- DrawPlayerIcon (1, True, X + IconSize + 1, Y + (42 - IconSize) / 2, IconSize, IconAlpha);
- DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y + (42 - IconSize) / 2, IconSize, IconAlpha);
- }
-
- LyricX := X + W/2 - Line.Width/2;
- LyricX2 := LyricX + Line.Width;
-
- // maybe center smaller lines
- //LyricY := Y;
- LyricY := Y + ((Size / Line.Size - 1) * LyricsHeight) / 2;
-
- Alpha := 1;
-
- // check if this line is active (at least its first note must be active)
- if (Beat >= Line.StartNote) then
- begin
- // if this line just got active, CurWord is -1,
- // this means we should try to make the first word active
- if (Line.CurWord = -1) then
- Line.CurWord := 0;
-
- // check if the current active word is still active.
- // Otherwise proceed to the next word if there is one in this line.
- // Note: the max. value of Line.CurWord is High(Line.Words)
- if (Line.CurWord < High(Line.Words)) and
- (Beat >= Line.Words[Line.CurWord + 1].Start) then
- begin
- Inc(Line.CurWord);
- end;
-
- FreestyleDiff := 0;
-
- // determine current and last word in this line.
- // If the end of the line is reached use the last word as current word.
- LastWord := @Line.Words[High(Line.Words)];
- CurWord := @Line.Words[Line.CurWord];
-
- // calc the progress of the lyrics effect
- Progress := (Beat - CurWord.Start) / CurWord.Length;
- if Progress >= 1 then
- Progress := 1;
- if Progress <= 0 then
- Progress := 0;
-
- // last word of this line finished, but this line did not hide -> fade out
- if Line.LastLine and
- (Beat > LastWord.Start + LastWord.Length) then
- begin
- Alpha := 1 - (Beat - (LastWord.Start + LastWord.Length)) / 15;
- if (Alpha < 0) then
- Alpha := 0;
- end;
-
- // determine the start-/end positions of the fragment of the current word
- CurWordStart := CurWord.X;
- CurWordEnd := CurWord.X + CurWord.Width;
-
- // Slide Effect
- // simply paint the active texture to the current position
- if Ini.LyricsEffect = 2 then
- begin
- CurWordStart := CurWordStart + CurWord.Width * Progress;
- CurWordEnd := CurWordStart;
- end;
-
- if CurWord.Freestyle then
- begin
- if (Line.CurWord < High(Line.Words)) and
- (not Line.Words[Line.CurWord + 1].Freestyle) then
- begin
- FreestyleDiff := 2;
- end
- else
- begin
- FreestyleDiff := 12;
- CurWordStart := CurWordStart - 1;
- CurWordEnd := CurWordEnd - 2;
- end;
- end;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, Line.Tex);
-
- // draw sentence up to current word
- // type 0: simple lyric effect
- // type 3: ball lyric effect
- // type 4: shift lyric effect
- if (Ini.LyricsEffect in [0, 3, 4]) then
- // ball lyric effect - only highlight current word and not that ones before in this line
- glColorRGB(LineColor_en, Alpha)
- else
- glColorRGB(LineColor_act, Alpha);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1);
- glVertex2f(LyricX, LyricY);
-
- glTexCoord2f(0, 1-LyricsHeight/64);
- glVertex2f(LyricX, LyricY + LyricsHeight);
-
- glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64);
- glVertex2f(LyricX + CurWordStart, LyricY + LyricsHeight);
-
- glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
- glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY);
- glEnd;
-
- // draw rest of sentence
- glColorRGB(LineColor_en, Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
- glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY);
-
- glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64);
- glVertex2f(LyricX + CurWordEnd, LyricY + LyricsHeight);
-
- glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64);
- glVertex2f(LyricX2, LyricY + LyricsHeight);
-
- glTexCoord2f(Line.Width/1024, 1);
- glVertex2f(LyricX2, LyricY);
- glEnd;
-
- // draw active word:
- // type 0: simple lyric effect
- // type 3: ball lyric effect
- // type 4: shift lyric effect
- // only change the color of the current word
- if (Ini.LyricsEffect in [0, 3, 4]) then
- begin
- if (Ini.LyricsEffect = 4) then
- LyricY := LyricY - 8 * (1-Progress);
-
- glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
- glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY);
-
- glTexCoord2f(CurWordStart/1024, 0);
- glVertex2f(LyricX + CurWordStart, LyricY + 64);
-
- glTexCoord2f(CurWordEnd/1024, 0);
- glVertex2f(LyricX + CurWordEnd, LyricY + 64);
-
- glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
- glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY);
- glEnd;
-
- if (Ini.LyricsEffect = 4) then
- LyricY := LyricY + 8 * (1-Progress);
- end
-
- // draw active word:
- // type 1: zoom lyric effect
- // change color and zoom current word
- else if Ini.LyricsEffect = 1 then
- begin
- glPushMatrix;
-
- glTranslatef(LyricX + CurWordStart + (CurWordEnd-CurWordStart)/2,
- LyricY + LyricsHeight/2, 0);
-
- // set current zoom factor
- glScalef(1.0 + (1-Progress) * 0.5, 1.0 + (1-Progress) * 0.5, 1.0);
-
- glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
- glVertex2f(-(CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2);
-
- glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64);
- glVertex2f(-(CurWordEnd-CurWordStart)/2, LyricsHeight/2);
-
- glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64);
- glVertex2f((CurWordEnd-CurWordStart)/2, LyricsHeight/2);
-
- glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
- glVertex2f((CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2);
- glEnd;
-
- glPopMatrix;
- end;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // type 3: ball lyric effect
- if Ini.LyricsEffect = 3 then
- begin
- DrawBall(LyricX + CurWordStart + (CurWordEnd-CurWordStart) * Progress,
- LyricY - 15 - 15*sin(Progress * Pi), Alpha);
- end;
- end
- else
- begin
- // this section is called if the whole line can be drawn at once and no
- // word has to be emphasized.
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Line.Tex);
-
- // enable the upper, disable the lower line
- if (Line = UpperLine) then
- glColorRGB(LineColor_en)
- else
- glColorRGB(LineColor_dis);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1);
- glVertex2f(LyricX, LyricY);
-
- glTexCoord2f(0, 1-LyricsHeight/64);
- glVertex2f(LyricX, LyricY + LyricsHeight);
-
- glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64);
- glVertex2f(LyricX2, LyricY + LyricsHeight);
-
- glTexCoord2f(Line.Width/1024, 1);
- glVertex2f(LyricX2, LyricY);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end;
-end;
-
-//---------------
-// GetUpperLine() - Returns a reference to the upper line
-//---------------
-function TLyricEngine.GetUpperLine(): TLyricLine;
-begin
- Result := UpperLine;
-end;
-
-//---------------
-// GetLowerLine() - Returns a reference to the lower line
-//---------------
-function TLyricEngine.GetLowerLine(): TLyricLine;
-begin
- Result := LowerLine;
-end;
-
-//---------------
-// GetUpperLineIndex() - Returns the index of the upper line
-//---------------
-function TLyricEngine.GetUpperLineIndex(): Integer;
-const
- QUEUE_SIZE = 3;
-begin
- // no line in queue
- if (LineCounter <= 0) then
- Result := -1
- // no line has been removed from queue yet
- else if (LineCounter <= QUEUE_SIZE) then
- Result := 0
- // lines have been removed from queue already
- else
- Result := LineCounter - QUEUE_SIZE;
-end;
-
-end.
-
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
deleted file mode 100644
index da9df6d3..00000000
--- a/Game/Code/Classes/UMain.pas
+++ /dev/null
@@ -1,1107 +0,0 @@
-unit UMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SysUtils,
- Classes,
- SDL,
- UMusic,
- URecord,
- UTime,
- UDisplay,
- UIni,
- ULog,
- ULyrics,
- UScreenSing,
- USong,
- gl;
-
-type
- PPLayerNote = ^TPlayerNote;
- TPlayerNote = record
- Start: integer;
- Length: integer;
- Detect: real; // accurate place, detected in the note
- Tone: real;
- Perfect: boolean; // true if the note matches the original one, lit the star
- Hit: boolean; // true if the note Hits the Line
- end;
-
- PPLayer = ^TPlayer;
- TPlayer = record
- Name: string;
-
- // Index in Teaminfo record
- TeamID: Byte;
- PlayerID: Byte;
-
- // Scores
- Score: real;
- ScoreLine: real;
- ScoreGolden: real;
-
- ScoreInt: integer;
- ScoreLineInt: integer;
- ScoreGoldenInt: integer;
- ScoreTotalInt: integer;
-
- // LineBonus
- ScoreLast: Real;//Last Line Score
-
- // PerfectLineTwinkle (effect)
- LastSentencePerfect: Boolean;
-
- HighNote: integer; // index of last note (= High(Note)?)
- LengthNote: integer; // number of notes (= Length(Note)?).
- Note: array of TPlayerNote;
- end;
-
-
-var
- // Absolute Paths
- GamePath: string;
- SoundPath: string;
- SongPaths: TStringList;
- LogPath: string;
- ThemePath: string;
- SkinsPath: string;
- ScreenshotsPath: string;
- CoverPaths: TStringList;
- LanguagesPath: string;
- PluginPath: string;
- VisualsPath: string;
- ResourcesPath: string;
- PlayListPath: string;
-
- Done: Boolean;
- Event: TSDL_event;
- // FIXME: ConversionFileName should not be global
- ConversionFileName: string;
- Restart: boolean;
-
- // player and music info
- Player: array of TPlayer;
- PlayersPlay: integer;
-
- CurrentSong : TSong;
-
-const
- MAX_SONG_SCORE = 10000; // max. achievable points per song
- MAX_SONG_LINE_BONUS = 1000; // max. achievable line bonus per song
-
-function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
-procedure InitializePaths;
-procedure AddSongPath(const Path: string);
-
-Procedure Main;
-procedure MainLoop;
-procedure CheckEvents;
-procedure Sing(Screen: TScreenSing);
-procedure NewSentence(Screen: TScreenSing);
-procedure NewBeatClick(Screen: TScreenSing); // executed when on then new beat for click
-procedure NewBeatDetect(Screen: TScreenSing); // executed when on then new beat for detection
-procedure NewNote(Screen: TScreenSing); // detect note
-function GetMidBeat(Time: real): real;
-function GetTimeFromBeat(Beat: integer): real;
-procedure ClearScores(PlayerNum: integer);
-
-implementation
-
-uses
- Math,
- StrUtils,
- USongs,
- UJoystick,
- UCommandLine,
- ULanguage,
- //SDL_ttf,
- USkins,
- UCovers,
- UCatCovers,
- UDataBase,
- UPlaylist,
- UDLLManager,
- UParty,
- UConfig,
- UCore,
- UCommon,
- UGraphic,
- UGraphicClasses,
- UPluginDefs,
- UPlatform,
- UThemes;
-
-
-
-
-procedure Main;
-var
- WndTitle: string;
-begin
- try
- WndTitle := USDXVersionStr;
-
- Platform.Init;
-
- if Platform.TerminateIfAlreadyRunning(WndTitle) then
- Exit;
-
- // fix floating-point exceptions (FPE)
- DisableFloatingPointExceptions();
- // fix the locale for string-to-float parsing in C-libs
- SetDefaultNumericLocale();
-
- // setup separators for parsing
- // Note: ThousandSeparator must be set because of a bug in TIniFile.ReadFloat
- ThousandSeparator := ',';
- DecimalSeparator := '.';
-
- //------------------------------
- //StartUp - Create Classes and Load Files
- //------------------------------
-
- // Initialize SDL
- // Without SDL_INIT_TIMER SDL_GetTicks() might return strange values
- SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER);
- SDL_EnableUnicode(1);
-
- USTime := TTime.Create;
- VideoBGTimer := TRelativeTimer.Create;
-
- // Commandline Parameter Parser
- Params := TCMDParams.Create;
-
- // Log + Benchmark
- Log := TLog.Create;
- Log.Title := WndTitle;
- Log.FileOutputEnabled := 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_ttf (Not used yet, maybe in version 1.5)
- 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;
-
- //it's possible that this is the first run, create a .ini file if neccessary
- Log.LogStatus('Write Ini', 'Initialization');
- Ini.Save;
-
- // 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);
-
- // Lyrics-engine with media reference timer
- LyricsState := TLyricsState.Create();
-
- // 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 := TCoverDatabase.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 (Platform.GetGameUserPath + '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 Particle 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.LogStatus('Creating Core', 'Initialization');
- {Core := TCore.Create(
- USDXShortVersionStr,
- MakeVersion(USDX_VERSION_MAJOR,
- USDX_VERSION_MINOR,
- USDX_VERSION_RELEASE,
- chr(0))
- ); }
-
- Log.LogStatus('Running Core', 'Initialization');
- //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
-
- FinalizeMedia();
-
- //TTF_Quit();
- SDL_Quit();
-
- if assigned(Log) then
- begin
- Log.LogStatus('Main Loop', 'Finished');
- Log.Free;
- end;
- end;
-end;
-
-procedure MainLoop;
-var
- Delay: integer;
-const
- MAX_FPS = 100;
-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;
-
- // delay
- CountMidTime;
-
- Delay := Floor(1000 / MAX_FPS - 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;
- // Note: do NOT call SDL_SetVideoMode on Windows and MacOSX here.
- // This would create a new OpenGL render-context and all texture data
- // would be invalidated.
- // On Linux the mode MUST be resetted, otherwise graphics will be corrupted.
- {$IFDEF LINUX}
- if boolean( Ini.FullScreen ) then
- SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN)
- else
- SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE);
- {$ENDIF}
- 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 ) );
-
- // FIXME: SDL_SetVideoMode creates a new OpenGL RC so we have to
- // reload all texture data (-> whitescreen bug).
- // Only Linux is able to handle screen-switching this way.
- {$IFDEF LINUX}
- 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);
- {$ENDIF}
- end
- // if print is pressed -> make screenshot and save to screenshot path
- else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then
- Display.SaveScreenShot
- // 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)
- else
- begin
- // check if screen wants 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 // if ask-for-exit is disabled then simply exit
- begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
- end;
- end;
-
- end;
- end;
- SDL_JOYAXISMOTION:
- begin
- // not implemented
- end;
- SDL_JOYBUTTONDOWN:
- begin
- // not implemented
- 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;
-begin
- // static BPM
- if Length(CurrentSong.BPM) = 1 then
- begin
- Result := Time * CurrentSong.BPM[0].BPM / 60;
- end
- // variable BPM
- else 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
- // invalid BPM
- else
- begin
- Result := 0;
- end;
-end;
-
-function GetTimeFromBeat(Beat: integer): real;
-var
- CurBPM: integer;
-begin
- // static BPM
- if Length(CurrentSong.BPM) = 1 then
- begin
- Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM;
- end
- // variable BPM
- else 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
- // invalid BPM
- else
- begin
- Result := 0;
- end;
-end;
-
-procedure Sing(Screen: TScreenSing);
-var
- Count: integer;
- CountGr: integer;
- CP: integer;
- Done: real;
- N: integer;
- CurLine: PLine;
- CurNote: PLineFragment;
-begin
- LyricsState.UpdateBeats();
-
- // sentences routines
- for CountGr := 0 to 0 do //High(Lines)
- begin;
- CP := CountGr;
- // old parts
- LyricsState.OldLine := Lines[CP].Current;
-
- // choose current parts
- for Count := 0 to Lines[CP].High do
- begin
- if LyricsState.CurrentBeat >= Lines[CP].Line[Count].Start then
- Lines[CP].Current := Count;
- end;
-
- // clean player note if there is a new line
- // (optimization on halfbeat time)
- if Lines[CP].Current <> LyricsState.OldLine then
- NewSentence(Screen);
-
- end; // for CountGr
-
- // make some operations on clicks
- if {(LyricsState.CurrentBeatC >= 0) and }(LyricsState.OldBeatC <> LyricsState.CurrentBeatC) then
- NewBeatClick(Screen);
-
- // make some operations when detecting new voice pitch
- if (LyricsState.CurrentBeatD >= 0) and (LyricsState.OldBeatD <> LyricsState.CurrentBeatD) then
- NewBeatDetect(Screen);
-
- CurLine := @Lines[0].Line[Lines[0].Current];
-
- // remove moving text
- Done := 1;
- for N := 0 to CurLine.HighNote do
- begin
- CurNote := @CurLine.Note[N];
- if (CurNote.Start <= LyricsState.MidBeat) and
- (CurNote.Start + CurNote.Length >= LyricsState.MidBeat) then
- begin
- Done := (LyricsState.MidBeat - CurNote.Start) / CurNote.Length;
- end;
- end;
-end;
-
-procedure NewSentence(Screen: TScreenSing);
-var
- i: Integer;
-begin
- // clean note of player
- for i := 0 to High(Player) do
- begin
- Player[i].LengthNote := 0;
- Player[i].HighNote := -1;
- SetLength(Player[i].Note, 0);
- end;
-
- // on sentence change...
- Screen.onSentenceChange(Lines[0].Current);
-end;
-
-procedure NewBeatClick;
-var
- Count: integer;
-begin
- // beat click
- if ((Ini.BeatClick = 1) and
- ((LyricsState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0)) then
- begin
- AudioPlayback.PlaySound(SoundLib.Click);
- end;
-
- for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do
- begin
- if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LyricsState.CurrentBeatC) then
- begin
- // click assist
- if Ini.ClickAssist = 1 then
- AudioPlayback.PlaySound(SoundLib.Click);
-
- // drum machine
- (*
- TempBeat := LyricsState.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;
-end;
-
-procedure NewBeatDetect(Screen: TScreenSing);
-begin
- NewNote(Screen);
-end;
-
-procedure NewNote(Screen: TScreenSing);
-var
- LineFragmentIndex: integer;
- CurrentLineFragment: PLineFragment;
- PlayerIndex: integer;
- CurrentSound: TCaptureBuffer;
- CurrentPlayer: PPlayer;
- LastPlayerNote: PPLayerNote;
- Line: PLine;
- SentenceIndex: integer;
- SentenceMin: integer;
- SentenceMax: integer;
- SentenceDetected: integer; // sentence of detected note
- NoteAvailable: boolean;
- NewNote: boolean;
- Range: integer;
- NoteHit: boolean;
- MaxSongPoints: integer; // max. points for the song (without line bonus)
- MaxLinePoints: Real; // max. points for the current line
-begin
- // TODO: add duet mode support
- // use Lines[LineSetIndex] with LineSetIndex depending on the current player
-
- // count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
- SentenceMin := Lines[0].Current-1;
- if (SentenceMin < 0) then
- SentenceMin := 0;
- SentenceMax := Lines[0].Current;
-
- // check for an active note at the current time defined in the lyrics
- NoteAvailable := false;
- SentenceDetected := SentenceMin;
- for SentenceIndex := SentenceMin to SentenceMax do
- begin
- Line := @Lines[0].Line[SentenceIndex];
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- // check if line is active
- if ((CurrentLineFragment.Start <= LyricsState.CurrentBeatD) and
- (CurrentLineFragment.Start + CurrentLineFragment.Length-1 >= LyricsState.CurrentBeatD)) and
- (CurrentLineFragment.NoteType <> ntFreestyle) and // but ignore FreeStyle notes
- (CurrentLineFragment.Length > 0) then // and make sure the note lengths is at least 1
- begin
- SentenceDetected := SentenceIndex;
- NoteAvailable := true;
- Break;
- end;
- end;
- // TODO: break here, if NoteAvailable is true? We would then use the first instead
- // of the last note matching the current beat if notes overlap. But notes
- // should not overlap at all.
- //if (NoteAvailable) then
- // Break;
- end;
-
- // analyze player signals
- for PlayerIndex := 0 to PlayersPlay-1 do
- begin
- CurrentPlayer := @Player[PlayerIndex];
- CurrentSound := AudioInputProcessor.Sound[PlayerIndex];
- LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
-
- // analyze buffer
- CurrentSound.AnalyzeBuffer;
-
- // add some noise
- // TODO: do we need this?
- //LyricsState.Tone := LyricsState.Tone + Round(Random(3)) - 1;
-
- // add note if possible
- if (CurrentSound.ToneValid and NoteAvailable) then
- begin
- Line := @Lines[0].Line[SentenceDetected];
-
- // process until last note
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- if (CurrentLineFragment.Start <= LyricsState.OldBeatD+1) and
- (CurrentLineFragment.Start + CurrentLineFragment.Length > LyricsState.OldBeatD+1) then
- begin
- // compare notes (from song-file and from player)
-
- // move players tone to proper octave
- while (CurrentSound.Tone - CurrentLineFragment.Tone > 6) do
- CurrentSound.Tone := CurrentSound.Tone - 12;
-
- while (CurrentSound.Tone - CurrentLineFragment.Tone < -6) do
- CurrentSound.Tone := CurrentSound.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;
-
- // check if the player hit the correct tone within the tolerated range
- if (Abs(CurrentLineFragment.Tone - CurrentSound.Tone) <= Range) then
- begin
- // adjust the players tone to the correct one
- // TODO: do we need to do this?
- CurrentSound.Tone := CurrentLineFragment.Tone;
-
- // half size notes patch
- NoteHit := true;
-
- if (Ini.LineBonus > 0) then
- MaxSongPoints := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS
- else
- MaxSongPoints := MAX_SONG_SCORE;
-
- // Note: ScoreValue is the sum of all note values of the song
- MaxLinePoints := MaxSongPoints / Lines[0].ScoreValue;
-
- // FIXME: is this correct? Why do we add the points for a whole line
- // if just one note is correct?
- case CurrentLineFragment.NoteType of
- ntNormal: CurrentPlayer.Score := CurrentPlayer.Score + MaxLinePoints;
- ntGolden: CurrentPlayer.ScoreGolden := CurrentPlayer.ScoreGolden + MaxLinePoints;
- end;
-
- CurrentPlayer.ScoreInt := Floor(CurrentPlayer.Score / 10) * 10;
- CurrentPlayer.ScoreGoldenInt := Floor(CurrentPlayer.ScoreGolden / 10) * 10;
-
- CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
- CurrentPlayer.ScoreGoldenInt +
- CurrentPlayer.ScoreLineInt;
- end;
-
- end; // operation
- end; // for
-
- // check if we have to add a new note or extend the note's length
- if (SentenceDetected = SentenceMax) then
- begin
- // we will add a new note
- NewNote := true;
- // if last has the same tone
- if ((CurrentPlayer.LengthNote > 0) and
- (LastPlayerNote.Tone = CurrentSound.Tone) and
- ((LastPlayerNote.Start + LastPlayerNote.Length) = LyricsState.CurrentBeatD)) then
- begin
- NewNote := false;
- end;
-
- // if is not as new note to control
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- if (Line.Note[LineFragmentIndex].Start = LyricsState.CurrentBeatD) then
- NewNote := true;
- end;
-
- // add new note
- if NewNote then
- begin
- // new note
- Inc(CurrentPlayer.LengthNote);
- Inc(CurrentPlayer.HighNote);
- SetLength(CurrentPlayer.Note, CurrentPlayer.LengthNote);
-
- // update player's last note
- LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
- with LastPlayerNote^ do
- begin
- Start := LyricsState.CurrentBeatD;
- Length := 1;
- Tone := CurrentSound.Tone; // Tone || ToneAbs
- Detect := LyricsState.MidBeat;
- Hit := NoteHit; // half note patch
- end;
- end
- else
- begin
- // extend note length
- Inc(LastPlayerNote.Length);
- end;
-
- // check for perfect note and then lit the star (on Draw)
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- if (CurrentLineFragment.Start = LastPlayerNote.Start) and
- (CurrentLineFragment.Length = LastPlayerNote.Length) and
- (CurrentLineFragment.Tone = LastPlayerNote.Tone) then
- begin
- LastPlayerNote.Perfect := true;
- end;
- end;
- end; // if SentenceDetected = SentenceMax
-
- end; // if Detected
- end; // for PlayerIndex
-
- //Log.LogStatus('EndBeat', 'NewBeat');
-
- // on sentence end -> for LineBonus and display of SingBar (rating pop-up)
- if (SentenceDetected >= Low(Lines[0].Line)) and
- (SentenceDetected <= High(Lines[0].Line)) then
- begin
- Line := @Lines[0].Line[SentenceDetected];
- CurrentLineFragment := @Line.Note[Line.HighNote];
- if ((CurrentLineFragment.Start + CurrentLineFragment.Length - 1) = LyricsState.CurrentBeatD) then
- begin
- if assigned(Screen) then
- Screen.OnSentenceEnd(SentenceDetected);
- end;
- end;
-
-end;
-
-procedure ClearScores(PlayerNum: integer);
-begin
- with Player[PlayerNum] do
- begin
- Score := 0;
- ScoreInt := 0;
- ScoreLine := 0;
- ScoreLineInt := 0;
- ScoreGolden := 0;
- ScoreGoldenInt := 0;
- ScoreTotalInt := 0;
- end;
-end;
-
-procedure AddSpecialPath(var PathList: TStringList; const Path: string);
-var
- I: integer;
- PathAbs, OldPathAbs: string;
-begin
- if (PathList = nil) then
- PathList := TStringList.Create;
-
- if (Path = '') or not DirectoryExists(Path) then
- Exit;
-
- PathAbs := IncludeTrailingPathDelimiter(ExpandFileName(Path));
-
- // check if path or a part of the path was already added
- for I := 0 to PathList.Count-1 do
- begin
- OldPathAbs := IncludeTrailingPathDelimiter(ExpandFileName(PathList[I]));
- // check if the new directory is a sub-directory of a previously added one.
- // This is also true, if both paths point to the same directories.
- if (AnsiStartsText(OldPathAbs, PathAbs)) then
- begin
- // ignore the new path
- Exit;
- end;
-
- // check if a previously added directory is a sub-directory of the new one.
- if (AnsiStartsText(PathAbs, OldPathAbs)) then
- begin
- // replace the old with the new one.
- PathList[I] := PathAbs;
- Exit;
- end;
- end;
-
- PathList.Add(PathAbs);
-end;
-
-procedure AddSongPath(const Path: string);
-begin
- AddSpecialPath(SongPaths, Path);
-end;
-
-procedure AddCoverPath(const Path: string);
-begin
- AddSpecialPath(CoverPaths, Path);
-end;
-
-(**
- * Initialize a path variable
- * After setting paths, make sure that paths exist
- *)
-function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
-begin
- Result := false;
-
- if (RequestedPath = '') then
- Exit;
-
- // Make sure the directory exists
- if (not ForceDirectories(RequestedPath)) then
- begin
- PathResult := '';
- Exit;
- end;
-
- PathResult := IncludeTrailingPathDelimiter(RequestedPath);
-
- if (NeedsWritePermission) and
- (FileIsReadOnly(RequestedPath)) then
- begin
- Exit;
- end;
-
- Result := true;
-end;
-
-(**
- * Function sets all absolute paths e.g. song path and makes sure the directorys exist
- *)
-procedure InitializePaths;
-begin
- // Log directory (must be writable)
- if (not FindPath(LogPath, Platform.GetLogPath, true)) then
- begin
- Log.FileOutputEnabled := false;
- Log.LogWarn('Log directory "'+ Platform.GetLogPath +'" not available', 'InitializePaths');
- end;
-
- FindPath(SoundPath, Platform.GetGameSharedPath + 'Sounds', false);
- FindPath(ThemePath, Platform.GetGameSharedPath + 'Themes', false);
- FindPath(SkinsPath, Platform.GetGameSharedPath + 'Themes', false);
- FindPath(LanguagesPath, Platform.GetGameSharedPath + 'Languages', false);
- FindPath(PluginPath, Platform.GetGameSharedPath + 'Plugins', false);
- FindPath(VisualsPath, Platform.GetGameSharedPath + 'Visuals', false);
- FindPath(ResourcesPath, Platform.GetGameSharedPath + 'Resources', false);
-
- // Playlists are not shared as we need one directory to write too
- FindPath(PlaylistPath, Platform.GetGameUserPath + 'Playlists', true);
-
- // Screenshot directory (must be writable)
- if (not FindPath(ScreenshotsPath, Platform.GetGameUserPath + 'Screenshots', true)) then
- begin
- Log.LogWarn('Screenshot directory "'+ Platform.GetGameUserPath +'" not available', 'InitializePaths');
- end;
-
- // Add song paths
- AddSongPath(Params.SongPath);
- AddSongPath(Platform.GetGameSharedPath + 'Songs');
- AddSongPath(Platform.GetGameUserPath + 'Songs');
-
- // Add category cover paths
- AddCoverPath(Platform.GetGameSharedPath + 'Covers');
- AddCoverPath(Platform.GetGameUserPath + 'Covers');
-end;
-
-end.
diff --git a/Game/Code/Classes/UMediaCore_FFmpeg.pas b/Game/Code/Classes/UMediaCore_FFmpeg.pas
deleted file mode 100644
index cdd320ac..00000000
--- a/Game/Code/Classes/UMediaCore_FFmpeg.pas
+++ /dev/null
@@ -1,405 +0,0 @@
-unit UMediaCore_FFmpeg;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMusic,
- avcodec,
- avformat,
- avutil,
- ULog,
- sdl;
-
-type
- PPacketQueue = ^TPacketQueue;
- TPacketQueue = class
- private
- FirstListEntry: PAVPacketList;
- LastListEntry: PAVPacketList;
- PacketCount: integer;
- Mutex: PSDL_Mutex;
- Condition: PSDL_Cond;
- Size: integer;
- AbortRequest: boolean;
- public
- constructor Create();
- destructor Destroy(); override;
-
- function Put(Packet : PAVPacket): integer;
- function PutStatus(StatusFlag: integer; StatusInfo: Pointer): integer;
- procedure FreeStatusInfo(var Packet: TAVPacket);
- function GetStatusInfo(var Packet: TAVPacket): Pointer;
- function Get(var Packet: TAVPacket; Blocking: boolean): integer;
- function GetSize(): integer;
- procedure Flush();
- procedure Abort();
- function IsAborted(): boolean;
- end;
-
-const
- STATUS_PACKET: PChar = 'STATUS_PACKET';
-const
- PKT_STATUS_FLAG_EOF = 1; // signal end-of-file
- PKT_STATUS_FLAG_FLUSH = 2; // request the decoder to flush its avcodec decode buffers
- PKT_STATUS_FLAG_ERROR = 3; // signal an error state
- PKT_STATUS_FLAG_EMPTY = 4; // request the decoder to output empty data (silence or black frames)
-
-type
- TMediaCore_FFmpeg = class
- private
- AVCodecLock: PSDL_Mutex;
- public
- constructor Create();
- destructor Destroy(); override;
- class function GetInstance(): TMediaCore_FFmpeg;
-
- function GetErrorString(ErrorNum: integer): string;
- function FindStreamIDs(FormatCtx: PAVFormatContext; out FirstVideoStream, FirstAudioStream: integer ): boolean;
- function FindAudioStreamIndex(FormatCtx: PAVFormatContext): integer;
- function ConvertFFmpegToAudioFormat(FFmpegFormat: TSampleFormat; out Format: TAudioSampleFormat): boolean;
- procedure LockAVCodec();
- procedure UnlockAVCodec();
- end;
-
-implementation
-
-uses
- SysUtils;
-
-var
- Instance: TMediaCore_FFmpeg;
-
-constructor TMediaCore_FFmpeg.Create();
-begin
- inherited;
- AVCodecLock := SDL_CreateMutex();
-end;
-
-destructor TMediaCore_FFmpeg.Destroy();
-begin
- SDL_DestroyMutex(AVCodecLock);
- inherited;
-end;
-
-class function TMediaCore_FFmpeg.GetInstance(): TMediaCore_FFmpeg;
-begin
- if (not Assigned(Instance)) then
- Instance := TMediaCore_FFmpeg.Create();
- Result := Instance;
-end;
-
-procedure TMediaCore_FFmpeg.LockAVCodec();
-begin
- SDL_mutexP(AVCodecLock);
-end;
-
-procedure TMediaCore_FFmpeg.UnlockAVCodec();
-begin
- SDL_mutexV(AVCodecLock);
-end;
-
-function TMediaCore_FFmpeg.GetErrorString(ErrorNum: integer): string;
-begin
- case ErrorNum of
- AVERROR_IO: Result := 'AVERROR_IO';
- AVERROR_NUMEXPECTED: Result := 'AVERROR_NUMEXPECTED';
- AVERROR_INVALIDDATA: Result := 'AVERROR_INVALIDDATA';
- AVERROR_NOMEM: Result := 'AVERROR_NOMEM';
- AVERROR_NOFMT: Result := 'AVERROR_NOFMT';
- AVERROR_NOTSUPP: Result := 'AVERROR_NOTSUPP';
- AVERROR_NOENT: Result := 'AVERROR_NOENT';
- AVERROR_PATCHWELCOME: Result := 'AVERROR_PATCHWELCOME';
- else Result := 'AVERROR_#'+inttostr(ErrorNum);
- end;
-end;
-
-{
- @param(FormatCtx is a PAVFormatContext returned from av_open_input_file )
- @param(FirstVideoStream is an OUT value of type integer, this is the index of the video stream)
- @param(FirstAudioStream is an OUT value of type integer, this is the index of the audio stream)
- @returns(@true on success, @false otherwise)
-}
-function TMediaCore_FFmpeg.FindStreamIDs(FormatCtx: PAVFormatContext; out FirstVideoStream, FirstAudioStream: integer): boolean;
-var
- i: integer;
- Stream: PAVStream;
-begin
- // find the first video stream
- FirstAudioStream := -1;
- FirstVideoStream := -1;
-
- for i := 0 to FormatCtx.nb_streams-1 do
- begin
- Stream := FormatCtx.streams[i];
-
- if (Stream.codec.codec_type = CODEC_TYPE_VIDEO) and
- (FirstVideoStream < 0) then
- begin
- FirstVideoStream := i;
- end;
-
- if (Stream.codec.codec_type = CODEC_TYPE_AUDIO) and
- (FirstAudioStream < 0) then
- begin
- FirstAudioStream := i;
- end;
- end;
-
- // return true if either an audio- or video-stream was found
- Result := (FirstAudioStream > -1) or
- (FirstVideoStream > -1) ;
-end;
-
-function TMediaCore_FFmpeg.FindAudioStreamIndex(FormatCtx: PAVFormatContext): integer;
-var
- i: integer;
- StreamIndex: integer;
- Stream: PAVStream;
-begin
- // find the first audio stream
- StreamIndex := -1;
-
- for i := 0 to FormatCtx^.nb_streams-1 do
- begin
- Stream := FormatCtx^.streams[i];
-
- if (Stream.codec^.codec_type = CODEC_TYPE_AUDIO) then
- begin
- StreamIndex := i;
- Break;
- end;
- end;
-
- Result := StreamIndex;
-end;
-
-function TMediaCore_FFmpeg.ConvertFFmpegToAudioFormat(FFmpegFormat: TSampleFormat; out Format: TAudioSampleFormat): boolean;
-begin
- case FFmpegFormat of
- SAMPLE_FMT_U8: Format := asfU8;
- SAMPLE_FMT_S16: Format := asfS16;
- SAMPLE_FMT_S24: Format := asfS24;
- SAMPLE_FMT_S32: Format := asfS32;
- SAMPLE_FMT_FLT: Format := asfFloat;
- else begin
- Result := false;
- Exit;
- end;
- end;
- Result := true;
-end;
-
-{ TPacketQueue }
-
-constructor TPacketQueue.Create();
-begin
- inherited;
-
- FirstListEntry := nil;
- LastListEntry := nil;
- PacketCount := 0;
- Size := 0;
-
- Mutex := SDL_CreateMutex();
- Condition := SDL_CreateCond();
-end;
-
-destructor TPacketQueue.Destroy();
-begin
- Flush();
- SDL_DestroyMutex(Mutex);
- SDL_DestroyCond(Condition);
- inherited;
-end;
-
-procedure TPacketQueue.Abort();
-begin
- SDL_LockMutex(Mutex);
-
- AbortRequest := true;
-
- SDL_CondBroadcast(Condition);
- SDL_UnlockMutex(Mutex);
-end;
-
-function TPacketQueue.IsAborted(): boolean;
-begin
- SDL_LockMutex(Mutex);
- Result := AbortRequest;
- SDL_UnlockMutex(Mutex);
-end;
-
-function TPacketQueue.Put(Packet : PAVPacket): integer;
-var
- CurrentListEntry : PAVPacketList;
-begin
- Result := -1;
-
- if (Packet = nil) then
- Exit;
-
- if (PChar(Packet^.data) <> STATUS_PACKET) then
- begin
- if (av_dup_packet(Packet) < 0) then
- Exit;
- end;
-
- CurrentListEntry := av_malloc(SizeOf(TAVPacketList));
- if (CurrentListEntry = nil) then
- Exit;
-
- CurrentListEntry^.pkt := Packet^;
- CurrentListEntry^.next := nil;
-
- SDL_LockMutex(Mutex);
- try
- if (LastListEntry = nil) then
- FirstListEntry := CurrentListEntry
- else
- LastListEntry^.next := CurrentListEntry;
-
- LastListEntry := CurrentListEntry;
- Inc(PacketCount);
-
- Size := Size + CurrentListEntry^.pkt.size;
- SDL_CondSignal(Condition);
- finally
- SDL_UnlockMutex(Mutex);
- end;
-
- Result := 0;
-end;
-
-(**
- * Adds a status packet (EOF, Flush, etc.) to the end of the queue.
- * StatusInfo can be used to pass additional information to the decoder.
- * Only assign nil or a valid pointer to data allocated with Getmem() to
- * StatusInfo because the pointer will be disposed with Freemem() on a call
- * to Flush(). If the packet is removed from the queue it is the decoder's
- * responsibility to free the StatusInfo data with FreeStatusInfo().
- *)
-function TPacketQueue.PutStatus(StatusFlag: integer; StatusInfo: Pointer): integer;
-var
- TempPacket: PAVPacket;
-begin
- // create temp. package
- TempPacket := av_malloc(SizeOf(TAVPacket));
- if (TempPacket = nil) then
- begin
- Result := -1;
- Exit;
- end;
- // init package
- av_init_packet(TempPacket^);
- TempPacket^.data := Pointer(STATUS_PACKET);
- TempPacket^.flags := StatusFlag;
- TempPacket^.priv := StatusInfo;
- // put a copy of the package into the queue
- Result := Put(TempPacket);
- // data has been copied -> delete temp. package
- av_free(TempPacket);
-end;
-
-procedure TPacketQueue.FreeStatusInfo(var Packet: TAVPacket);
-begin
- if (Packet.priv <> nil) then
- FreeMem(Packet.priv);
-end;
-
-function TPacketQueue.GetStatusInfo(var Packet: TAVPacket): Pointer;
-begin
- Result := Packet.priv;
-end;
-
-function TPacketQueue.Get(var Packet: TAVPacket; Blocking: boolean): integer;
-var
- CurrentListEntry: PAVPacketList;
-const
- WAIT_TIMEOUT = 10; // timeout in ms
-begin
- Result := -1;
-
- SDL_LockMutex(Mutex);
- try
- while (true) do
- begin
- if (AbortRequest) then
- Exit;
-
- CurrentListEntry := FirstListEntry;
- if (CurrentListEntry <> nil) then
- begin
- FirstListEntry := CurrentListEntry^.next;
- if (FirstListEntry = nil) then
- LastListEntry := nil;
- Dec(PacketCount);
-
- Size := Size - CurrentListEntry^.pkt.size;
- Packet := CurrentListEntry^.pkt;
- av_free(CurrentListEntry);
-
- Result := 1;
- Break;
- end
- else if (not Blocking) then
- begin
- Result := 0;
- Break;
- end
- else
- begin
- // block until a new package arrives,
- // but do not wait till infinity to avoid deadlocks
- if (SDL_CondWaitTimeout(Condition, Mutex, WAIT_TIMEOUT) = SDL_MUTEX_TIMEDOUT) then
- begin
- Result := 0;
- Break;
- end;
- end;
- end;
- finally
- SDL_UnlockMutex(Mutex);
- end;
-end;
-
-function TPacketQueue.GetSize(): integer;
-begin
- SDL_LockMutex(Mutex);
- Result := Size;
- SDL_UnlockMutex(Mutex);
-end;
-
-procedure TPacketQueue.Flush();
-var
- CurrentListEntry, TempListEntry: PAVPacketList;
-begin
- SDL_LockMutex(Mutex);
-
- CurrentListEntry := FirstListEntry;
- while(CurrentListEntry <> nil) do
- begin
- TempListEntry := CurrentListEntry^.next;
- // free status data
- if (PChar(CurrentListEntry^.pkt.data) = STATUS_PACKET) then
- FreeStatusInfo(CurrentListEntry^.pkt);
- // free packet data
- av_free_packet(@CurrentListEntry^.pkt);
- // Note: param must be a pointer to a pointer!
- av_freep(@CurrentListEntry);
- CurrentListEntry := TempListEntry;
- end;
- LastListEntry := nil;
- FirstListEntry := nil;
- PacketCount := 0;
- Size := 0;
-
- SDL_UnlockMutex(Mutex);
-end;
-
-end.
diff --git a/Game/Code/Classes/UMediaCore_SDL.pas b/Game/Code/Classes/UMediaCore_SDL.pas
deleted file mode 100644
index 252f72a0..00000000
--- a/Game/Code/Classes/UMediaCore_SDL.pas
+++ /dev/null
@@ -1,38 +0,0 @@
-unit UMediaCore_SDL;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMusic,
- sdl;
-
-function ConvertAudioFormatToSDL(Format: TAudioSampleFormat; out SDLFormat: UInt16): boolean;
-
-implementation
-
-function ConvertAudioFormatToSDL(Format: TAudioSampleFormat; out SDLFormat: UInt16): boolean;
-begin
- case Format of
- asfU8: SDLFormat := AUDIO_U8;
- asfS8: SDLFormat := AUDIO_S8;
- asfU16LSB: SDLFormat := AUDIO_U16LSB;
- asfS16LSB: SDLFormat := AUDIO_S16LSB;
- asfU16MSB: SDLFormat := AUDIO_U16MSB;
- asfS16MSB: SDLFormat := AUDIO_S16MSB;
- asfU16: SDLFormat := AUDIO_U16;
- asfS16: SDLFormat := AUDIO_S16;
- else begin
- Result := false;
- Exit;
- end;
- end;
- Result := true;
-end;
-
-end.
diff --git a/Game/Code/Classes/UMedia_dummy.pas b/Game/Code/Classes/UMedia_dummy.pas
deleted file mode 100644
index 438b89ab..00000000
--- a/Game/Code/Classes/UMedia_dummy.pas
+++ /dev/null
@@ -1,243 +0,0 @@
-unit UMedia_dummy;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-implementation
-
-uses
- SysUtils,
- math,
- UMusic;
-
-type
- TMedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput )
- private
- DummyOutputDeviceList: TAudioOutputDeviceList;
- public
- constructor Create();
- function GetName: string;
-
- function Init(): boolean;
- function Finalize(): boolean;
-
- function Open(const aFileName : string): boolean; // true if succeed
- procedure Close;
-
- procedure Play;
- procedure Pause;
- procedure Stop;
-
- procedure SetPosition(Time: real);
- function GetPosition: real;
-
- procedure SetSyncSource(SyncSource: TSyncSource);
-
- procedure GetFrame(Time: Extended);
- procedure DrawGL(Screen: integer);
-
- // IAudioInput
- function InitializeRecord: boolean;
- function FinalizeRecord: boolean;
- procedure CaptureStart;
- procedure CaptureStop;
- procedure GetFFTData(var data: TFFTData);
- function GetPCMData(var data: TPCMData): Cardinal;
-
- // IAudioPlayback
- function InitializePlayback: boolean;
- function FinalizePlayback: boolean;
-
- function GetOutputDeviceList(): TAudioOutputDeviceList;
- procedure FadeIn(Time: real; TargetVolume: single);
- procedure SetAppVolume(Volume: single);
- procedure SetVolume(Volume: single);
- procedure SetLoop(Enabled: boolean);
- procedure Rewind;
-
- function Finished: boolean;
- function Length: real;
-
- function OpenSound(const Filename: string): TAudioPlaybackStream;
- procedure CloseSound(var PlaybackStream: TAudioPlaybackStream);
- procedure PlaySound(stream: TAudioPlaybackStream);
- procedure StopSound(stream: TAudioPlaybackStream);
-
- function CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
- procedure CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
- end;
-
-function TMedia_dummy.GetName: string;
-begin
- Result := 'dummy';
-end;
-
-procedure TMedia_dummy.GetFrame(Time: Extended);
-begin
-end;
-
-procedure TMedia_dummy.DrawGL(Screen: integer);
-begin
-end;
-
-constructor TMedia_dummy.Create();
-begin
- inherited;
-end;
-
-function TMedia_dummy.Init(): boolean;
-begin
- Result := true;
-end;
-
-function TMedia_dummy.Finalize(): boolean;
-begin
- Result := true;
-end;
-
-function TMedia_dummy.Open(const aFileName : string): boolean; // true if succeed
-begin
- Result := false;
-end;
-
-procedure TMedia_dummy.Close;
-begin
-end;
-
-procedure TMedia_dummy.Play;
-begin
-end;
-
-procedure TMedia_dummy.Pause;
-begin
-end;
-
-procedure TMedia_dummy.Stop;
-begin
-end;
-
-procedure TMedia_dummy.SetPosition(Time: real);
-begin
-end;
-
-function TMedia_dummy.GetPosition: real;
-begin
- Result := 0;
-end;
-
-procedure TMedia_dummy.SetSyncSource(SyncSource: TSyncSource);
-begin
-end;
-
-// IAudioInput
-function TMedia_dummy.InitializeRecord: boolean;
-begin
- Result := true;
-end;
-
-function TMedia_dummy.FinalizeRecord: boolean;
-begin
- Result := true;
-end;
-
-procedure TMedia_dummy.CaptureStart;
-begin
-end;
-
-procedure TMedia_dummy.CaptureStop;
-begin
-end;
-
-procedure TMedia_dummy.GetFFTData(var data: TFFTData);
-begin
-end;
-
-function TMedia_dummy.GetPCMData(var data: TPCMData): Cardinal;
-begin
- Result := 0;
-end;
-
-// IAudioPlayback
-function TMedia_dummy.InitializePlayback: boolean;
-begin
- SetLength(DummyOutputDeviceList, 1);
- DummyOutputDeviceList[0] := TAudioOutputDevice.Create();
- DummyOutputDeviceList[0].Name := '[Dummy Device]';
- Result := true;
-end;
-
-function TMedia_dummy.FinalizePlayback: boolean;
-begin
- Result := true;
-end;
-
-function TMedia_dummy.GetOutputDeviceList(): TAudioOutputDeviceList;
-begin
- Result := DummyOutputDeviceList;
-end;
-
-procedure TMedia_dummy.SetAppVolume(Volume: single);
-begin
-end;
-
-procedure TMedia_dummy.SetVolume(Volume: single);
-begin
-end;
-
-procedure TMedia_dummy.SetLoop(Enabled: boolean);
-begin
-end;
-
-procedure TMedia_dummy.FadeIn(Time: real; TargetVolume: single);
-begin
-end;
-
-procedure TMedia_dummy.Rewind;
-begin
-end;
-
-function TMedia_dummy.Finished: boolean;
-begin
- Result := false;
-end;
-
-function TMedia_dummy.Length: real;
-begin
- Result := 60;
-end;
-
-function TMedia_dummy.OpenSound(const Filename: string): TAudioPlaybackStream;
-begin
- Result := nil;
-end;
-
-procedure TMedia_dummy.CloseSound(var PlaybackStream: TAudioPlaybackStream);
-begin
-end;
-
-procedure TMedia_dummy.PlaySound(stream: TAudioPlaybackStream);
-begin
-end;
-
-procedure TMedia_dummy.StopSound(stream: TAudioPlaybackStream);
-begin
-end;
-
-function TMedia_dummy.CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
-begin
- Result := nil;
-end;
-
-procedure TMedia_dummy.CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
-begin
-end;
-
-initialization
- MediaManager.Add(TMedia_dummy.Create);
-
-end.
diff --git a/Game/Code/Classes/UModules.pas b/Game/Code/Classes/UModules.pas
deleted file mode 100644
index 554a24c4..00000000
--- a/Game/Code/Classes/UModules.pas
+++ /dev/null
@@ -1,26 +0,0 @@
-unit UModules;
-
-interface
-
-{$I switches.inc}
-
-{*********************
- UModules
- Unit Contains all used Modules in its uses clausel
- and a const with an array of all Modules to load
-*********************}
-
-uses
- UCoreModule,
- UPluginLoader;
-
-const
- CORE_MODULES_TO_LOAD: Array[0..2] of cCoreModule = (
- TPluginLoader, //First because it has to look if there are Module replacements (Feature o/t Future)
- TCoreModule, //Remove this later, just a dummy
- TtehPlugins //Represents the Plugins. Last because they may use CoreModules Services etc.
- );
-
-implementation
-
-end.
\ No newline at end of file
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas
deleted file mode 100644
index 6476f629..00000000
--- a/Game/Code/Classes/UMusic.pas
+++ /dev/null
@@ -1,1233 +0,0 @@
-unit UMusic;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UTime,
- Classes;
-
-type
- TNoteType = (ntFreestyle, ntNormal, ntGolden);
-
- (**
- * TLineFragment represents a fragment of a lyrics line.
- * This is a text-fragment (e.g. a syllable) assigned to a note pitch,
- * represented by a bar in the sing-screen.
- *)
- PLineFragment = ^TLineFragment;
- TLineFragment = record
- Color: integer;
- Start: integer; // beat the fragment starts at
- Length: integer; // length in beats
- Tone: integer; // full range tone
- Text: string; // text assigned to this fragment (a syllable, word, etc.)
- NoteType: TNoteType; // note-type: golden-note/freestyle etc.
- end;
-
- (**
- * TLine represents one lyrics line and consists of multiple
- * notes.
- *)
- PLine = ^TLine;
- TLine = record
- Start: integer; // the start beat of this line (<> start beat of the first note of this line)
- Lyric: string;
- LyricWidth: real; // @deprecated: width of the line in pixels.
- // Do not use this as the width is not correct.
- // Use TLyricsEngine.GetUpperLine().Width instead.
- End_: integer;
- BaseNote: integer;
- HighNote: integer; // index of last note in line (= High(Note)?)
- TotalNotes: integer; // value of all notes in the line
- LastLine: boolean;
- Note: array of TLineFragment;
- end;
-
- (**
- * TLines stores sets of lyric lines and information on them.
- * Normally just one set is defined but in duet mode it might for example
- * contain two sets.
- *)
- TLines = record
- Current: integer; // for drawing of current line
- High: integer; // (= High(Line)?)
- Number: integer;
- Resolution: integer;
- NotesGAP: integer;
- ScoreValue: integer;
- Line: array of TLine;
- end;
-
- (**
- * TLyricsState contains all information concerning the
- * state of the lyrics, e.g. the current beat or duration of the lyrics.
- *)
- TLyricsState = class
- private
- Timer: TRelativeTimer; // keeps track of the current time
- public
- OldBeat: integer; // previous discovered beat
- CurrentBeat: integer; // current beat (rounded)
- MidBeat: real; // current beat (float)
-
- // now we use this for super synchronization!
- // only used when analyzing voice
- // TODO: change ...D to ...Detect(ed)
- OldBeatD: integer; // previous discovered beat
- CurrentBeatD: integer; // current discovered beat (rounded)
- MidBeatD: real; // current discovered beat (float)
-
- // we use this for audible clicks
- // TODO: Change ...C to ...Click
- OldBeatC: integer; // previous discovered beat
- CurrentBeatC: integer;
- MidBeatC: real; // like CurrentBeatC
-
- OldLine: integer; // previous displayed sentence
-
- StartTime: real; // time till start of lyrics (= Gap)
- TotalTime: real; // total song time
-
- constructor Create();
- procedure Pause();
- procedure Resume();
-
- procedure Reset();
- procedure UpdateBeats();
-
- (**
- * current song time (in seconds) used as base-timer for lyrics etc.
- *)
- function GetCurrentTime(): real;
- procedure SetCurrentTime(Time: real);
- end;
-
-
-const
- FFTSize = 512; // size of FFT data (output: FFTSize/2 values)
-type
- TFFTData = array[0..(FFTSize div 2)-1] of Single;
-
-type
- PPCMStereoSample = ^TPCMStereoSample;
- TPCMStereoSample = array[0..1] of SmallInt;
- TPCMData = array[0..511] of TPCMStereoSample;
-
-type
- TStreamStatus = (ssStopped, ssPlaying, ssPaused);
-const
- StreamStatusStr: array[TStreamStatus] of string =
- ('Stopped', 'Playing', 'Paused');
-
-type
- TAudioSampleFormat = (
- asfU8, asfS8, // unsigned/signed 8 bits
- asfU16LSB, asfS16LSB, // unsigned/signed 16 bits (endianness: LSB)
- asfU16MSB, asfS16MSB, // unsigned/signed 16 bits (endianness: MSB)
- asfU16, asfS16, // unsigned/signed 16 bits (endianness: System)
- asfS24, // signed 24 bits (endianness: System)
- asfS32, // signed 32 bits (endianness: System)
- asfFloat // float
- );
-
-const
- // Size of one sample (one channel only) in bytes
- AudioSampleSize: array[TAudioSampleFormat] of integer = (
- 1, 1, // asfU8, asfS8
- 2, 2, // asfU16LSB, asfS16LSB
- 2, 2, // asfU16MSB, asfS16MSB
- 2, 2, // asfU16, asfS16
- 3, // asfS24
- 4, // asfS32
- 4 // asfFloat
- );
-
-const
- CHANNELMAP_LEFT = 1;
- CHANNELMAP_RIGHT = 2;
- CHANNELMAP_FRONT = CHANNELMAP_LEFT or CHANNELMAP_RIGHT;
-
-type
- TAudioFormatInfo = class
- private
- fSampleRate : double;
- fChannels : byte;
- fFormat : TAudioSampleFormat;
- fFrameSize : integer;
-
- procedure SetChannels(Channels: byte);
- procedure SetFormat(Format: TAudioSampleFormat);
- procedure UpdateFrameSize();
- function GetBytesPerSec(): double;
- public
- constructor Create(Channels: byte; SampleRate: double; Format: TAudioSampleFormat);
- function Copy(): TAudioFormatInfo;
-
- (**
- * Returns the inverse ratio of the size of data in this format to its
- * size in a given target format.
- * Example: SrcSize*SrcInfo.GetRatio(TgtInfo) = TgtSize
- *)
- function GetRatio(TargetInfo: TAudioFormatInfo): double;
-
- property SampleRate: double read fSampleRate write fSampleRate;
- property Channels: byte read fChannels write SetChannels;
- property Format: TAudioSampleFormat read fFormat write SetFormat;
- property FrameSize: integer read fFrameSize;
- property BytesPerSec: double read GetBytesPerSec;
- end;
-
-type
- TSoundEffect = class
- public
- EngineData: Pointer; // can be used for engine-specific data
- procedure Callback(Buffer: PChar; BufSize: integer); virtual; abstract;
- end;
-
- TVoiceRemoval = class(TSoundEffect)
- public
- procedure Callback(Buffer: PChar; BufSize: integer); override;
- end;
-
-type
- TSyncSource = class
- function GetClock(): real; virtual; abstract;
- end;
-
- TAudioProcessingStream = class;
- TOnCloseHandler = procedure(Stream: TAudioProcessingStream);
-
- TAudioProcessingStream = class
- protected
- OnCloseHandlers: array of TOnCloseHandler;
-
- function GetLength(): real; virtual; abstract;
- function GetPosition(): real; virtual; abstract;
- procedure SetPosition(Time: real); virtual; abstract;
- function GetLoop(): boolean; virtual; abstract;
- procedure SetLoop(Enabled: boolean); virtual; abstract;
-
- procedure PerformOnClose();
- public
- function GetAudioFormatInfo(): TAudioFormatInfo; virtual; abstract;
- procedure Close(); virtual; abstract;
-
- (**
- * Adds a new OnClose action handler.
- * The handlers are performed in the order they were added.
- * If not stated explicitely, member-variables might have been invalidated
- * already. So do not use any member (variable/method/...) if you are not
- * sure it is valid.
- *)
- procedure AddOnCloseHandler(Handler: TOnCloseHandler);
-
- property Length: real read GetLength;
- property Position: real read GetPosition write SetPosition;
- property Loop: boolean read GetLoop write SetLoop;
- end;
-
- TAudioSourceStream = class(TAudioProcessingStream)
- protected
- function IsEOF(): boolean; virtual; abstract;
- function IsError(): boolean; virtual; abstract;
- public
- function ReadData(Buffer: PChar; BufferSize: integer): integer; virtual; abstract;
-
- property EOF: boolean read IsEOF;
- property Error: boolean read IsError;
- end;
-
- (*
- * State-Chart for playback-stream state transitions
- * []: Transition, (): State
- *
- * /---[Play/FadeIn]--->-\ /-------[Pause]----->-\
- * -[Create]->(Stop) (Play) (Pause)
- * \\-<-[Stop/EOF*/Error]-/ \-<---[Play/FadeIn]--//
- * \-<------------[Stop/EOF*/Error]--------------/
- *
- * *: if not looped, otherwise stream is repeated
- * Note: SetPosition() does not change the state.
- *)
-
- TAudioPlaybackStream = class(TAudioProcessingStream)
- protected
- SyncSource: TSyncSource;
- AvgSyncDiff: double;
- SourceStream: TAudioSourceStream;
-
- function GetLatency(): double; virtual; abstract;
- function GetStatus(): TStreamStatus; virtual; abstract;
- function GetVolume(): single; virtual; abstract;
- procedure SetVolume(Volume: single); virtual; abstract;
- function Synchronize(BufferSize: integer; FormatInfo: TAudioFormatInfo): integer;
- procedure FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
- public
- (**
- * Opens a SourceStream for playback.
- * Note that the caller (not the TAudioPlaybackStream) is responsible to
- * free the SourceStream after the Playback-Stream is closed.
- * You may use an OnClose-handler to achieve this. GetSourceStream()
- * guarantees to deliver this method's SourceStream parameter to
- * the OnClose-handler. Freeing SourceStream at OnClose is allowed.
- *)
- function Open(SourceStream: TAudioSourceStream): boolean; virtual; abstract;
-
- procedure Play(); virtual; abstract;
- procedure Pause(); virtual; abstract;
- procedure Stop(); virtual; abstract;
- procedure FadeIn(Time: real; TargetVolume: single); virtual; abstract;
-
- procedure GetFFTData(var data: TFFTData); virtual; abstract;
- function GetPCMData(var data: TPCMData): Cardinal; virtual; abstract;
-
- procedure AddSoundEffect(Effect: TSoundEffect); virtual; abstract;
- procedure RemoveSoundEffect(Effect: TSoundEffect); virtual; abstract;
-
- procedure SetSyncSource(SyncSource: TSyncSource);
- function GetSourceStream(): TAudioSourceStream;
-
- property Status: TStreamStatus read GetStatus;
- property Volume: single read GetVolume write SetVolume;
- end;
-
- TAudioDecodeStream = class(TAudioSourceStream)
- end;
-
- TAudioVoiceStream = class(TAudioSourceStream)
- protected
- FormatInfo: TAudioFormatInfo;
- ChannelMap: integer;
- public
- destructor Destroy; override;
-
- function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; virtual;
- procedure Close(); override;
-
- procedure WriteData(Buffer: PChar; BufferSize: integer); virtual; abstract;
- function GetAudioFormatInfo(): TAudioFormatInfo; override;
-
- function GetLength(): real; override;
- function GetPosition(): real; override;
- procedure SetPosition(Time: real); override;
- function GetLoop(): boolean; override;
- procedure SetLoop(Enabled: boolean); override;
- end;
-
-type
- // soundcard output-devices information
- TAudioOutputDevice = class
- public
- Name: string; // soundcard name
- end;
- TAudioOutputDeviceList = array of TAudioOutputDevice;
-
-type
- IGenericPlayback = Interface
- ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCE33DD}']
- function GetName: String;
-
- function Open(const Filename: string): boolean; // true if succeed
- procedure Close;
-
- procedure Play;
- procedure Pause;
- procedure Stop;
-
- procedure SetPosition(Time: real);
- function GetPosition: real;
-
- property Position: real read GetPosition write SetPosition;
- end;
-
- IVideoPlayback = Interface( IGenericPlayback )
- ['{3574C40C-28AE-4201-B3D1-3D1F0759B131}']
- function Init(): boolean;
- function Finalize: boolean;
-
- procedure GetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC
- procedure DrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC
-
- end;
-
- IVideoVisualization = Interface( IVideoPlayback )
- ['{5AC17D60-B34D-478D-B632-EB00D4078017}']
- end;
-
- IAudioPlayback = Interface( IGenericPlayback )
- ['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}']
- function InitializePlayback: boolean;
- function FinalizePlayback: boolean;
-
- function GetOutputDeviceList(): TAudioOutputDeviceList;
-
- procedure SetAppVolume(Volume: single);
- procedure SetVolume(Volume: single);
- procedure SetLoop(Enabled: boolean);
-
- procedure FadeIn(Time: real; TargetVolume: single);
- procedure SetSyncSource(SyncSource: TSyncSource);
-
- procedure Rewind;
- function Finished: boolean;
- function Length: real;
-
- // Sounds
- // TODO:
- // add a TMediaDummyPlaybackStream implementation that will
- // be used by the TSoundLib whenever OpenSound() fails, so checking for
- // nil-pointers is not neccessary anymore.
- // PlaySound/StopSound will be removed then, OpenSound will be renamed to
- // CreateSound.
- function OpenSound(const Filename: String): TAudioPlaybackStream;
- procedure PlaySound(Stream: TAudioPlaybackStream);
- procedure StopSound(Stream: TAudioPlaybackStream);
-
- // Equalizer
- procedure GetFFTData(var Data: TFFTData);
-
- // Interface for Visualizer
- function GetPCMData(var Data: TPCMData): Cardinal;
-
- function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
- end;
-
- IGenericDecoder = Interface
- ['{557B0E9A-604D-47E4-B826-13769F3E10B7}']
- function GetName(): String;
- function InitializeDecoder(): boolean;
- function FinalizeDecoder(): boolean;
- //function IsSupported(const Filename: string): boolean;
- end;
-
- (*
- IVideoDecoder = Interface( IGenericDecoder )
- ['{2F184B2B-FE69-44D5-9031-0A2462391DCA}']
- function Open(const Filename: string): TVideoDecodeStream;
- end;
- *)
-
- IAudioDecoder = Interface( IGenericDecoder )
- ['{AB47B1B6-2AA9-4410-BF8C-EC79561B5478}']
- function Open(const Filename: string): TAudioDecodeStream;
- end;
-
- IAudioInput = Interface
- ['{A5C8DA92-2A0C-4AB2-849B-2F7448C6003A}']
- function GetName: String;
- function InitializeRecord: boolean;
- function FinalizeRecord(): boolean;
-
- procedure CaptureStart;
- procedure CaptureStop;
- end;
-
-type
- TAudioConverter = class
- protected
- fSrcFormatInfo: TAudioFormatInfo;
- fDstFormatInfo: TAudioFormatInfo;
- public
- function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; virtual;
- destructor Destroy(); override;
-
- (**
- * Converts the InputBuffer and stores the result in OutputBuffer.
- * If the result is not -1, InputSize will be set to the actual number of
- * input-buffer bytes used.
- * Returns the number of bytes written to the output-buffer or -1 if an error occured.
- *)
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; virtual; abstract;
-
- (**
- * Destination/Source size ratio
- *)
- function GetRatio(): double; virtual; abstract;
-
- function GetOutputBufferSize(InputSize: integer): integer; virtual; abstract;
- property SrcFormatInfo: TAudioFormatInfo read fSrcFormatInfo;
- property DstFormatInfo: TAudioFormatInfo read fDstFormatInfo;
- end;
-
-(* TODO
-const
- SOUNDID_START = 0;
- SOUNDID_BACK = 1;
- SOUNDID_SWOOSH = 2;
- SOUNDID_CHANGE = 3;
- SOUNDID_OPTION = 4;
- SOUNDID_CLICK = 5;
- LAST_SOUNDID = SOUNDID_CLICK;
-
- BaseSoundFilenames: array[0..LAST_SOUNDID] of string = (
- '%SOUNDPATH%/Common start.mp3', // Start
- '%SOUNDPATH%/Common back.mp3', // Back
- '%SOUNDPATH%/menu swoosh.mp3', // Swoosh
- '%SOUNDPATH%/select music change music 50.mp3', // Change
- '%SOUNDPATH%/option change col.mp3', // Option
- '%SOUNDPATH%/rimshot022b.mp3' // Click
- {
- '%SOUNDPATH%/bassdrumhard076b.mp3', // Drum (unused)
- '%SOUNDPATH%/hihatclosed068b.mp3', // Hihat (unused)
- '%SOUNDPATH%/claps050b.mp3', // Clap (unused)
- '%SOUNDPATH%/Shuffle.mp3' // Shuffle (unused)
- }
- );
-*)
-
-type
- TSoundLibrary = class
- private
- // TODO
- //Sounds: array of TAudioPlaybackStream;
- public
- // TODO: move sounds to the private section
- // and provide IDs instead.
- Start: TAudioPlaybackStream;
- Back: TAudioPlaybackStream;
- Swoosh: TAudioPlaybackStream;
- Change: TAudioPlaybackStream;
- Option: TAudioPlaybackStream;
- Click: TAudioPlaybackStream;
- BGMusic: TAudioPlaybackStream;
-
- constructor Create();
- destructor Destroy(); override;
-
- procedure LoadSounds();
- procedure UnloadSounds();
-
- procedure StartBgMusic();
- procedure PauseBgMusic();
- // TODO
- //function AddSound(Filename: string): integer;
- //procedure RemoveSound(ID: integer);
- //function GetSound(ID: integer): TAudioPlaybackStream;
- //property Sound[ID: integer]: TAudioPlaybackStream read GetSound; default;
- end;
-
-var
- // TODO: JB --- THESE SHOULD NOT BE GLOBAL
- Lines: array of TLines;
- LyricsState: TLyricsState;
- SoundLib: TSoundLibrary;
-
-
-procedure InitializeSound;
-procedure InitializeVideo;
-procedure FinalizeMedia;
-
-function Visualization(): IVideoPlayback;
-function VideoPlayback(): IVideoPlayback;
-function AudioPlayback(): IAudioPlayback;
-function AudioInput(): IAudioInput;
-function AudioDecoders(): TInterfaceList;
-
-function MediaManager: TInterfaceList;
-
-procedure DumpMediaInterfaces();
-
-implementation
-
-uses
- sysutils,
- math,
- UIni,
- UMain,
- UCommandLine,
- URecord,
- ULog;
-
-var
- DefaultVideoPlayback : IVideoPlayback;
- DefaultVisualization : IVideoPlayback;
- DefaultAudioPlayback : IAudioPlayback;
- DefaultAudioInput : IAudioInput;
- AudioDecoderList : TInterfaceList;
- MediaInterfaceList : TInterfaceList;
-
-
-constructor TAudioFormatInfo.Create(Channels: byte; SampleRate: double; Format: TAudioSampleFormat);
-begin
- inherited Create();
- fChannels := Channels;
- fSampleRate := SampleRate;
- fFormat := Format;
- UpdateFrameSize();
-end;
-
-procedure TAudioFormatInfo.SetChannels(Channels: byte);
-begin
- fChannels := Channels;
- UpdateFrameSize();
-end;
-
-procedure TAudioFormatInfo.SetFormat(Format: TAudioSampleFormat);
-begin
- fFormat := Format;
- UpdateFrameSize();
-end;
-
-function TAudioFormatInfo.GetBytesPerSec(): double;
-begin
- Result := FrameSize * SampleRate;
-end;
-
-procedure TAudioFormatInfo.UpdateFrameSize();
-begin
- fFrameSize := AudioSampleSize[fFormat] * fChannels;
-end;
-
-function TAudioFormatInfo.Copy(): TAudioFormatInfo;
-begin
- Result := TAudioFormatInfo.Create(Self.Channels, Self.SampleRate, Self.Format);
-end;
-
-function TAudioFormatInfo.GetRatio(TargetInfo: TAudioFormatInfo): double;
-begin
- Result := (TargetInfo.FrameSize / Self.FrameSize) *
- (TargetInfo.SampleRate / Self.SampleRate)
-end;
-
-
-function MediaManager: TInterfaceList;
-begin
- if (not assigned(MediaInterfaceList)) then
- MediaInterfaceList := TInterfaceList.Create();
- Result := MediaInterfaceList;
-end;
-
-function VideoPlayback(): IVideoPlayback;
-begin
- Result := DefaultVideoPlayback;
-end;
-
-function Visualization(): IVideoPlayback;
-begin
- Result := DefaultVisualization;
-end;
-
-function AudioPlayback(): IAudioPlayback;
-begin
- Result := DefaultAudioPlayback;
-end;
-
-function AudioInput(): IAudioInput;
-begin
- Result := DefaultAudioInput;
-end;
-
-function AudioDecoders(): TInterfaceList;
-begin
- Result := AudioDecoderList;
-end;
-
-procedure FilterInterfaceList(const IID: TGUID; InList, OutList: TInterfaceList);
-var
- i: integer;
- obj: IInterface;
-begin
- if (not assigned(OutList)) then
- Exit;
-
- OutList.Clear;
- for i := 0 to InList.Count-1 do
- begin
- if assigned(InList[i]) then
- begin
- // add object to list if it implements the interface searched for
- if (InList[i].QueryInterface(IID, obj) = 0) then
- OutList.Add(obj);
- end;
- end;
-end;
-
-procedure InitializeSound;
-var
- i: integer;
- InterfaceList: TInterfaceList;
- CurrentAudioDecoder: IAudioDecoder;
- CurrentAudioPlayback: IAudioPlayback;
- CurrentAudioInput: IAudioInput;
-begin
- // create a temporary list for interface enumeration
- InterfaceList := TInterfaceList.Create();
-
- // initialize all audio-decoders first
- FilterInterfaceList(IAudioDecoder, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- begin
- CurrentAudioDecoder := IAudioDecoder(InterfaceList[i]);
- if (not CurrentAudioDecoder.InitializeDecoder()) then
- begin
- Log.LogError('Initialize failed, Removing - '+ CurrentAudioDecoder.GetName);
- MediaManager.Remove(CurrentAudioDecoder);
- end;
- end;
-
- // create and setup decoder-list (see AudioDecoders())
- AudioDecoderList := TInterfaceList.Create;
- FilterInterfaceList(IAudioDecoder, MediaManager, AudioDecoders);
-
- // find and initialize playback interface
- DefaultAudioPlayback := nil;
- FilterInterfaceList(IAudioPlayback, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- begin
- CurrentAudioPlayback := IAudioPlayback(InterfaceList[i]);
- if (CurrentAudioPlayback.InitializePlayback()) then
- begin
- DefaultAudioPlayback := CurrentAudioPlayback;
- break;
- end;
- Log.LogError('Initialize failed, Removing - '+ CurrentAudioPlayback.GetName);
- MediaManager.Remove(CurrentAudioPlayback);
- end;
-
- // find and initialize input interface
- DefaultAudioInput := nil;
- FilterInterfaceList(IAudioInput, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- begin
- CurrentAudioInput := IAudioInput(InterfaceList[i]);
- if (CurrentAudioInput.InitializeRecord()) then
- begin
- DefaultAudioInput := CurrentAudioInput;
- break;
- end;
- Log.LogError('Initialize failed, Removing - '+ CurrentAudioInput.GetName);
- MediaManager.Remove(CurrentAudioInput);
- end;
-
- InterfaceList.Free;
-
- // Update input-device list with registered devices
- AudioInputProcessor.UpdateInputDeviceConfig();
-
- // Load in-game sounds
- SoundLib := TSoundLibrary.Create;
-end;
-
-procedure InitializeVideo();
-var
- i: integer;
- InterfaceList: TInterfaceList;
- VideoInterface: IVideoPlayback;
- VisualInterface: IVideoVisualization;
-begin
- InterfaceList := TInterfaceList.Create;
-
- // initialize and set video-playback singleton
- DefaultVideoPlayback := nil;
- FilterInterfaceList(IVideoPlayback, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- begin
- VideoInterface := IVideoPlayback(InterfaceList[i]);
- if (VideoInterface.Init()) then
- begin
- DefaultVideoPlayback := VideoInterface;
- break;
- end;
- Log.LogError('Initialize failed, Removing - '+ VideoInterface.GetName);
- MediaManager.Remove(VideoInterface);
- end;
-
- // initialize and set visualization singleton
- DefaultVisualization := nil;
- FilterInterfaceList(IVideoVisualization, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- begin
- VisualInterface := IVideoVisualization(InterfaceList[i]);
- if (VisualInterface.Init()) then
- begin
- DefaultVisualization := VisualInterface;
- break;
- end;
- Log.LogError('Initialize failed, Removing - '+ VisualInterface.GetName);
- MediaManager.Remove(VisualInterface);
- end;
-
- InterfaceList.Free;
-
- // now that we have all interfaces, we can dump them
- // TODO: move this to another place
- if FindCmdLineSwitch( cMediaInterfaces ) then
- begin
- DumpMediaInterfaces();
- halt;
- end;
-end;
-
-procedure UnloadMediaModules;
-var
- i: integer;
- InterfaceList: TInterfaceList;
-begin
- FreeAndNil(AudioDecoderList);
- DefaultAudioPlayback := nil;
- DefaultAudioInput := nil;
- DefaultVideoPlayback := nil;
- DefaultVisualization := nil;
-
- // create temporary interface list
- InterfaceList := TInterfaceList.Create();
-
- // finalize audio playback interfaces (should be done before the decoders)
- FilterInterfaceList(IAudioPlayback, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- IAudioPlayback(InterfaceList[i]).FinalizePlayback();
-
- // finalize audio input interfaces
- FilterInterfaceList(IAudioInput, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- IAudioInput(InterfaceList[i]).FinalizeRecord();
-
- // finalize audio decoder interfaces
- FilterInterfaceList(IAudioDecoder, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- IAudioDecoder(InterfaceList[i]).FinalizeDecoder();
-
- // finalize video interfaces
- FilterInterfaceList(IVideoPlayback, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- IVideoPlayback(InterfaceList[i]).Finalize();
-
- // finalize audio decoder interfaces
- FilterInterfaceList(IVideoVisualization, MediaManager, InterfaceList);
- for i := 0 to InterfaceList.Count-1 do
- IVideoVisualization(InterfaceList[i]).Finalize();
-
- InterfaceList.Free;
-
- // finally free interfaces (by removing all references to them)
- FreeAndNil(MediaInterfaceList);
-end;
-
-procedure FinalizeMedia;
-begin
- // stop, close and free sounds
- SoundLib.Free;
-
- // stop and close music stream
- if (AudioPlayback <> nil) then
- AudioPlayback.Close;
-
- // stop any active captures
- if (AudioInput <> nil) then
- AudioInput.CaptureStop;
-
- if (VideoPlayback <> nil) then
- VideoPlayback.Close;
-
- if (Visualization <> nil) then
- Visualization.Close;
-
- UnloadMediaModules();
-end;
-
-procedure DumpMediaInterfaces();
-begin
- writeln( '' );
- writeln( '--------------------------------------------------------------' );
- writeln( ' In-use Media Interfaces ' );
- writeln( '--------------------------------------------------------------' );
- writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName );
- writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName );
- writeln( 'Registered Video Playback Interface : ' + VideoPlayback.GetName );
- writeln( 'Registered Visualization Interface : ' + Visualization.GetName );
- writeln( '--------------------------------------------------------------' );
- writeln( '' );
-end;
-
-
-{ TSoundLibrary }
-
-constructor TSoundLibrary.Create();
-begin
- inherited;
- LoadSounds();
-end;
-
-destructor TSoundLibrary.Destroy();
-begin
- UnloadSounds();
- inherited;
-end;
-
-procedure TSoundLibrary.LoadSounds();
-begin
- UnloadSounds();
-
- Start := AudioPlayback.OpenSound(SoundPath + 'Common start.mp3');
- Back := AudioPlayback.OpenSound(SoundPath + 'Common back.mp3');
- Swoosh := AudioPlayback.OpenSound(SoundPath + 'menu swoosh.mp3');
- Change := AudioPlayback.OpenSound(SoundPath + 'select music change music 50.mp3');
- Option := AudioPlayback.OpenSound(SoundPath + 'option change col.mp3');
- Click := AudioPlayback.OpenSound(SoundPath + 'rimshot022b.mp3');
-
- BGMusic := AudioPlayback.OpenSound(SoundPath + 'Bebeto_-_Loop010.mp3');
-
- if (BGMusic <> nil) then
- BGMusic.Loop := True;
-end;
-
-procedure TSoundLibrary.UnloadSounds();
-begin
- FreeAndNil(Start);
- FreeAndNil(Back);
- FreeAndNil(Swoosh);
- FreeAndNil(Change);
- FreeAndNil(Option);
- FreeAndNil(Click);
- FreeAndNil(BGMusic);
-end;
-
-(* TODO
-function TSoundLibrary.GetSound(ID: integer): TAudioPlaybackStream;
-begin
- if ((ID >= 0) and (ID < Length(Sounds))) then
- Result := Sounds[ID]
- else
- Result := nil;
-end;
-*)
-
-procedure TSoundLibrary.StartBgMusic();
-begin
- if (TBackgroundMusicOption(Ini.BackgroundMusicOption) = bmoOn) and
- (Soundlib.BGMusic <> nil) and not (Soundlib.BGMusic.Status = ssPlaying) then
- begin
- AudioPlayback.PlaySound(Soundlib.BGMusic);
- end;
-end;
-
-procedure TSoundLibrary.PauseBgMusic();
-begin
- If (Soundlib.BGMusic <> nil) then
- begin
- Soundlib.BGMusic.Pause;
- end;
-end;
-
-{ TVoiceRemoval }
-
-procedure TVoiceRemoval.Callback(Buffer: PChar; BufSize: integer);
-var
- FrameIndex, FrameSize: integer;
- Value: integer;
- Sample: PPCMStereoSample;
-begin
- FrameSize := 2 * SizeOf(SmallInt);
- for FrameIndex := 0 to (BufSize div FrameSize)-1 do
- begin
- Sample := PPCMStereoSample(Buffer);
- // channel difference
- Value := Sample[0] - Sample[1];
- // clip
- if (Value > High(SmallInt)) then
- Value := High(SmallInt)
- else if (Value < Low(SmallInt)) then
- Value := Low(SmallInt);
- // assign result
- Sample[0] := Value;
- Sample[1] := Value;
- // increase to next frame
- Inc(Buffer, FrameSize);
- end;
-end;
-
-
-{ TVoiceRemoval }
-
-constructor TLyricsState.Create();
-begin
- // create a triggered timer, so we can Pause() it, set the time
- // and Resume() it afterwards for better synching.
- Timer := TRelativeTimer.Create(true);
-
- // reset state
- Reset();
-end;
-
-procedure TLyricsState.Pause();
-begin
- Timer.Pause();
-end;
-
-procedure TLyricsState.Resume();
-begin
- Timer.Resume();
-end;
-
-procedure TLyricsState.SetCurrentTime(Time: real);
-begin
- // do not start the timer (if not started already),
- // after setting the current time
- Timer.SetTime(Time, false);
-end;
-
-function TLyricsState.GetCurrentTime(): real;
-begin
- Result := Timer.GetTime();
-end;
-
-(**
- * Resets the timer and state of the lyrics.
- * The timer will be stopped afterwards so you have to call Resume()
- * to start the lyrics timer.
- *)
-procedure TLyricsState.Reset();
-begin
- Pause();
- SetCurrentTime(0);
-
- StartTime := 0;
- TotalTime := 0;
-
- OldBeat := -1;
- MidBeat := -1;
- CurrentBeat := -1;
-
- OldBeatC := -1;
- MidBeatC := -1;
- CurrentBeatC := -1;
-
- OldBeatD := -1;
- MidBeatD := -1;
- CurrentBeatD := -1;
-end;
-
-(**
- * Updates the beat information (CurrentBeat/MidBeat/...) according to the
- * current lyric time.
- *)
-procedure TLyricsState.UpdateBeats();
-var
- CurLyricsTime: real;
-begin
- CurLyricsTime := GetCurrentTime();
-
- OldBeat := CurrentBeat;
- MidBeat := GetMidBeat(CurLyricsTime - StartTime / 1000);
- CurrentBeat := Floor(MidBeat);
-
- OldBeatC := CurrentBeatC;
- MidBeatC := GetMidBeat(CurLyricsTime - StartTime / 1000);
- CurrentBeatC := Floor(MidBeatC);
-
- OldBeatD := CurrentBeatD;
- // MidBeatD = MidBeat with additional GAP
- MidBeatD := -0.5 + GetMidBeat(CurLyricsTime - (StartTime + 120 + 20) / 1000);
- CurrentBeatD := Floor(MidBeatD);
-end;
-
-
-{ TAudioConverter }
-
-function TAudioConverter.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
-begin
- fSrcFormatInfo := SrcFormatInfo.Copy();
- fDstFormatInfo := DstFormatInfo.Copy();
- Result := true;
-end;
-
-destructor TAudioConverter.Destroy();
-begin
- FreeAndNil(fSrcFormatInfo);
- FreeAndNil(fDstFormatInfo);
-end;
-
-
-{ TAudioProcessingStream }
-
-procedure TAudioProcessingStream.AddOnCloseHandler(Handler: TOnCloseHandler);
-begin
- if (@Handler <> nil) then
- begin
- SetLength(OnCloseHandlers, System.Length(OnCloseHandlers)+1);
- OnCloseHandlers[High(OnCloseHandlers)] := @Handler;
- end;
-end;
-
-procedure TAudioProcessingStream.PerformOnClose();
-var i: integer;
-begin
- for i := 0 to High(OnCloseHandlers) do
- begin
- OnCloseHandlers[i](Self);
- end;
-end;
-
-
-{ TAudioPlaybackStream }
-
-function TAudioPlaybackStream.GetSourceStream(): TAudioSourceStream;
-begin
- Result := SourceStream;
-end;
-
-procedure TAudioPlaybackStream.SetSyncSource(SyncSource: TSyncSource);
-begin
- Self.SyncSource := SyncSource;
- AvgSyncDiff := -1;
-end;
-
-(*
- * Results an adjusted size of the input buffer size to keep the stream in sync
- * with the SyncSource. If no SyncSource was assigned to this stream, the
- * input buffer size will be returned, so this method will have no effect.
- *
- * These are the possible cases:
- * - Result > BufferSize: stream is behind the sync-source (stream is too slow),
- * (Result-BufferSize) bytes of the buffer must be skipped.
- * - Result = BufferSize: stream is in sync,
- * there is nothing to do.
- * - Result < BufferSize: stream is ahead of the sync-source (stream is too fast),
- * (BufferSize-Result) bytes of the buffer must be padded.
- *)
-function TAudioPlaybackStream.Synchronize(BufferSize: integer; FormatInfo: TAudioFormatInfo): integer;
-var
- TimeDiff: double;
- TimeCorrectionFactor: double;
-const
- AVG_HISTORY_FACTOR = 0.9;
- SYNC_THRESHOLD = 0.045;
- MAX_SYNC_DIFF_TIME = 0.002;
-begin
- Result := BufferSize;
-
- if (not assigned(SyncSource)) then
- Exit;
-
- if (BufferSize <= 0) then
- Exit;
-
- // difference between sync-source and stream position
- // (negative if the music-stream's position is ahead of the master clock)
- TimeDiff := SyncSource.GetClock() - (Position - GetLatency());
-
- // calculate average time difference (some sort of weighted mean).
- // The bigger AVG_HISTORY_FACTOR is, the smoother is the average diff.
- // This means that older diffs are weighted more with a higher history factor
- // than with a lower. Do not use a too low history factor. FFmpeg produces
- // very instable timestamps (pts) for ogg due to some bugs. They may differ
- // +-50ms from the real stream position. Without filtering those glitches we
- // would synch without any need, resulting in ugly plopping sounds.
- if (AvgSyncDiff = -1) then
- AvgSyncDiff := TimeDiff
- else
- AvgSyncDiff := TimeDiff * (1-AVG_HISTORY_FACTOR) +
- AvgSyncDiff * AVG_HISTORY_FACTOR;
-
- // check if sync needed
- if (Abs(AvgSyncDiff) >= SYNC_THRESHOLD) then
- begin
- // TODO: use SetPosition if diff is too large (>5s)
- if (TimeDiff < 1) then
- TimeCorrectionFactor := Sign(TimeDiff)*TimeDiff*TimeDiff
- else
- TimeCorrectionFactor := TimeDiff;
-
- // calculate adapted buffer size
- // reduce size of data to fetch if music is ahead, increase otherwise
- Result := BufferSize + Round(TimeCorrectionFactor * FormatInfo.SampleRate) * FormatInfo.FrameSize;
- if (Result < 0) then
- Result := 0;
-
- // reset average
- AvgSyncDiff := -1;
- end;
-
- (*
- DebugWriteln('Diff: ' + floattostrf(TimeDiff, ffFixed, 15, 3) +
- '| SyS: ' + floattostrf(SyncSource.GetClock(), ffFixed, 15, 3) +
- '| Pos: ' + floattostrf(Position, ffFixed, 15, 3) +
- '| Avg: ' + floattostrf(AvgSyncDiff, ffFixed, 15, 3));
- *)
-end;
-
-(*
- * Fills a buffer with copies of the given frame or with 0 if frame.
- *)
-procedure TAudioPlaybackStream.FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
-var
- i: integer;
- FrameCopyCount: integer;
-begin
- // the buffer must at least contain place for one copy of the frame.
- if ((Buffer = nil) or (BufferSize <= 0) or (BufferSize < FrameSize)) then
- Exit;
-
- // no valid frame -> fill with 0
- if ((Frame = nil) or (FrameSize <= 0)) then
- begin
- FillChar(Buffer[0], BufferSize, 0);
- Exit;
- end;
-
- // number of frames to copy
- FrameCopyCount := BufferSize div FrameSize;
- // insert as many copies of frame into the buffer as possible
- for i := 0 to FrameCopyCount-1 do
- Move(Frame[0], Buffer[i*FrameSize], FrameSize);
-end;
-
-{ TAudioVoiceStream }
-
-function TAudioVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
-begin
- Self.ChannelMap := ChannelMap;
- Self.FormatInfo := FormatInfo.Copy();
- // a voice stream is always mono, reassure the the format is correct
- Self.FormatInfo.Channels := 1;
- Result := true;
-end;
-
-destructor TAudioVoiceStream.Destroy;
-begin
- Close();
- inherited;
-end;
-
-procedure TAudioVoiceStream.Close();
-begin
- PerformOnClose();
- FreeAndNil(FormatInfo);
-end;
-
-function TAudioVoiceStream.GetAudioFormatInfo(): TAudioFormatInfo;
-begin
- Result := FormatInfo;
-end;
-
-function TAudioVoiceStream.GetLength(): real;
-begin
- Result := -1;
-end;
-
-function TAudioVoiceStream.GetPosition(): real;
-begin
- Result := -1;
-end;
-
-procedure TAudioVoiceStream.SetPosition(Time: real);
-begin
-end;
-
-function TAudioVoiceStream.GetLoop(): boolean;
-begin
- Result := false;
-end;
-
-procedure TAudioVoiceStream.SetLoop(Enabled: boolean);
-begin
-end;
-
-
-end.
diff --git a/Game/Code/Classes/UParty.pas b/Game/Code/Classes/UParty.pas
deleted file mode 100644
index 01a182b1..00000000
--- a/Game/Code/Classes/UParty.pas
+++ /dev/null
@@ -1,630 +0,0 @@
-unit UParty;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses UPartyDefs, UCoreModule, UPluginDefs;
-
-type
- ARounds = Array [0..252] of Integer; //0..252 needed for
- PARounds = ^ARounds;
-
- TRoundInfo = record
- Modi: Cardinal;
- Winner: Byte;
- end;
-
- TeamOrderEntry = record
- Teamnum: Byte;
- Score: Byte;
- end;
-
- TeamOrderArray = Array[0..5] of Byte;
-
- TUS_ModiInfoEx = record
- Info: TUS_ModiInfo;
- Owner: Integer;
- TimesPlayed: Byte; //Helper for setting Round Plugins
- end;
-
- TPartySession = class (TCoreModule)
- private
- bPartyMode: Boolean; //Is this Party or Singleplayer
- CurRound: Byte;
-
- Modis: Array of TUS_ModiInfoEx;
- Teams: TTeamInfo;
-
- function IsWinner(Player, Winner: Byte): boolean;
- procedure GenScores;
- function GetRandomPlugin(TeamMode: Boolean): Cardinal;
- function GetRandomPlayer(Team: Byte): Byte;
- public
- //Teams: TTeamInfo;
- Rounds: array of TRoundInfo;
-
- //TCoreModule methods to inherit
- Constructor Create; override;
- Procedure Info(const pInfo: PModuleInfo); override;
- Function Load: Boolean; override;
- Function Init: Boolean; override;
- Procedure DeInit; override;
- Destructor Destroy; override;
-
- //Register Modi Service
- Function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new Modi. wParam: Pointer to TUS_ModiInfo
-
- //Start new Party
- Function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new Party Mode. Returns Non Zero on Success
- Function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns Pointer to Cur. Modis TUS_ModiInfo (to Use with Singscreen)
- Function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops Party Mode. Returns 1 If Partymode was enabled before.
- Function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
-
- Function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
- Function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and does the RoundEnding
-
- Function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
- Function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
-
- Function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
- Function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
- end;
-
-const
- StandardModi = 0; //Modi ID that will be played in non party Mode
-
-implementation
-
-uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils;
-
-{*********************
- TPluginLoader
- Implentation
-*********************}
-
-//-------------
-// Function that gives some Infos about the Module to the Core
-//-------------
-Procedure TPartySession.Info(const pInfo: PModuleInfo);
-begin
- pInfo^.Name := 'TPartySession';
- pInfo^.Version := MakeVersion(1,0,0,chr(0));
- pInfo^.Description := 'Manages Party Modi and Party Game';
-end;
-
-//-------------
-// Just the Constructor
-//-------------
-Constructor TPartySession.Create;
-begin
- inherited;
- //UnSet PartyMode
- bPartyMode := False;
-end;
-
-//-------------
-//Is Called on Loading.
-//In this Method only Events and Services should be created
-//to offer them to other Modules or Plugins during the Init process
-//If False is Returned this will cause a Forced Exit
-//-------------
-Function TPartySession.Load: Boolean;
-begin
- //Add Register Party Modi Service
- Result := True;
- Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi);
- Core.Services.AddService('Party/StartParty', nil, Self.StartParty);
- Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi);
-end;
-
-//-------------
-//Is Called on Init Process
-//In this Method you can Hook some Events and Create + Init
-//your Classes, Variables etc.
-//If False is Returned this will cause a Forced Exit
-//-------------
-Function TPartySession.Init: Boolean;
-begin
- //Just set Prvate Var to true.
- Result := true;
-end;
-
-//-------------
-//Is Called if this Module has been Inited and there is a Exit.
-//Deinit is in backwards Initing Order
-//-------------
-Procedure TPartySession.DeInit;
-begin
- //Force DeInit
-
-end;
-
-//-------------
-//Is Called if this Module will be unloaded and has been created
-//Should be used to Free Memory
-//-------------
-Destructor TPartySession.Destroy;
-begin
- //Just save some Memory if it wasn't done now..
- SetLength(Modis, 0);
- inherited;
-end;
-
-//-------------
-// Registers a new Modi. wParam: Pointer to TUS_ModiInfo
-// Service for Plugins
-//-------------
-Function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer;
-var
- Len: Integer;
- Info: PUS_ModiInfo;
-begin
- Info := PModiInfo;
- //Copy Info if cbSize is correct
- If (Info.cbSize = SizeOf(TUS_ModiInfo)) then
- begin
- Len := Length(Modis);
- SetLength(Modis, Len + 1);
-
- Modis[Len].Info := Info^;
- end
- else
- Core.ReportError(Integer(PChar('Plugins try to Register Modi with wrong Pointer, or wrong TUS_ModiInfo Record.')), PChar('TPartySession'));
-
- // FIXME: return a valid result
- Result := 0;
-end;
-
-//----------
-// Returns a Number of a Random Plugin
-//----------
-Function TPartySession.GetRandomPlugin(TeamMode: Boolean): Cardinal;
-var
- LowestTP: Byte;
- NumPwithLTP: Word;
- I: Integer;
- R: Word;
-begin
- Result := StandardModi; //If there are no matching Modis, Play StandardModi
- LowestTP := high(Byte);
- NumPwithLTP := 0;
-
- //Search for Plugins not often played yet
- For I := 0 to high(Modis) do
- begin
- if (Modis[I].TimesPlayed < lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
- begin
- lowestTP := Modis[I].TimesPlayed;
- NumPwithLTP := 1;
- end
- else if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
- begin
- Inc(NumPwithLTP);
- end;
- end;
-
- //Create Random No
- R := Random(NumPwithLTP);
-
- //Search for Random Plugin
- For I := 0 to high(Modis) do
- begin
- if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
- begin
- //Plugin Found
- if (R = 0) then
- begin
- Result := I;
- Inc(Modis[I].TimesPlayed);
- Break;
- end;
-
- Dec(R);
- end;
- end;
-end;
-
-//----------
-// Starts new Party Mode. Returns Non Zero on Success
-//----------
-Function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer;
-var
- I: Integer;
- aiRounds: PARounds;
- TeamMode: Boolean;
-begin
- Result := 0;
- If (Teams.NumTeams >= 1) AND (NumRounds < High(Byte)-1) then
- begin
- bPartyMode := false;
- aiRounds := PAofIRounds;
-
- Try
- //Is this Teammode(More then one Player per Team) ?
- TeamMode := True;
- For I := 0 to Teams.NumTeams-1 do
- TeamMode := TeamMode AND (Teams.Teaminfo[I].NumPlayers > 1);
-
- //Set Rounds
- SetLength(Rounds, NumRounds);
-
- For I := 0 to High(Rounds) do
- begin //Set Plugins
- If (aiRounds[I] = -1) then
- Rounds[I].Modi := GetRandomPlugin(TeamMode)
- Else If (aiRounds[I] >= 0) AND (aiRounds[I] <= High(Modis)) AND (TeamMode OR ((Modis[aiRounds[I]].Info.LoadingSettings AND MLS_TeamOnly) = 0)) then
- Rounds[I].Modi := aiRounds[I]
- Else
- Rounds[I].Modi := StandardModi;
-
- Rounds[I].Winner := High(Byte); //Set Winner to Not Played
- end;
-
- CurRound := High(Byte); //Set CurRound to not defined
-
- //Return teh true and Set PartyMode
- bPartyMode := True;
- Result := 1;
-
- Except
- Core.ReportError(Integer(PChar('Can''t start PartyMode.')), PChar('TPartySession'));
- end;
- end;
-end;
-
-//----------
-// Returns Pointer to Cur. ModiInfoEx (to Use with Singscreen)
-//----------
-Function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer;
-begin
- If (bPartyMode) AND (CurRound <= High(Rounds)) then
- begin //If PartyMode is enabled:
- //Return the Plugin of the Cur Round
- Result := Integer(@Modis[Rounds[CurRound].Modi]);
- end
- else
- begin //Return StandardModi
- Result := Integer(@Modis[StandardModi]);
- end;
-end;
-
-//----------
-// Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible
-//----------
-Function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer;
-begin
- Result := -1;
- If (bPartyMode) then
- begin
- // to-do : Whitü: Check here if SingScreen is not Shown atm.
- bPartyMode := False;
- Result := 1;
- end
- else
- Result := 0;
-end;
-
-//----------
-//GetRandomPlayer - Gives back a Random Player to Play next Round
-//----------
-function TPartySession.GetRandomPlayer(Team: Byte): Byte;
-var
- I, R: Integer;
- lowestTP: Byte;
- NumPwithLTP: Byte;
-begin
- LowestTP := high(Byte);
- NumPwithLTP := 0;
- Result := 0;
-
- //Search for Players that have not often played yet
- For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
- begin
- if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
- begin
- lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
- NumPwithLTP := 1;
- end
- else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
- begin
- Inc(NumPwithLTP);
- end;
- end;
-
- //Create Random No
- R := Random(NumPwithLTP);
-
- //Search for Random Player
- For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
- begin
- if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then
- begin
- //Player Found
- if (R = 0) then
- begin
- Result := I;
- Break;
- end;
-
- Dec(R);
- end;
- end;
-end;
-
-//----------
-// NextRound - Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
-//----------
-Function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer;
-var I: Integer;
-begin
- If ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then
- begin //everythings OK! -> Start the Round, maaaaan
- Inc(CurRound);
-
- //Set Players to play this Round
- for I := 0 to Teams.NumTeams-1 do
- Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I);
-
- // FIXME: return a valid result
- Result := 0;
- end
- else
- Result := -1;
-end;
-
-//----------
-//IsWinner - Returns True if the Players Bit is set in the Winner Byte
-//----------
-function TPartySession.IsWinner(Player, Winner: Byte): boolean;
-var
- Bit: Byte;
-begin
- Bit := 1 shl Player;
-
- Result := ((Winner AND Bit) = Bit);
-end;
-
-//----------
-//GenScores - Inc Scores for Cur. Round
-//----------
-procedure TPartySession.GenScores;
-var
- I: Byte;
-begin
- for I := 0 to Teams.NumTeams-1 do
- begin
- if isWinner(I, Rounds[CurRound].Winner) then
- Inc(Teams.Teaminfo[I].Score);
- end;
-end;
-
-//----------
-// CallModiInit - Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
-//----------
-Function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer;
-begin
- If (not bPartyMode) then
- begin //Set Rounds if not in PartyMode
- SetLength(Rounds, 1);
- Rounds[0].Modi := StandardModi;
- Rounds[0].Winner := High(Byte);
- CurRound := 0;
- end;
-
- Try
- //Core.
- Except
- on E : Exception do
- begin
- Core.ReportError(Integer(PChar('Error starting Modi: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession'));
- If (Rounds[CurRound].Modi = StandardModi) then
- begin
- Core.ReportError(Integer(PChar('Can''t start StandardModi, will exit now!')), PChar('TPartySession'));
- Halt;
- end
- Else //Select StandardModi
- begin
- Rounds[CurRound].Modi := StandardModi
- end;
- end;
- End;
-
- // FIXME: return a valid result
- Result := 0;
-end;
-
-//----------
-// CallModiDeInit - Calls DeInitProc and does the RoundEnding
-//----------
-Function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer;
-var
- I: Integer;
- MaxScore: Word;
-begin
- If (bPartyMode) then
- begin
- //Get Winner Byte!
- if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get Winners from Plugin
- Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID)
- else
- begin //Create winners by Score :/
- Rounds[CurRound].Winner := 0;
- MaxScore := 0;
- for I := 0 to Teams.NumTeams-1 do
- begin
- // to-do : recode Percentage stuff
- //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999;
- if (Player[I].ScoreTotalInt > MaxScore) then
- begin
- MaxScore := Player[I].ScoreTotalInt;
- Rounds[CurRound].Winner := 1 shl I;
- end
- else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then
- begin
- Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I);
- end;
- end;
-
-
- //When nobody has Points -> Everybody loose
- if (MaxScore = 0) then
- Rounds[CurRound].Winner := 0;
-
- end;
-
- //Generate teh Scores
- GenScores;
-
- //Inc Players TimesPlayed
- If ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings AND MLS_IncTP) = MLS_IncTP) then
- begin
- For I := 0 to Teams.NumTeams-1 do
- Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed);
- end;
- end
- else if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then
- Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID);
-
- // FIXME: return a valid result
- Result := 0;
-end;
-
-//----------
-// GetTeamInfo - Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
-//----------
-Function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
-var Info: ^TTeamInfo;
-begin
- Result := -1;
- Info := pTeamInfo;
- If (Info <> nil) then
- begin
- Try
- // to - do : Check Delphi memory management in this case
- //Not sure if i had to copy PChars to a new address or if delphi manages this o0
- Info^ := Teams;
- Result := 0;
- Except
- Result := -2;
- End;
- end;
-end;
-
-//----------
-// SetTeamInfo - Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
-//----------
-Function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
-var
- TeamInfobackup: TTeamInfo;
- Info: ^TTeamInfo;
-begin
- Result := -1;
- Info := pTeamInfo;
- If (Info <> nil) then
- begin
- Try
- TeamInfoBackup := Teams;
- // to - do : Check Delphi memory management in this case
- //Not sure if i had to copy PChars to a new address or if delphi manages this o0
- Teams := Info^;
- Result := 0;
- Except
- Teams := TeamInfoBackup;
- Result := -2;
- End;
- end;
-end;
-
-//----------
-// GetTeamOrder - Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
-//----------
-Function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer;
-var
- I, J: Integer;
- ATeams: array [0..5] of TeamOrderEntry;
- TempTeam: TeamOrderEntry;
-begin
- // to-do : PartyMode: Write this in another way, so that teams with the same scire get the same Placing
- //Fill Team Array
- For I := 0 to Teams.NumTeams-1 do
- begin
- ATeams[I].Teamnum := I;
- ATeams[I].Score := Teams.Teaminfo[I].Score;
- end;
-
- //Sort Teams
- for J := 0 to Teams.NumTeams-1 do
- for I := 1 to Teams.NumTeams-1 do
- if ATeams[I].Score > ATeams[I-1].Score then
- begin
- TempTeam := ATeams[I-1];
- ATeams[I-1] := ATeams[I];
- ATeams[I] := TempTeam;
- end;
-
- //Copy to Result
- Result := 0;
- For I := 0 to Teams.NumTeams-1 do
- Result := Result or (ATeams[I].TeamNum Shl I*3);
-end;
-
-//----------
-// GetWinnerString - wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
-//----------
-Function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer;
-var
- Winners: Array of String;
- I: Integer;
- ResultStr: String;
- S: ^String;
-begin
- ResultStr := Language.Translate('PARTY_NOBODY');
-
- if (wParam <= High(Rounds)) then
- begin
- if (Rounds[wParam].Winner <> 0) then
- begin
- if (Rounds[wParam].Winner = 255) then
- begin
- ResultStr := Language.Translate('PARTY_NOTPLAYEDYET');
- end
- else
- begin
- SetLength(Winners, 0);
- for I := 0 to Teams.NumTeams-1 do
- begin
- if isWinner(I, Rounds[wParam].Winner) then
- begin
- SetLength(Winners, Length(Winners) + 1);
- Winners[high(Winners)] := Teams.TeamInfo[I].Name;
- end;
- end;
- ResultStr := Language.Implode(Winners);
- end;
- end;
- end;
-
- //Now Return what we have got
- If (lParam = nil) then
- begin //ReturnString Length
- Result := Length(ResultStr);
- end
- Else
- begin //Return String
- Try
- S := lParam;
- S^ := ResultStr;
- Result := 0;
- Except
- Result := -1;
-
- End;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UPlatform.pas b/Game/Code/Classes/UPlatform.pas
deleted file mode 100644
index b71ac1b8..00000000
--- a/Game/Code/Classes/UPlatform.pas
+++ /dev/null
@@ -1,165 +0,0 @@
-unit UPlatform;
-
-// Comment by Eddie:
-// This unit defines an interface for platform specific utility functions.
-// The Interface is implemented in separate files for each platform:
-// UPlatformWindows, UPlatformLinux and UPlatformMacOSX.
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses Classes;
-
-type
- TDirectoryEntry = record
- Name : WideString;
- IsDirectory : boolean;
- IsFile : boolean;
- end;
-
- TDirectoryEntryArray = array of TDirectoryEntry;
-
- TPlatform = class
- procedure Init; virtual;
- function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; virtual; abstract;
- function TerminateIfAlreadyRunning(var WndTitle : string): boolean; virtual;
- function FindSongFile(Dir, Mask: WideString): WideString; virtual;
- procedure Halt; virtual;
- function GetLogPath : WideString; virtual; abstract;
- function GetGameSharedPath : WideString; virtual; abstract;
- function GetGameUserPath : WideString; virtual; abstract;
- function CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean; virtual;
- end;
-
- function Platform(): TPlatform;
-
-implementation
-
-uses
- SysUtils,
- {$IFDEF MSWINDOWS}
- UPlatformWindows,
- {$ENDIF}
- {$IFDEF LINUX}
- UPlatformLinux,
- {$ENDIF}
- {$IFDEF DARWIN}
- UPlatformMacOSX,
- {$ENDIF}
- ULog;
-
-
-// I have modified it to use the Platform_singleton in this location ( in the implementaiton )
-// so that this variable can NOT be overwritten from anywhere else in the application.
-// the accessor function platform, emulates all previous calls to work the same way.
-var
- Platform_singleton : TPlatform;
-
-function Platform : TPlatform;
-begin
- Result := Platform_singleton;
-end;
-
-(**
- * Default Init() implementation
- *)
-procedure TPlatform.Init;
-begin
-end;
-
-(**
- * Default Halt() implementation
- *)
-procedure TPlatform.Halt;
-begin
- // Note: Application.terminate is NOT the same
- System.Halt;
-end;
-
-(**
- * Default TerminateIfAlreadyRunning() implementation
- *)
-function TPlatform.TerminateIfAlreadyRunning(var WndTitle : string): Boolean;
-begin
- Result := false;
-end;
-
-(**
- * Default FindSongFile() implementation
- *)
-function TPlatform.FindSongFile(Dir, Mask: WideString): WideString;
-var
- SR: TSearchRec; // for parsing song directory
-begin
- Result := '';
- if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then
- begin
- Result := SR.Name;
- end;
- SysUtils.FindClose(SR);
-end;
-
-function TPlatform.CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean;
-const
- COPY_BUFFER_SIZE = 4096; // a good tradeoff between speed and memory consumption
-var
- SourceFile, TargetFile: TFileStream;
- FileCopyBuffer: array [0..COPY_BUFFER_SIZE-1] of byte; // temporary copy-buffer.
- NumberOfBytes: integer; // number of bytes read from SourceFile
-begin
- Result := false;
- SourceFile := nil;
- TargetFile := nil;
-
- // if overwrite is disabled return if the target file already exists
- if (FailIfExists and FileExists(Target)) then
- Exit;
-
- try
- try
- // open source and target file (might throw an exception on error)
- SourceFile := TFileStream.Create(Source, fmOpenRead);
- TargetFile := TFileStream.Create(Target, fmCreate or fmOpenWrite);
-
- while true do
- begin
- // read a block from the source file and check for errors or EOF
- NumberOfBytes := SourceFile.Read(FileCopyBuffer, SizeOf(FileCopyBuffer));
- if (NumberOfBytes <= 0) then
- Break;
- // write block to target file and check if everything was written
- if (TargetFile.Write(FileCopyBuffer, NumberOfBytes) <> NumberOfBytes) then
- Exit;
- end;
- except
- Exit;
- end;
- finally
- SourceFile.Free;
- TargetFile.Free;
- end;
-
- Result := true;
-end;
-
-
-initialization
-{$IFDEF MSWINDOWS}
- Platform_singleton := TPlatformWindows.Create;
-{$ENDIF}
-{$IFDEF LINUX}
- Platform_singleton := TPlatformLinux.Create;
-{$ENDIF}
-{$IFDEF DARWIN}
- Platform_singleton := TPlatformMacOSX.Create;
-{$ENDIF}
-
-finalization
- Platform_singleton.Free;
-
-end.
diff --git a/Game/Code/Classes/UPlatformLinux.pas b/Game/Code/Classes/UPlatformLinux.pas
deleted file mode 100644
index 27fb130e..00000000
--- a/Game/Code/Classes/UPlatformLinux.pas
+++ /dev/null
@@ -1,160 +0,0 @@
-unit UPlatformLinux;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Classes,
- UPlatform,
- UConfig;
-
-type
- TPlatformLinux = class(TPlatform)
- private
- function GetHomeDir(): string;
- public
- function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; override;
-
- function GetLogPath : WideString; override;
- function GetGameSharedPath : WideString; override;
- function GetGameUserPath : WideString; override;
- end;
-
-implementation
-
-uses
- UCommandLine,
- BaseUnix,
- {$IF FPC_VERSION_INT >= 2002002}
- pwd,
- {$IFEND}
- SysUtils,
- ULog;
-
-function TPlatformLinux.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray;
-var
- i: Integer;
- TheDir : pDir;
- ADirent : pDirent;
- Entry : Longint;
- lAttrib : integer;
-begin
- i := 0;
- Filter := LowerCase(Filter);
-
- TheDir := FpOpenDir( Dir );
- if Assigned(TheDir) then
- begin
- repeat
- ADirent := FpReadDir(TheDir^);
-
- if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then
- begin
- lAttrib := FileGetAttr(Dir + ADirent^.d_name);
- if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then
- begin
- SetLength( Result, i + 1);
- Result[i].Name := ADirent^.d_name;
- Result[i].IsDirectory := true;
- Result[i].IsFile := false;
- i := i + 1;
- end
- else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then
- begin
- SetLength( Result, i + 1);
- Result[i].Name := ADirent^.d_name;
- Result[i].IsDirectory := false;
- Result[i].IsFile := true;
- i := i + 1;
- end;
- end;
- until (ADirent = nil);
-
- FpCloseDir(TheDir^);
- end;
-end;
-
-function TPlatformLinux.GetLogPath: WideString;
-begin
- if FindCmdLineSwitch( cUseLocalPaths ) then
- begin
- Result := ExtractFilePath(ParamStr(0));
- end
- else
- begin
- {$IFDEF UseLocalDirs}
- Result := ExtractFilePath(ParamStr(0));
- {$ELSE}
- Result := GetGameUserPath() + 'logs' + PathDelim;
- {$ENDIF}
- end;
-
- // create non-existing directories
- ForceDirectories(Result);
-end;
-
-function TPlatformLinux.GetGameSharedPath: WideString;
-begin
- if FindCmdLineSwitch( cUseLocalPaths ) then
- Result := ExtractFilePath(ParamStr(0))
- else
- begin
- {$IFDEF UseLocalDirs}
- Result := ExtractFilePath(ParamStr(0));
- {$ELSE}
- Result := SharedPath + PathDelim;
- {$ENDIF}
- end;
-end;
-
-function TPlatformLinux.GetGameUserPath: WideString;
-begin
- if FindCmdLineSwitch( cUseLocalPaths ) then
- Result := ExtractFilePath(ParamStr(0))
- else
- begin
- {$IFDEF UseLocalDirs}
- Result := ExtractFilePath(ParamStr(0));
- {$ELSE}
- Result := GetHomeDir() + '.'+PathSuffix + PathDelim;
- {$ENDIF}
- end;
-end;
-
-(**
- * Returns the user's home directory terminated by a path delimiter
- *)
-function TPlatformLinux.GetHomeDir(): string;
-{$IF FPC_VERSION_INT >= 2002002}
-var
- PasswdEntry: PPasswd;
-{$IFEND}
-begin
- Result := '';
-
- {$IF FPC_VERSION_INT >= 2002002}
- // try to retrieve the info from passwd
- PasswdEntry := FpGetpwuid(FpGetuid());
- if (PasswdEntry <> nil) then
- Result := PasswdEntry.pw_dir;
- {$IFEND}
- // fallback if passwd does not contain the path
- if (Result = '') then
- Result := GetEnvironmentVariable('HOME');
- // add trailing path delimiter (normally '/')
- if (Result <> '') then
- Result := IncludeTrailingPathDelimiter(Result);
-
- {$IF FPC_VERSION_INT >= 2002002}
- // GetUserDir() is another function that returns a user path.
- // It uses env-var HOME or a fallback to a temp-dir.
- //Result := GetUserDir();
- {$IFEND}
-end;
-
-end.
diff --git a/Game/Code/Classes/UPlatformMacOSX.pas b/Game/Code/Classes/UPlatformMacOSX.pas
deleted file mode 100644
index 849c354b..00000000
--- a/Game/Code/Classes/UPlatformMacOSX.pas
+++ /dev/null
@@ -1,294 +0,0 @@
-unit UPlatformMacOSX;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- Classes,
- ULog,
- UPlatform;
-
-type
- {**
- * @abstract(Provides Mac OS X specific details.)
- * @lastmod(August 1, 2008)
- * The UPlatformMacOSX unit takes care of setting paths to resource folders.
- *
- * (Note for non-Maccies: "folder" is the Mac name for directory.)
- *
- * Note on the resource folders:
- * 1. Installation of an application on the mac works as follows: Extract and copy an application
- * and if you don't like or need the application anymore you move the folder
- * to the trash - and you're done.
- * 2. The use folders in the user's home directory is against Apple's guidelines
- * and strange to an average user.
- * 3. Even worse is using /usr/local/... since all lowercase folders in / are
- * not visible to an average user in the Finder, at least not without some "tricks".
- *
- * The best way would be to store everything within the application bundle. However, this
- * requires USDX to offer the handling of the resources. Until this is implemented, the
- * second best solution is as follows:
- *
- * According to Aple guidelines handling of resources and folders should follow these lines:
- *
- * Acceptable places for files are folders named UltraStarDeluxe either in
- * /Library/Application Support/
- * or
- * ~/Library/Application Support/
- *
- * So
- * GetGameSharedPath could return
- * /Library/Application Support/UltraStarDeluxe/Resources/.
- * GetGameUserPath could return
- * ~/Library/Application Support/UltraStarDeluxe/Resources/.
- *
- * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
- * is used. So every user needs the complete set of files and folders.
- * Future versions may also use shared resources in
- * /Library/Application Support/UltraStarDeluxe/Resources. However, this is not
- * treated yet in the code outside this unit.
- *
- * USDX checks, whether GetGameUserPath exists. If not, USDX creates it.
- * The existence of needed files is then checked and if a file is missing
- * it is copied to there from within the Resources folder in the Application
- * bundle, which contains the default files. USDX should not delete files or
- * folders in Application Support/UltraStarDeluxe automatically or without
- * user confirmation.
- *}
- TPlatformMacOSX = class(TPlatform)
- private
- {**
- * GetBundlePath returns the path to the application bundle UltraStarDeluxe.app.
- *}
- function GetBundlePath: WideString;
-
- {**
- * GetApplicationSupportPath returns the path to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
- *}
- function GetApplicationSupportPath: WideString;
-
- {**
- * see the description of @link(Init).
- *}
- procedure CreateUserFolders();
-
- public
- {**
- * Init simply calls @link(CreateUserFolders), which in turn scans the folder
- * UltraStarDeluxe.app/Contents/Resources for all files and folders.
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources is then checked
- * for their presence and missing ones are copied.
- *}
- procedure Init; override;
-
- {**
- * DirectoryFindFiles returns all entries of a folder with names and booleans
- * about their type, i.e. file or directory.
- *}
- function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override;
-
- {**
- * GetLogPath returns the path for log messages. Currently it is set to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources/Log.
- *}
- function GetLogPath : WideString; override;
-
- {**
- * GetGameSharedPath returns the path for shared resources. Currently it is set to
- * /Library/Application Support/UltraStarDeluxe/Resources.
- * However it is not used.
- *}
- function GetGameSharedPath : WideString; override;
-
- {**
- * GetGameUserPath returns the path for user resources. Currently it is set to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
- * This is where a user can add songs, themes, ....
- *}
- function GetGameUserPath : WideString; override;
- end;
-
-implementation
-
-uses
- SysUtils,
- BaseUnix;
-
-procedure TPlatformMacOSX.Init;
-begin
- CreateUserFolders();
-end;
-
-procedure TPlatformMacOSX.CreateUserFolders();
-var
- RelativePath: string;
- // BaseDir contains the path to the folder, where a search is performed.
- // It is set to the entries in @link(DirectoryList) one after the other.
- BaseDir: string;
- // OldBaseDir contains the path to the folder, where the search started.
- // It is used to return to it, when the search is completed in all folders.
- OldBaseDir: string;
- // This record contains the result of a file search with FindFirst or FindNext
- SearchInfo: TSearchRec;
- // These two lists contain all folder and file names found
- // within the folder @link(BaseDir).
- DirectoryList, FileList: TStringList;
- // DirectoryIsFinished contains the index of the folder in @link(DirectoryList),
- // which is the last one completely searched. Later folders are still to be
- // searched for additional files and folders.
- DirectoryIsFinished: longint;
- Counter: longint;
-
- UserPathName: string;
-const
- // used to construct the @link(UserPathName)
- PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources';
-begin
- // Get the current folder and save it in OldBaseDir for returning to it, when
- // finished.
- GetDir(0, OldBaseDir);
-
- // UltraStarDeluxe.app/Contents/Resources contains all the default files and
- // folders.
- BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources';
- ChDir(BaseDir);
-
- // Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
- // is used.
- UserPathName := GetEnvironmentVariable('HOME') + PathName;
-
- DirectoryIsFinished := 0;
- DirectoryList := TStringList.Create();
- FileList := TStringList.Create();
- DirectoryList.Add('.');
-
- // create the folder and file lists
- repeat
-
- RelativePath := DirectoryList[DirectoryIsFinished];
- ChDir(BaseDir + '/' + RelativePath);
- if (FindFirst('*', faAnyFile, SearchInfo) = 0) then
- begin
- repeat
- if DirectoryExists(SearchInfo.Name) then
- begin
- if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then
- DirectoryList.Add(RelativePath + '/' + SearchInfo.Name);
- end
- else
- Filelist.Add(RelativePath + '/' + SearchInfo.Name);
- until (FindNext(SearchInfo) <> 0);
- end;
- FindClose(SearchInfo);
- Inc(DirectoryIsFinished);
- until (DirectoryIsFinished = DirectoryList.Count);
-
- // create missing folders
- for Counter := 0 to DirectoryList.Count-1 do
- begin
- if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then
- Log.LogError('Failed to create the folder "'+ UserPathName + '/' + DirectoryList[Counter] +'"',
- 'TPlatformMacOSX.CreateUserFolders');
- end;
- DirectoryList.Free();
-
- // copy missing files
- for Counter := 0 to Filelist.Count-1 do
- begin
- CopyFile(BaseDir + '/' + Filelist[Counter],
- UserPathName + '/' + Filelist[Counter], true);
- end;
- FileList.Free();
-
- // go back to the initial folder
- ChDir(OldBaseDir);
-end;
-
-function TPlatformMacOSX.GetBundlePath: WideString;
-var
- i, pos : integer;
-begin
- // Mac applications are packaged in folders.
- // We have to cut the last two folders
- // to get the application folder.
-
- Result := ExtractFilePath(ParamStr(0));
- for i := 1 to 2 do
- begin
- pos := Length(Result);
- repeat
- Delete(Result, pos, 1);
- pos := Length(Result);
- until (pos = 0) or (Result[pos] = '/');
- end;
-end;
-
-function TPlatformMacOSX.GetApplicationSupportPath: WideString;
-const
- PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources';
-begin
- Result := GetEnvironmentVariable('HOME') + PathName + '/';
-end;
-
-function TPlatformMacOSX.GetLogPath: WideString;
-begin
- Result := GetApplicationSupportPath + 'Logs';
-end;
-
-function TPlatformMacOSX.GetGameSharedPath: WideString;
-begin
- Result := GetApplicationSupportPath;
-end;
-
-function TPlatformMacOSX.GetGameUserPath: WideString;
-begin
- Result := GetApplicationSupportPath;
-end;
-
-function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray;
-var
- i : integer;
- TheDir : pdir;
- ADirent : pDirent;
- lAttrib : integer;
-begin
- i := 0;
- Filter := LowerCase(Filter);
-
- TheDir := FPOpenDir(Dir);
- if Assigned(TheDir) then
- repeat
- ADirent := FPReadDir(TheDir);
-
- if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then
- begin
- lAttrib := FileGetAttr(Dir + ADirent^.d_name);
- if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then
- begin
- SetLength(Result, i + 1);
- Result[i].Name := ADirent^.d_name;
- Result[i].IsDirectory := true;
- Result[i].IsFile := false;
- i := i + 1;
- end
- else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then
- begin
- SetLength(Result, i + 1);
- Result[i].Name := ADirent^.d_name;
- Result[i].IsDirectory := false;
- Result[i].IsFile := true;
- i := i + 1;
- end;
- end;
- until ADirent = nil;
-
- FPCloseDir(TheDir);
-end;
-
-end.
diff --git a/Game/Code/Classes/UPlatformWindows.pas b/Game/Code/Classes/UPlatformWindows.pas
deleted file mode 100644
index ee132a7b..00000000
--- a/Game/Code/Classes/UPlatformWindows.pas
+++ /dev/null
@@ -1,236 +0,0 @@
-unit UPlatformWindows;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-// turn off messages for platform specific symbols
-{$WARN SYMBOL_PLATFORM OFF}
-
-uses
- Classes,
- UPlatform;
-
-type
- TPlatformWindows = class(TPlatform)
- private
- function GetSpecialPath(CSIDL: integer): WideString;
- public
- function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; override;
- function TerminateIfAlreadyRunning(var WndTitle: String): Boolean; override;
-
- function GetLogPath: WideString; override;
- function GetGameSharedPath: WideString; override;
- function GetGameUserPath: WideString; override;
-
- function CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean; override;
- end;
-
-implementation
-
-uses
- SysUtils,
- ShlObj,
- Windows,
- UConfig;
-
-type
- TSearchRecW = record
- Time: Integer;
- Size: Integer;
- Attr: Integer;
- Name: WideString;
- ExcludeAttr: Integer;
- FindHandle: THandle;
- FindData: TWin32FindDataW;
- end;
-
-function FindFirstW(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; forward;
-function FindNextW(var F: TSearchRecW): Integer; forward;
-procedure FindCloseW(var F: TSearchRecW); forward;
-function FindMatchingFileW(var F: TSearchRecW): Integer; forward;
-function DirectoryExistsW(const Directory: widestring): Boolean; forward;
-
-function FindFirstW(const Path: widestring; Attr: Integer; var F: TSearchRecW): Integer;
-const
- faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
-begin
- F.ExcludeAttr := not Attr and faSpecial;
-{$IFDEF Delphi}
- F.FindHandle := FindFirstFileW(PWideChar(Path), F.FindData);
-{$ELSE}
- F.FindHandle := FindFirstFileW(PWideChar(Path), @F.FindData);
-{$ENDIF}
- if F.FindHandle <> INVALID_HANDLE_VALUE then
- begin
- Result := FindMatchingFileW(F);
- if Result <> 0 then FindCloseW(F);
- end else
- Result := GetLastError;
-end;
-
-function FindNextW(var F: TSearchRecW): Integer;
-begin
-{$IFDEF Delphi}
- if FindNextFileW(F.FindHandle, F.FindData) then
-{$ELSE}
- if FindNextFileW(F.FindHandle, @F.FindData) then
-{$ENDIF}
- Result := FindMatchingFileW(F)
- else
- Result := GetLastError;
-end;
-
-procedure FindCloseW(var F: TSearchRecW);
-begin
- if F.FindHandle <> INVALID_HANDLE_VALUE then
- begin
- Windows.FindClose(F.FindHandle);
- F.FindHandle := INVALID_HANDLE_VALUE;
- end;
-end;
-
-function FindMatchingFileW(var F: TSearchRecW): Integer;
-var
- LocalFileTime: TFileTime;
-begin
- with F do
- begin
- while FindData.dwFileAttributes and ExcludeAttr <> 0 do
-{$IFDEF Delphi}
- if not FindNextFileW(FindHandle, FindData) then
-{$ELSE}
- if not FindNextFileW(FindHandle, @FindData) then
-{$ENDIF}
- begin
- Result := GetLastError;
- Exit;
- end;
- FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
- FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
- Size := FindData.nFileSizeLow;
- Attr := FindData.dwFileAttributes;
- Name := FindData.cFileName;
- end;
- Result := 0;
-end;
-
-function DirectoryExistsW(const Directory: widestring): Boolean;
-var
- Code: Integer;
-begin
- Code := GetFileAttributesW(PWideChar(Directory));
- Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
-end;
-
-//------------------------------
-//Start more than One Time Prevention
-//------------------------------
-function TPlatformWindows.TerminateIfAlreadyRunning(var WndTitle: String): Boolean;
-var
- hWnd: THandle;
- I: Integer;
-begin
- Result := false;
- hWnd:= FindWindow(nil, PChar(WndTitle));
- //Programm already started
- if (hWnd <> 0) then
- begin
- I := Messagebox(0, PChar('Another Instance of Ultrastar is already running. Continue ?'), PChar(WndTitle), MB_ICONWARNING or MB_YESNO);
- if (I = IDYes) then
- begin
- I := 1;
- repeat
- Inc(I);
- hWnd := FindWindow(nil, PChar(WndTitle + ' Instance ' + InttoStr(I)));
- until (hWnd = 0);
- WndTitle := WndTitle + ' Instance ' + InttoStr(I);
- end
- else
- Result := true;
- end;
-end;
-
-function TPlatformWindows.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray;
-var
- i : Integer;
- SR : TSearchRecW;
- Attrib : Integer;
-begin
- i := 0;
- Filter := LowerCase(Filter);
-
- if FindFirstW(Dir + '*', faAnyFile or faDirectory, SR) = 0 then
- repeat
- if (SR.Name <> '.') and (SR.Name <> '..') then
- begin
- Attrib := FileGetAttr(Dir + SR.name);
- if ReturnAllSubDirs and ((Attrib and faDirectory) <> 0) then
- begin
- SetLength( Result, i + 1);
- Result[i].Name := SR.name;
- Result[i].IsDirectory := true;
- Result[i].IsFile := false;
- i := i + 1;
- end
- else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(SR.Name)) > 0) then
- begin
- SetLength( Result, i + 1);
- Result[i].Name := SR.Name;
- Result[i].IsDirectory := false;
- Result[i].IsFile := true;
- i := i + 1;
- end;
- end;
- until FindNextW(SR) <> 0;
- FindCloseW(SR);
-end;
-
-(**
- * Returns the path of a special folder.
- *
- * Some Folder IDs:
- * CSIDL_APPDATA (e.g. C:\Documents and Settings\username\Application Data)
- * CSIDL_LOCAL_APPDATA (e.g. C:\Documents and Settings\username\Local Settings\Application Data)
- * CSIDL_PROFILE (e.g. C:\Documents and Settings\username)
- * CSIDL_PERSONAL (e.g. C:\Documents and Settings\username\My Documents)
- * CSIDL_MYMUSIC (e.g. C:\Documents and Settings\username\My Documents\My Music)
- *)
-function TPlatformWindows.GetSpecialPath(CSIDL: integer): WideString;
-var
- Buffer: array [0..MAX_PATH-1] of WideChar;
-begin
-{$IF Defined(Delphi) or (FPC_VERSION_INT >= 2002002)} // >= 2.2.2
- if (SHGetSpecialFolderPathW(0, @Buffer, CSIDL, false)) then
- Result := Buffer
- else
-{$IFEND}
- Result := '';
-end;
-
-function TPlatformWindows.GetLogPath: WideString;
-begin
- Result := ExtractFilePath(ParamStr(0));
-end;
-
-function TPlatformWindows.GetGameSharedPath: WideString;
-begin
- Result := ExtractFilePath(ParamStr(0));
-end;
-
-function TPlatformWindows.GetGameUserPath: WideString;
-begin
- //Result := GetSpecialPath(CSIDL_APPDATA) + PathDelim + 'UltraStarDX' + PathDelim;
- Result := ExtractFilePath(ParamStr(0));
-end;
-
-function TPlatformWindows.CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean;
-begin
- Result := Windows.CopyFileW(PWideChar(Source), PWideChar(Target), FailIfExists);
-end;
-
-end.
diff --git a/Game/Code/Classes/UPlaylist.pas b/Game/Code/Classes/UPlaylist.pas
deleted file mode 100644
index c867c356..00000000
--- a/Game/Code/Classes/UPlaylist.pas
+++ /dev/null
@@ -1,490 +0,0 @@
-unit UPlaylist;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- USong;
-
-type
- TPlaylistItem = record
- Artist: String;
- Title: String;
- SongID: Integer;
- end;
-
- APlaylistItem = array of TPlaylistItem;
-
- TPlaylist = record
- Name: String;
- Filename: String;
- Items: APlaylistItem;
- end;
-
- APlaylist = array of TPlaylist;
-
- //----------
- //TPlaylistManager - Class for Managing Playlists (Loading, Displaying, Saving)
- //----------
- TPlaylistManager = class
- private
-
- public
- Mode: TSingMode; //Current Playlist Mode for SongScreen
- CurPlayList: Cardinal;
- CurItem: Cardinal;
-
- Playlists: APlaylist;
-
- constructor Create;
- Procedure LoadPlayLists;
- Function LoadPlayList(Index: Cardinal; Filename: String): Boolean;
- Procedure SavePlayList(Index: Cardinal);
-
- Procedure SetPlayList(Index: Cardinal);
-
- Function AddPlaylist(Name: String): Cardinal;
- Procedure DelPlaylist(const Index: Cardinal);
-
- Procedure AddItem(const SongID: Cardinal; const iPlaylist: Integer = -1);
- Procedure DelItem(const iItem: Cardinal; const iPlaylist: Integer = -1);
-
- Procedure GetNames(var PLNames: array of String);
- Function GetIndexbySongID(const SongID: Cardinal; const iPlaylist: Integer = -1): Integer;
- end;
-
- {Modes:
- 0: Standard Mode
- 1: Category Mode
- 2: PlayList Mode}
-
- var
- PlayListMan: TPlaylistManager;
-
-
-implementation
-
-uses USongs,
- ULog,
- UMain,
- //UFiles,
- UGraphic,
- UThemes,
- SysUtils;
-
-//----------
-//Create - Construct Class - Dummy for now
-//----------
-constructor TPlayListManager.Create;
-begin
- inherited;
- LoadPlayLists;
-end;
-
-//----------
-//LoadPlayLists - Load list of Playlists from PlayList Folder
-//----------
-Procedure TPlayListManager.LoadPlayLists;
-var
- SR: TSearchRec;
- Len: Integer;
- PlayListBuffer: TPlayList;
-begin
- SetLength(Playlists, 0);
-
- if FindFirst(PlayListPath + '*.upl', 0, SR) = 0 then
- begin
- repeat
- Len := Length(Playlists);
- SetLength(Playlists, Len +1);
-
- if not LoadPlayList (Len, Sr.Name) then
- SetLength(Playlists, Len)
- else
- begin
- // Sort the Playlists - Insertion Sort
- PlayListBuffer := Playlists[Len];
- Dec(Len);
- while (Len >= 0) AND (CompareText(Playlists[Len].Name, PlayListBuffer.Name) >= 0) do
- begin
- Playlists[Len+1] := Playlists[Len];
- Dec(Len);
- end;
- Playlists[Len+1] := PlayListBuffer;
- end;
-
- until FindNext(SR) <> 0;
- FindClose(SR);
- end;
-end;
-
-//----------
-//LoadPlayList - Load a Playlist in the Array
-//----------
-Function TPlayListManager.LoadPlayList(Index: Cardinal; Filename: String): Boolean;
- var
- F: TextFile;
- Line: String;
- PosDelimiter: Integer;
- SongID: Integer;
- Len: Integer;
-
- Function FindSong(Artist, Title: String): Integer;
- var I: Integer;
- begin
- Result := -1;
-
- For I := low(CatSongs.Song) to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[I].Title = Title) AND (CatSongs.Song[I].Artist = Artist) then
- begin
- Result := I;
- Break;
- end;
- end;
- end;
-begin
- if not FileExists(PlayListPath + Filename) then
- begin
- Log.LogError('Could not load Playlist: ' + Filename);
- Result := False;
- Exit;
- end;
- Result := True;
-
- //Load File
- AssignFile(F, PlayListPath + FileName);
- Reset(F);
-
- //Set Filename
- PlayLists[Index].Filename := Filename;
- PlayLists[Index].Name := '';
-
- //Read Until End of File
- While not Eof(F) do
- begin
- //Read Curent Line
- Readln(F, Line);
-
- if (Length(Line) > 0) then
- begin
- PosDelimiter := Pos(':', Line);
- if (PosDelimiter <> 0) then
- begin
- //Comment or Name String
- if (Line[1] = '#') then
- begin
- //Found Name Value
- if (Uppercase(Trim(copy(Line, 2, PosDelimiter - 2))) = 'NAME') then
- PlayLists[Index].Name := Trim(copy(Line, PosDelimiter + 1,Length(Line) - PosDelimiter))
-
- end
- //Song Entry
- else
- begin
- SongID := FindSong(Trim(copy(Line, 1, PosDelimiter - 1)), Trim(copy(Line, PosDelimiter + 1, Length(Line) - PosDelimiter)));
- if (SongID <> -1) then
- begin
- Len := Length(PlayLists[Index].Items);
- SetLength(PlayLists[Index].Items, Len + 1);
-
- PlayLists[Index].Items[Len].SongID := SongID;
-
- PlayLists[Index].Items[Len].Artist := Trim(copy(Line, 1, PosDelimiter - 1));
- PlayLists[Index].Items[Len].Title := Trim(copy(Line, PosDelimiter + 1, Length(Line) - PosDelimiter));
- end
- else Log.LogError('Could not find Song in Playlist: ' + PlayLists[Index].Filename + ', ' + Line);
- end;
- end;
- end;
- end;
-
- //If no special name is given, use Filename
- if PlayLists[Index].Name = '' then
- begin
- PlayLists[Index].Name := ChangeFileExt(FileName, '');
- end;
-
- //Finish (Close File)
- CloseFile(F);
-end;
-
-//----------
-//SavePlayList - Saves the specified Playlist
-//----------
-Procedure TPlayListManager.SavePlayList(Index: Cardinal);
-var
- F: TextFile;
- I: Integer;
-begin
- if (Not FileExists(PlaylistPath + Playlists[Index].Filename)) OR (Not FileisReadOnly(PlaylistPath + Playlists[Index].Filename)) then
- begin
-
- //open File for Rewriting
- AssignFile(F, PlaylistPath + Playlists[Index].Filename);
- try
- try
- Rewrite(F);
-
- //Write Version (not nessecary but helpful)
- WriteLn(F, '######################################');
- WriteLn(F, '#Ultrastar Deluxe Playlist Format v1.0');
- WriteLn(F, '#Playlist "' + Playlists[Index].Name + '" with ' + InttoStr(Length(Playlists[Index].Items)) + ' Songs.');
- WriteLn(F, '######################################');
-
- //Write Name Information
- WriteLn(F, '#Name: ' + Playlists[Index].Name);
-
- //Write Song Information
- WriteLn(F, '#Songs:');
-
- For I := 0 to high(Playlists[Index].Items) do
- begin
- WriteLn(F, Playlists[Index].Items[I].Artist + ' : ' + Playlists[Index].Items[I].Title);
- end;
- except
- log.LogError('Could not write Playlistfile "' + Playlists[Index].Name + '"');
- end;
- finally
- CloseFile(F);
- end;
- end;
-end;
-
-//----------
-//SetPlayList - Display a Playlist in CatSongs
-//----------
-Procedure TPlayListManager.SetPlayList(Index: Cardinal);
-var
- I: Integer;
-begin
- If (Int(Index) > High(PlayLists)) then
- exit;
-
- //Hide all Songs
- For I := 0 to high(CatSongs.Song) do
- CatSongs.Song[I].Visible := False;
-
- //Show Songs in PL
- For I := 0 to high(PlayLists[Index].Items) do
- begin
- CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True;
- end;
-
- //Set CatSongsMode + Playlist Mode
- CatSongs.CatNumShow := -3;
- Mode := smPlayListRandom;
-
- //Set CurPlaylist
- CurPlaylist := Index;
-
- //Show Cat in Topleft:
- ScreenSong.ShowCatTLCustom(Format(Theme.Playlist.CatText,[Playlists[Index].Name]));
-
- //Fix SongSelection
- ScreenSong.Interaction := 0;
- ScreenSong.SelectNext;
- ScreenSong.FixSelected;
-
- //Play correct Music
- ScreenSong.ChangeMusic;
-end;
-
-//----------
-//AddPlaylist - Adds a Playlist and Returns the Index
-//----------
-Function TPlayListManager.AddPlaylist(Name: String): Cardinal;
-var
- I: Integer;
-begin
- Result := Length(Playlists);
- SetLength(Playlists, Result + 1);
-
- // Sort the Playlists - Insertion Sort
- while (Result > 0) AND (CompareText(Playlists[Result - 1].Name, Name) >= 0) do
- begin
- Dec(Result);
- Playlists[Result+1] := Playlists[Result];
- end;
- Playlists[Result].Name := Name;
-
- I := 1;
- if (not FileExists(PlaylistPath + Name + '.upl')) then
- Playlists[Result].Filename := Name + '.upl'
- else
- begin
- repeat
- Inc(I);
- until not FileExists(PlaylistPath + Name + InttoStr(I) + '.upl');
- Playlists[Result].Filename := Name + InttoStr(I) + '.upl';
- end;
-
- //Save new Playlist
- SavePlayList(Result);
-end;
-
-//----------
-//DelPlaylist - Deletes a Playlist
-//----------
-Procedure TPlayListManager.DelPlaylist(const Index: Cardinal);
-var
- I: Integer;
- Filename: String;
-begin
- If Int(Index) > High(Playlists) then
- Exit;
-
- Filename := PlaylistPath + Playlists[Index].Filename;
-
- //If not FileExists or File is not Writeable then exit
- If (Not FileExists(Filename)) OR (FileisReadOnly(Filename)) then
- Exit;
-
-
- //Delete Playlist from FileSystem
- if Not DeleteFile(Filename) then
- Exit;
-
- //Delete Playlist from Array
- //move all PLs to the Hole
- For I := Index to High(Playlists)-1 do
- PlayLists[I] := PlayLists[I+1];
-
- //Delete last Playlist
- SetLength (Playlists, High(Playlists));
-
- //If Playlist is Displayed atm
- //-> Display Songs
- if (CatSongs.CatNumShow = -3) and (Index = CurPlaylist) then
- begin
- ScreenSong.UnLoadDetailedCover;
- ScreenSong.HideCatTL;
- CatSongs.SetFilter('', 0);
- ScreenSong.Interaction := 0;
- ScreenSong.FixSelected;
- ScreenSong.ChangeMusic;
- end;
-end;
-
-//----------
-//AddItem - Adds an Item to a specific Playlist
-//----------
-Procedure TPlayListManager.AddItem(const SongID: Cardinal; const iPlaylist: Integer);
-var
- P: Cardinal;
- Len: Cardinal;
-begin
- if iPlaylist = -1 then
- P := CurPlaylist
- else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
- P := iPlaylist
- else
- exit;
-
- if (Int(SongID) <= High(CatSongs.Song)) AND (NOT CatSongs.Song[SongID].Main) then
- begin
- Len := Length(Playlists[P].Items);
- SetLength(Playlists[P].Items, Len + 1);
-
- Playlists[P].Items[Len].SongID := SongID;
- Playlists[P].Items[Len].Title := CatSongs.Song[SongID].Title;
- Playlists[P].Items[Len].Artist := CatSongs.Song[SongID].Artist;
-
- //Save Changes
- SavePlayList(P);
-
- //Correct Display when Editing current Playlist
- if (CatSongs.CatNumShow = -3) and (P = CurPlaylist) then
- SetPlaylist(P);
- end;
-end;
-
-//----------
-//DelItem - Deletes an Item from a specific Playlist
-//----------
-Procedure TPlayListManager.DelItem(const iItem: Cardinal; const iPlaylist: Integer);
-var
- I: Integer;
- P: Cardinal;
-begin
- if iPlaylist = -1 then
- P := CurPlaylist
- else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
- P := iPlaylist
- else
- exit;
-
- if (Int(iItem) <= high(Playlists[P].Items)) then
- begin
- //Move all entrys behind deleted one to Front
- For I := iItem to High(Playlists[P].Items) - 1 do
- Playlists[P].Items[I] := Playlists[P].Items[I + 1];
-
- //Delete Last Entry
- SetLength(PlayLists[P].Items, Length(PlayLists[P].Items) - 1);
-
- //Save Changes
- SavePlayList(P);
- end;
-
- //Delete Playlist if Last Song is deleted
- if (Length(PlayLists[P].Items) = 0) then
- begin
- DelPlaylist(P);
- end
- //Correct Display when Editing current Playlist
- else if (CatSongs.CatNumShow = -3) and (P = CurPlaylist) then
- SetPlaylist(P);
-end;
-
-//----------
-//GetNames - Writes Playlist Names in a Array
-//----------
-Procedure TPlayListManager.GetNames(var PLNames: array of String);
-var
- I: Integer;
- Len: Integer;
-begin
- Len := High(Playlists);
-
- if (Length(PLNames) <> Len + 1) then
- exit;
-
- For I := 0 to Len do
- PLNames[I] := Playlists[I].Name;
-end;
-
-//----------
-//GetIndexbySongID - Returns Index in the specified Playlist of the given Song
-//----------
-Function TPlayListManager.GetIndexbySongID(const SongID: Cardinal; const iPlaylist: Integer): Integer;
-var
- P: Integer;
- I: Integer;
-begin
- Result := -1;
-
- if iPlaylist = -1 then
- P := CurPlaylist
- else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
- P := iPlaylist
- else
- exit;
-
- For I := 0 to high(Playlists[P].Items) do
- begin
- if (Playlists[P].Items[I].SongID = Int(SongID)) then
- begin
- Result := I;
- Break;
- end;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/UPluginInterface.pas b/Game/Code/Classes/UPluginInterface.pas
deleted file mode 100644
index 77693d0f..00000000
--- a/Game/Code/Classes/UPluginInterface.pas
+++ /dev/null
@@ -1,156 +0,0 @@
-unit uPluginInterface;
-{*********************
- uPluginInterface
- Unit fills a TPluginInterface Structur with Method Pointers
- Unit Contains all Functions called directly by Plugins
-*********************}
-
-interface
-
-{$I switches.inc}
-
-uses uPluginDefs;
-
-//---------------
-// Methods for Plugin
-//---------------
- {******** Hook specific Methods ********}
- {Function Creates a new Hookable Event and Returns the Handle
- or 0 on Failure. (Name already exists)}
- Function CreateHookableEvent (EventName: PChar): THandle; stdcall;
-
- {Function Destroys an Event and Unhooks all Hooks to this Event.
- 0 on success, not 0 on Failure}
- Function DestroyHookableEvent (hEvent: THandle): integer; stdcall;
-
- {Function start calling the Hook Chain
- 0 if Chain is called until the End, -1 if Event Handle is not valid
- otherwise Return Value of the Hook that breaks the Chain}
- Function NotivyEventHooks (hEvent: THandle; wParam: TwParam; lParam: TlParam): integer; stdcall;
-
- {Function Hooks an Event by Name.
- Returns Hook Handle on Success, otherwise 0}
- Function HookEvent (EventName: PChar; HookProc: TUS_Hook): THandle; stdcall;
-
- {Function Removes the Hook from the Chain
- Returns 0 on Success}
- Function UnHookEvent (hHook: THandle): Integer; stdcall;
-
- {Function Returns Non Zero if a Event with the given Name Exists,
- otherwise 0}
- Function EventExists (EventName: PChar): Integer; stdcall;
-
- {******** Service specific Methods ********}
- {Function Creates a new Service and Returns the Services Handle
- or 0 on Failure. (Name already exists)}
- Function CreateService (ServiceName: PChar; ServiceProc: TUS_Service): THandle; stdcall;
-
- {Function Destroys a Service.
- 0 on success, not 0 on Failure}
- Function DestroyService (hService: THandle): integer; stdcall;
-
- {Function Calls a Services Proc
- Returns Services Return Value or SERVICE_NOT_FOUND on Failure}
- Function CallService (ServiceName: PChar; wParam: TwParam; lParam: TlParam): integer; stdcall;
-
- {Function Returns Non Zero if a Service with the given Name Exists,
- otherwise 0}
- Function ServiceExists (ServiceName: PChar): Integer; stdcall;
-
-implementation
-uses UCore;
-
-{******** Hook specific Methods ********}
-//---------------
-// Function Creates a new Hookable Event and Returns the Handle
-// or 0 on Failure. (Name already exists)
-//---------------
-Function CreateHookableEvent (EventName: PChar): THandle; stdcall;
-begin
- Result := Core.Hooks.AddEvent(EventName);
-end;
-
-//---------------
-// Function Destroys an Event and Unhooks all Hooks to this Event.
-// 0 on success, not 0 on Failure
-//---------------
-Function DestroyHookableEvent (hEvent: THandle): integer; stdcall;
-begin
- Result := Core.Hooks.DelEvent(hEvent);
-end;
-
-//---------------
-// Function start calling the Hook Chain
-// 0 if Chain is called until the End, -1 if Event Handle is not valid
-// otherwise Return Value of the Hook that breaks the Chain
-//---------------
-Function NotivyEventHooks (hEvent: THandle; wParam: TwParam; lParam: TlParam): integer; stdcall;
-begin
- Result := Core.Hooks.CallEventChain(hEvent, wParam, lParam);
-end;
-
-//---------------
-// Function Hooks an Event by Name.
-// Returns Hook Handle on Success, otherwise 0
-//---------------
-Function HookEvent (EventName: PChar; HookProc: TUS_Hook): THandle; stdcall;
-begin
- Result := Core.Hooks.AddSubscriber(EventName, HookProc);
-end;
-
-//---------------
-// Function Removes the Hook from the Chain
-// Returns 0 on Success
-//---------------
-Function UnHookEvent (hHook: THandle): Integer; stdcall;
-begin
- Result := Core.Hooks.DelSubscriber(hHook);
-end;
-
-//---------------
-// Function Returns Non Zero if a Event with the given Name Exists,
-// otherwise 0
-//---------------
-Function EventExists (EventName: PChar): Integer; stdcall;
-begin
- Result := Core.Hooks.EventExists(EventName);
-end;
-
- {******** Service specific Methods ********}
-//---------------
-// Function Creates a new Service and Returns the Services Handle
-// or 0 on Failure. (Name already exists)
-//---------------
-Function CreateService (ServiceName: PChar; ServiceProc: TUS_Service): THandle; stdcall;
-begin
- Result := Core.Services.AddService(ServiceName, ServiceProc);
-end;
-
-//---------------
-// Function Destroys a Service.
-// 0 on success, not 0 on Failure
-//---------------
-Function DestroyService (hService: THandle): integer; stdcall;
-begin
- Result := Core.Services.DelService(hService);
-end;
-
-//---------------
-// Function Calls a Services Proc
-// Returns Services Return Value or SERVICE_NOT_FOUND on Failure
-//---------------
-Function CallService (ServiceName: PChar; wParam: TwParam; lParam: TlParam): integer; stdcall;
-begin
- Result := Core.Services.CallService(ServiceName, wParam, lParam);
-end;
-
-//---------------
-// Function Returns Non Zero if a Service with the given Name Exists,
-// otherwise 0
-//---------------
-Function ServiceExists (ServiceName: PChar): Integer; stdcall;
-begin
- Result := Core.Services.ServiceExists(ServiceName);
-end;
-
-end.
diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas
deleted file mode 100644
index 8a537dc9..00000000
--- a/Game/Code/Classes/URecord.pas
+++ /dev/null
@@ -1,766 +0,0 @@
-unit URecord;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses Classes,
- Math,
- SysUtils,
- sdl,
- UCommon,
- UMusic,
- UIni;
-
-const
- BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz)
- NumHalftones = 36; // C2-B4 (for Whitney and my high voice)
-
-type
- TCaptureBuffer = class
- private
- VoiceStream: TAudioVoiceStream; // stream for voice passthrough
- AnalysisBufferLock: PSDL_Mutex;
-
- function GetToneString: string; // converts a tone to its string represenatation;
-
- procedure BoostBuffer(Buffer: PChar; Size: Cardinal);
- procedure ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
-
- // we call it to analyze sound by checking Autocorrelation
- procedure AnalyzeByAutocorrelation;
- // use this to check one frequency by Autocorrelation
- function AnalyzeAutocorrelationFreq(Freq: real): real;
- public
- AnalysisBuffer: array[0..4095] of smallint; // newest 4096 samples
- AnalysisBufferSize: integer; // number of samples of BufferArray to analyze
-
- LogBuffer: TMemoryStream; // full buffer
-
- AudioFormat: TAudioFormatInfo;
-
- // pitch detection
- // TODO: remove ToneValid, set Tone/ToneAbs=-1 if invalid instead
- ToneValid: boolean; // true if Tone contains a valid value (otherwise it contains noise)
- Tone: integer; // tone relative to one octave (e.g. C2=C3=C4). Range: 0-11
- ToneAbs: integer; // absolute (full range) tone (e.g. C2<>C3). Range: 0..NumHalftones-1
-
- // methods
- constructor Create;
- destructor Destroy; override;
-
- procedure Clear;
-
- // use to analyze sound from buffers to get new pitch
- procedure AnalyzeBuffer;
- procedure LockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
- procedure UnlockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
-
- function MaxSampleVolume: Single;
- property ToneString: string READ GetToneString;
- end;
-
-const
- DEFAULT_SOURCE_NAME = '[Default]';
-
-type
- TAudioInputSource = record
- Name: string;
- end;
-
- // soundcard input-devices information
- TAudioInputDevice = class
- public
- CfgIndex: integer; // index of this device in Ini.InputDeviceConfig
- Name: string; // soundcard name
- Source: array of TAudioInputSource; // soundcard input-sources
- SourceRestore: integer; // source-index that will be selected after capturing (-1: not detected)
- MicSource: integer; // source-index of mic (-1: none detected)
-
- AudioFormat: TAudioFormatInfo; // capture format info (e.g. 44.1kHz SInt16 stereo)
- CaptureChannel: array of TCaptureBuffer; // sound-buffer references used for mono or stereo channel's capture data
-
- destructor Destroy; override;
-
- procedure LinkCaptureBuffer(ChannelIndex: integer; Sound: TCaptureBuffer);
-
- // TODO: add Open/Close functions so Start/Stop becomes faster
- //function Open(): boolean; virtual; abstract;
- //function Close(): boolean; virtual; abstract;
- function Start(): boolean; virtual; abstract;
- function Stop(): boolean; virtual; abstract;
-
- function GetVolume(): single; virtual; abstract;
- procedure SetVolume(Volume: single); virtual; abstract;
- end;
-
- TAudioInputProcessor = class
- public
- Sound: array of TCaptureBuffer; // sound-buffers for every player
- DeviceList: array of TAudioInputDevice;
-
- constructor Create;
- destructor Destroy; override;
-
- procedure UpdateInputDeviceConfig;
-
- // handle microphone input
- procedure HandleMicrophoneData(Buffer: PChar; Size: Cardinal;
- InputDevice: TAudioInputDevice);
- end;
-
- TAudioInputBase = class( TInterfacedObject, IAudioInput )
- private
- Started: boolean;
- protected
- function UnifyDeviceName(const name: string; deviceIndex: integer): string;
- public
- function GetName: String; virtual; abstract;
- function InitializeRecord: boolean; virtual; abstract;
- function FinalizeRecord: boolean; virtual;
-
- procedure CaptureStart;
- procedure CaptureStop;
- end;
-
-
- TSmallIntArray = array [0..(MaxInt div SizeOf(SmallInt))-1] of SmallInt;
- PSmallIntArray = ^TSmallIntArray;
-
- function AudioInputProcessor(): TAudioInputProcessor;
-
-implementation
-
-uses
- ULog,
- UMain;
-
-var
- singleton_AudioInputProcessor : TAudioInputProcessor = nil;
-
-
-{ Global }
-
-function AudioInputProcessor(): TAudioInputProcessor;
-begin
- if singleton_AudioInputProcessor = nil then
- singleton_AudioInputProcessor := TAudioInputProcessor.create();
-
- result := singleton_AudioInputProcessor;
-end;
-
-
-{ TAudioInputDevice }
-
-destructor TAudioInputDevice.Destroy;
-begin
- Stop();
- Source := nil;
- CaptureChannel := nil;
- FreeAndNil(AudioFormat);
- inherited Destroy;
-end;
-
-procedure TAudioInputDevice.LinkCaptureBuffer(ChannelIndex: integer; Sound: TCaptureBuffer);
-var
- DeviceCfg: PInputDeviceConfig;
- OldSound: TCaptureBuffer;
-begin
- // check bounds
- if ((ChannelIndex < 0) or (ChannelIndex > High(CaptureChannel))) then
- Exit;
-
- // reset previously assigned (old) capture-buffer
- OldSound := CaptureChannel[ChannelIndex];
- if (OldSound <> nil) then
- begin
- // close voice stream
- FreeAndNil(OldSound.VoiceStream);
- // free old audio-format info
- FreeAndNil(OldSound.AudioFormat);
- end;
-
- // set audio-format of new capture-buffer
- if (Sound <> nil) then
- begin
- // copy the input-device audio-format ...
- Sound.AudioFormat := AudioFormat.Copy;
- // and adjust it because capture buffers are always mono
- Sound.AudioFormat.Channels := 1;
- DeviceCfg := @Ini.InputDeviceConfig[CfgIndex];
-
- if (Ini.VoicePassthrough = 1) then
- begin
- // TODO: map odd players to the left and even players to the right speaker
- Sound.VoiceStream := AudioPlayback.CreateVoiceStream(CHANNELMAP_FRONT, AudioFormat);
- end;
- end;
-
- // replace old with new buffer (Note: Sound might be nil)
- CaptureChannel[ChannelIndex] := Sound;
-end;
-
-{ TSound }
-
-constructor TCaptureBuffer.Create;
-begin
- inherited;
- LogBuffer := TMemoryStream.Create;
- AnalysisBufferLock := SDL_CreateMutex();
- AnalysisBufferSize := Length(AnalysisBuffer);
-end;
-
-destructor TCaptureBuffer.Destroy;
-begin
- FreeAndNil(LogBuffer);
- FreeAndNil(VoiceStream);
- FreeAndNil(AudioFormat);
- SDL_DestroyMutex(AnalysisBufferLock);
- inherited;
-end;
-
-procedure TCaptureBuffer.LockAnalysisBuffer();
-begin
- SDL_mutexP(AnalysisBufferLock);
-end;
-
-procedure TCaptureBuffer.UnlockAnalysisBuffer();
-begin
- SDL_mutexV(AnalysisBufferLock);
-end;
-
-procedure TCaptureBuffer.Clear;
-begin
- if assigned(LogBuffer) then
- LogBuffer.Clear;
- LockAnalysisBuffer();
- FillChar(AnalysisBuffer[0], Length(AnalysisBuffer) * SizeOf(SmallInt), 0);
- UnlockAnalysisBuffer();
-end;
-
-procedure TCaptureBuffer.ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
-var
- BufferOffset: integer;
- SampleCount: integer;
- i: integer;
-begin
- // apply software boost
- //BoostBuffer(Buffer, Size);
-
- // voice passthrough (send data to playback-device)
- if (assigned(VoiceStream)) then
- VoiceStream.WriteData(Buffer, BufferSize);
-
- // we assume that samples are in S16Int format
- // TODO: support float too
- if (AudioFormat.Format <> asfS16) then
- Exit;
-
- // process BufferArray
- BufferOffset := 0;
-
- SampleCount := BufferSize div SizeOf(SmallInt);
-
- // check if we have more new samples than we can store
- if (SampleCount > Length(AnalysisBuffer)) then
- begin
- // discard the oldest of the new samples
- BufferOffset := (SampleCount - Length(AnalysisBuffer)) * SizeOf(SmallInt);
- SampleCount := Length(AnalysisBuffer);
- end;
-
-
- LockAnalysisBuffer();
- try
-
- // move old samples to the beginning of the array (if necessary)
- for i := 0 to High(AnalysisBuffer)-SampleCount do
- AnalysisBuffer[i] := AnalysisBuffer[i+SampleCount];
-
- // copy new samples to analysis buffer
- Move(Buffer[BufferOffset], AnalysisBuffer[Length(AnalysisBuffer)-SampleCount],
- SampleCount * SizeOf(SmallInt));
-
- finally
- UnlockAnalysisBuffer();
- end;
-
-
- // save capture-data to BufferLong if enabled
- if (Ini.SavePlayback = 1) then
- begin
- // this is just for debugging (approx 15MB per player for a 3min song!!!)
- // For an in-game replay-mode we need to compress data so we do not
- // waste that much memory. Maybe ogg-vorbis with voice-preset in fast-mode?
- // Or we could use a faster but not that efficient lossless compression.
- LogBuffer.WriteBuffer(Buffer, BufferSize);
- end;
-end;
-
-procedure TCaptureBuffer.AnalyzeBuffer;
-var
- Volume: single;
- MaxVolume: single;
- SampleIndex: integer;
- Threshold: single;
-begin
- ToneValid := false;
- ToneAbs := -1;
- Tone := -1;
-
- LockAnalysisBuffer();
- try
-
- // find maximum volume of first 1024 samples
- MaxVolume := 0;
- for SampleIndex := 0 to 1023 do
- begin
- Volume := Abs(AnalysisBuffer[SampleIndex]) / -Low(Smallint);
- if Volume > MaxVolume then
- MaxVolume := Volume;
- end;
-
- Threshold := IThresholdVals[Ini.ThresholdIndex];
-
- // check if signal has an acceptable volume (ignore background-noise)
- if MaxVolume >= Threshold then
- begin
- // analyse the current voice pitch
- AnalyzeByAutocorrelation;
- ToneValid := true;
- end;
-
- finally
- UnlockAnalysisBuffer();
- end;
-end;
-
-procedure TCaptureBuffer.AnalyzeByAutocorrelation;
-var
- ToneIndex: integer;
- CurFreq: real;
- CurWeight: real;
- MaxWeight: real;
- MaxTone: integer;
-const
- HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave)
-begin
- // prepare to analyze
- MaxWeight := -1;
- MaxTone := 0; // this is not needed, but it satifies the compiler
-
- // analyze halftones
- // Note: at the lowest tone (~65Hz) and a buffer-size of 4096
- // at 44.1 (or 48kHz) only 6 (or 5) samples are compared, this might be
- // too few samples -> use a bigger buffer-size
- for ToneIndex := 0 to NumHalftones-1 do
- begin
- CurFreq := BaseToneFreq * Power(HalftoneBase, ToneIndex);
- CurWeight := AnalyzeAutocorrelationFreq(CurFreq);
-
- // TODO: prefer higher frequencies (use >= or use downto)
- if (CurWeight > MaxWeight) then
- begin
- // this frequency has a higher weight
- MaxWeight := CurWeight;
- MaxTone := ToneIndex;
- end;
- end;
-
- ToneAbs := MaxTone;
- Tone := MaxTone mod 12;
-end;
-
-// result medium difference
-function TCaptureBuffer.AnalyzeAutocorrelationFreq(Freq: real): real;
-var
- Dist: real; // distance (0=equal .. 1=totally different) between correlated samples
- AccumDist: real; // accumulated distances
- SampleIndex: integer; // index of sample to analyze
- CorrelatingSampleIndex: integer; // index of sample one period ahead
- SamplesPerPeriod: integer; // samples in one period
-begin
- SampleIndex := 0;
- SamplesPerPeriod := Round(AudioFormat.SampleRate/Freq);
- CorrelatingSampleIndex := SampleIndex + SamplesPerPeriod;
-
- AccumDist := 0;
-
- // compare correlating samples
- while (CorrelatingSampleIndex < AnalysisBufferSize) do
- begin
- // calc distance (correlation: 1-dist) to corresponding sample in next period
- Dist := Abs(AnalysisBuffer[SampleIndex] - AnalysisBuffer[CorrelatingSampleIndex]) /
- High(Word);
- AccumDist := AccumDist + Dist;
- Inc(SampleIndex);
- Inc(CorrelatingSampleIndex);
- end;
-
- // return "inverse" average distance (=correlation)
- Result := 1 - AccumDist / AnalysisBufferSize;
-end;
-
-function TCaptureBuffer.MaxSampleVolume: Single;
-var
- lSampleIndex: Integer;
- lMaxVol : Longint;
-begin;
- LockAnalysisBuffer();
- try
- lMaxVol := 0;
- for lSampleIndex := 0 to High(AnalysisBuffer) do
- begin
- if Abs(AnalysisBuffer[lSampleIndex]) > lMaxVol then
- lMaxVol := Abs(AnalysisBuffer[lSampleIndex]);
- end;
- finally
- UnlockAnalysisBuffer();
- end;
-
- result := lMaxVol / -Low(Smallint);
-end;
-
-const
- ToneStrings: array[0..11] of string = (
- 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'
- );
-
-function TCaptureBuffer.GetToneString: string;
-begin
- if (ToneValid) then
- Result := ToneStrings[Tone] + IntToStr(ToneAbs div 12 + 2)
- else
- Result := '-';
-end;
-
-procedure TCaptureBuffer.BoostBuffer(Buffer: PChar; Size: Cardinal);
-var
- i: integer;
- Value: Longint;
- SampleCount: integer;
- SampleBuffer: PSmallIntArray; // buffer handled as array of samples
- Boost: byte;
-begin
- // TODO: set boost per device
- {
- case Ini.MicBoost of
- 0: Boost := 1;
- 1: Boost := 2;
- 2: Boost := 4;
- 3: Boost := 8;
- else Boost := 1;
- end;
- }
- Boost := 1;
-
- // at the moment we will boost SInt16 data only
- if (AudioFormat.Format = asfS16) then
- begin
- // interpret buffer as buffer of bytes
- SampleBuffer := PSmallIntArray(Buffer);
- SampleCount := Size div AudioFormat.FrameSize;
-
- // boost buffer
- for i := 0 to SampleCount-1 do
- begin
- Value := SampleBuffer^[i] * Boost;
-
- // TODO : JB - This will clip the audio... cant we reduce the "Boost" if the data clips ??
- if Value > High(Smallint) then
- Value := High(Smallint);
-
- if Value < Low(Smallint) then
- Value := Low(Smallint);
-
- SampleBuffer^[i] := Value;
- end;
- end;
-end;
-
-
-{ TAudioInputProcessor }
-
-constructor TAudioInputProcessor.Create;
-var
- i: integer;
-begin
- inherited;
- SetLength(Sound, 6 {max players});//Ini.Players+1);
- for i := 0 to High(Sound) do
- Sound[i] := TCaptureBuffer.Create;
-end;
-
-destructor TAudioInputProcessor.Destroy;
-var
- i: integer;
-begin
- for i := 0 to High(Sound) do
- Sound[i].Free;
- SetLength(Sound, 0);
- inherited;
-end;
-
-// updates InputDeviceConfig with current input-device information
-// See: TIni.LoadInputDeviceCfg()
-procedure TAudioInputProcessor.UpdateInputDeviceConfig;
-var
- deviceIndex: integer;
- newDevice: boolean;
- deviceIniIndex: integer;
- deviceCfg: PInputDeviceConfig;
- device: TAudioInputDevice;
- channelCount: integer;
- channelIndex: integer;
- i: integer;
-begin
- // Input devices - append detected soundcards
- for deviceIndex := 0 to High(DeviceList) do
- begin
- newDevice := true;
- //Search for Card in List
- for deviceIniIndex := 0 to High(Ini.InputDeviceConfig) do
- begin
- deviceCfg := @Ini.InputDeviceConfig[deviceIniIndex];
- device := DeviceList[deviceIndex];
-
- if (deviceCfg.Name = Trim(device.Name)) then
- begin
- newDevice := false;
-
- // store highest channel index as an offset for the new channels
- channelIndex := High(deviceCfg.ChannelToPlayerMap);
- // add missing channels or remove non-existing ones
- SetLength(deviceCfg.ChannelToPlayerMap, device.AudioFormat.Channels);
- // initialize added channels to 0
- for i := channelIndex+1 to High(deviceCfg.ChannelToPlayerMap) do
- begin
- deviceCfg.ChannelToPlayerMap[i] := 0;
- end;
-
- // associate ini-index with device
- device.CfgIndex := deviceIniIndex;
- break;
- end;
- end;
-
- //If not in List -> Add
- if newDevice then
- begin
- // resize list
- SetLength(Ini.InputDeviceConfig, Length(Ini.InputDeviceConfig)+1);
- deviceCfg := @Ini.InputDeviceConfig[High(Ini.InputDeviceConfig)];
- device := DeviceList[deviceIndex];
-
- // associate ini-index with device
- device.CfgIndex := High(Ini.InputDeviceConfig);
-
- deviceCfg.Name := Trim(device.Name);
- deviceCfg.Input := 0;
-
- channelCount := device.AudioFormat.Channels;
- SetLength(deviceCfg.ChannelToPlayerMap, channelCount);
-
- for channelIndex := 0 to channelCount-1 do
- begin
- // set default at first start of USDX (1st device, 1st channel -> player1)
- if ((channelIndex = 0) and (device.CfgIndex = 0)) then
- deviceCfg.ChannelToPlayerMap[0] := 1
- else
- deviceCfg.ChannelToPlayerMap[channelIndex] := 0;
- end;
- end;
- end;
-end;
-
-{*
- * Handles captured microphone input data.
- * Params:
- * Buffer - buffer of signed 16bit interleaved stereo PCM-samples.
- * Interleaved means that a right-channel sample follows a left-
- * channel sample and vice versa (0:left[0],1:right[0],2:left[1],...).
- * Length - number of bytes in Buffer
- * Input - Soundcard-Input used for capture
- *}
-procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: PChar; Size: Cardinal; InputDevice: TAudioInputDevice);
-var
- MultiChannelBuffer: PChar; // buffer handled as array of bytes (offset relative to channel)
- SingleChannelBuffer: PChar; // temporary buffer for new samples per channel
- SingleChannelBufferSize: integer;
- ChannelIndex: integer;
- CaptureChannel: TCaptureBuffer;
- AudioFormat: TAudioFormatInfo;
- SampleSize: integer;
- SampleCount: integer;
- SamplesPerChannel: integer;
- i: integer;
-begin
- AudioFormat := InputDevice.AudioFormat;
- SampleSize := AudioSampleSize[AudioFormat.Format];
- SampleCount := Size div SampleSize;
- SamplesPerChannel := Size div AudioFormat.FrameSize;
-
- SingleChannelBufferSize := SamplesPerChannel * SampleSize;
- GetMem(SingleChannelBuffer, SingleChannelBufferSize);
-
- // process channels
- for ChannelIndex := 0 to High(InputDevice.CaptureChannel) do
- begin
- CaptureChannel := InputDevice.CaptureChannel[ChannelIndex];
- // check if a capture buffer was assigned, otherwise there is nothing to do
- if (CaptureChannel <> nil) then
- begin
- // set offset according to channel index
- MultiChannelBuffer := @Buffer[ChannelIndex * SampleSize];
- // seperate channel-data from interleaved multi-channel (e.g. stereo) data
- for i := 0 to SamplesPerChannel-1 do
- begin
- Move(MultiChannelBuffer[i*AudioFormat.FrameSize],
- SingleChannelBuffer[i*SampleSize],
- SampleSize);
- end;
- CaptureChannel.ProcessNewBuffer(SingleChannelBuffer, SingleChannelBufferSize);
- end;
- end;
-
- FreeMem(SingleChannelBuffer);
-end;
-
-
-{ TAudioInputBase }
-
-function TAudioInputBase.FinalizeRecord: boolean;
-var
- i: integer;
-begin
- for i := 0 to High(AudioInputProcessor.DeviceList) do
- AudioInputProcessor.DeviceList[i].Free();
- AudioInputProcessor.DeviceList := nil;
- Result := true;
-end;
-
-{*
- * Start capturing on all used input-device.
- *}
-procedure TAudioInputBase.CaptureStart;
-var
- S: integer;
- DeviceIndex: integer;
- ChannelIndex: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
- DeviceUsed: boolean;
- Player: integer;
-begin
- if (Started) then
- CaptureStop();
-
- // reset buffers
- for S := 0 to High(AudioInputProcessor.Sound) do
- AudioInputProcessor.Sound[S].Clear;
-
- // start capturing on each used device
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- Device := AudioInputProcessor.DeviceList[DeviceIndex];
- if not assigned(Device) then
- continue;
- DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
-
- DeviceUsed := false;
-
- // check if device is used
- for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
- begin
- Player := DeviceCfg.ChannelToPlayerMap[ChannelIndex]-1;
- if (Player < 0) or (Player >= PlayersPlay) then
- begin
- Device.LinkCaptureBuffer(ChannelIndex, nil);
- end
- else
- begin
- Device.LinkCaptureBuffer(ChannelIndex, AudioInputProcessor.Sound[Player]);
- DeviceUsed := true;
- end;
- end;
-
- // start device if used
- if (DeviceUsed) then
- begin
- //Log.BenchmarkStart(2);
- Device.Start();
- //Log.BenchmarkEnd(2);
- //Log.LogBenchmark('Device.Start', 2) ;
- end;
- end;
-
- Started := true;
-end;
-
-{*
- * Stop input-capturing on all soundcards.
- *}
-procedure TAudioInputBase.CaptureStop;
-var
- DeviceIndex: integer;
- ChannelIndex: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
-begin
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- Device := AudioInputProcessor.DeviceList[DeviceIndex];
- if not assigned(Device) then
- continue;
-
- Device.Stop();
-
- // disconnect capture buffers
- DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
- for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
- Device.LinkCaptureBuffer(ChannelIndex, nil);
- end;
-
- Started := false;
-end;
-
-function TAudioInputBase.UnifyDeviceName(const name: string; deviceIndex: integer): string;
-var
- count: integer; // count of devices with this name
-
- function IsDuplicate(const name: string): boolean;
- var
- i: integer;
- begin
- Result := False;
- // search devices with same description
- For i := 0 to deviceIndex-1 do
- begin
- if (AudioInputProcessor.DeviceList[i].Name = name) then
- begin
- Result := True;
- Break;
- end;
- end;
- end;
-begin
- count := 1;
- result := name;
-
- // if there is another device with the same ID, search for an available name
- while (IsDuplicate(result)) do
- begin
- Inc(count);
- // set description
- result := name + ' ('+IntToStr(count)+')';
- end;
-end;
-
-end.
-
-
-
diff --git a/Game/Code/Classes/URingBuffer.pas b/Game/Code/Classes/URingBuffer.pas
deleted file mode 100644
index ce51e209..00000000
--- a/Game/Code/Classes/URingBuffer.pas
+++ /dev/null
@@ -1,128 +0,0 @@
-unit URingBuffer;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SysUtils;
-
-type
- TRingBuffer = class
- private
- RingBuffer: PChar;
- BufferCount: integer;
- BufferSize: integer;
- WritePos: integer;
- ReadPos: integer;
- public
- constructor Create(Size: integer);
- destructor Destroy; override;
- function Read(Buffer: PChar; Count: integer): integer;
- function Write(Buffer: PChar; Count: integer): integer;
- procedure Flush();
- end;
-
-implementation
-
-uses
- Math;
-
-constructor TRingBuffer.Create(Size: integer);
-begin
- BufferSize := Size;
-
- GetMem(RingBuffer, Size);
- if (RingBuffer = nil) then
- raise Exception.Create('No memory');
-end;
-
-destructor TRingBuffer.Destroy;
-begin
- FreeMem(RingBuffer);
-end;
-
-function TRingBuffer.Read(Buffer: PChar; Count: integer): integer;
-var
- PartCount: integer;
-begin
- // adjust output count
- if (Count > BufferCount) then
- begin
- //DebugWriteln('Read too much: ' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
- Count := BufferCount;
- end;
-
- // check if there is something to do
- if (Count <= 0) then
- begin
- Result := Count;
- Exit;
- end;
-
- // copy data to output buffer
-
- // first step: copy from the area between the read-position and the end of the buffer
- PartCount := Min(Count, BufferSize - ReadPos);
- Move(RingBuffer[ReadPos], Buffer[0], PartCount);
-
- // second step: if we need more data, copy from the beginning of the buffer
- if (PartCount < Count) then
- Move(RingBuffer[0], Buffer[0], Count-PartCount);
-
- // mark the copied part of the buffer as free
- BufferCount := BufferCount - Count;
- ReadPos := (ReadPos + Count) mod BufferSize;
-
- Result := Count;
-end;
-
-function TRingBuffer.Write(Buffer: PChar; Count: integer): integer;
-var
- PartCount: integer;
-begin
- // check for a reasonable request
- if (Count <= 0) then
- begin
- Result := Count;
- Exit;
- end;
-
- // skip input data if the input buffer is bigger than the ring-buffer
- if (Count > BufferSize) then
- begin
- //DebugWriteln('Write skip data:' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
- Buffer := @Buffer[Count - BufferSize];
- Count := BufferSize;
- end;
-
- // first step: copy to the area between the write-position and the end of the buffer
- PartCount := Min(Count, BufferSize - WritePos);
- Move(Buffer[0], RingBuffer[WritePos], PartCount);
-
- // second step: copy data to front of buffer
- if (PartCount < Count) then
- Move(Buffer[PartCount], RingBuffer[0], Count-PartCount);
-
- // update info
- BufferCount := Min(BufferCount + Count, BufferSize);
- WritePos := (WritePos + Count) mod BufferSize;
- // if the buffer is full, we have to reposition the read-position
- if (BufferCount = BufferSize) then
- ReadPos := WritePos;
-
- Result := Count;
-end;
-
-procedure TRingBuffer.Flush();
-begin
- ReadPos := 0;
- WritePos := 0;
- BufferCount := 0;
-end;
-
-end.
\ No newline at end of file
diff --git a/Game/Code/Classes/UServices.pas b/Game/Code/Classes/UServices.pas
deleted file mode 100644
index 6325444c..00000000
--- a/Game/Code/Classes/UServices.pas
+++ /dev/null
@@ -1,358 +0,0 @@
-unit UServices;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses uPluginDefs,
- SysUtils;
-{*********************
- TServiceManager
- Class for saving, managing and calling of Services.
- Saves all Services and their Procs
-*********************}
-
-type
- TServiceName = String[60];
- PServiceInfo = ^TServiceInfo;
- TServiceInfo = record
- Self: THandle; //Handle of this Service
- Hash: Integer; //4 Bit Hash of the Services Name
- Name: TServiceName; //Name of this Service
-
- Owner: Integer; //If < 0 [-(DLLMan Pluginindex + 1)]; 0 - undefined, On Error Full shutdown, If < 0 [ModuleIndex - 1]
-
- Next: PServiceInfo; //Pointer to the Next Service in teh list
-
- //Here is s/t tricky
- //To avoid writing of Wrapping Functions to offer a Service from a Class
- //We save a Normal Proc or a Method of a Class
- Case isClass: boolean of
- False: (Proc: TUS_Service); //Proc that will be called on Event
- True: (ProcOfClass: TUS_Service_of_Object);
- end;
-
- TServiceManager = class
- private
- //Managing Service List
- FirstService: PServiceInfo;
- LastService: PServiceInfo;
-
- //Some Speed improvement by caching the last 4 called Services
- //Most of the time a Service is called multiple times
- ServiceCache: Array[0..3] of PServiceInfo;
- NextCacheItem: Byte;
-
- //Next Service added gets this Handle:
- NextHandle: THandle;
- public
- Constructor Create;
-
- Function AddService(const ServiceName: PChar; const Proc: TUS_Service = nil; const ProcofClass: TUS_Service_of_Object = nil): THandle;
- Function DelService(const hService: THandle): integer;
-
- Function CallService(const ServiceName: PChar; const wParam: TwParam; lParam: TlParam): integer;
-
- Function NametoHash(const ServiceName: TServiceName): Integer;
- Function ServiceExists(const ServiceName: PChar): Integer;
- end;
-
-var
- ServiceManager: TServiceManager;
-
-implementation
-uses
- ULog,
- UCore;
-
-//------------
-// Create - Creates Class and Set Standard Values
-//------------
-Constructor TServiceManager.Create;
-begin
- inherited;
-
- FirstService := nil;
- LastService := nil;
-
- ServiceCache[0] := nil;
- ServiceCache[1] := nil;
- ServiceCache[2] := nil;
- ServiceCache[3] := nil;
-
- NextCacheItem := 0;
-
- NextHandle := 1;
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Succesful created!');
- {$ENDIF}
-end;
-
-//------------
-// Function Creates a new Service and Returns the Services Handle,
-// 0 on Failure. (Name already exists)
-//------------
-Function TServiceManager.AddService(const ServiceName: PChar; const Proc: TUS_Service; const ProcofClass: TUS_Service_of_Object): THandle;
-var
- Cur: PServiceInfo;
-begin
- Result := 0;
-
- If (@Proc <> nil) or (@ProcOfClass <> nil) then
- begin
- If (ServiceExists(ServiceName) = 0) then
- begin //There is a Proc and the Service does not already exist
- //Ok Add it!
-
- //Get Memory
- GetMem(Cur, SizeOf(TServiceInfo));
-
- //Fill it with Data
- Cur.Next := nil;
-
- If (@Proc = nil) then
- begin //Use the ProcofClass Method
- Cur.isClass := True;
- Cur.ProcOfClass := ProcofClass;
- end
- else //Use the normal Proc
- begin
- Cur.isClass := False;
- Cur.Proc := Proc;
- end;
-
- Cur.Self := NextHandle;
- //Zero Name
- Cur.Name := #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0;
- Cur.Name := String(ServiceName);
- Cur.Hash := NametoHash(Cur.Name);
-
- //Add Owner to Service
- Cur.Owner := Core.CurExecuted;
-
- //Add Service to the List
- If (FirstService = nil) then
- FirstService := Cur;
-
- If (LastService <> nil) then
- LastService.Next := Cur;
-
- LastService := Cur;
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Service added: ''' + ServiceName + ''', Handle: ' + InttoStr(Cur.Self));
- {$ENDIF}
-
- //Inc Next Handle
- Inc(NextHandle);
- end
- {$IFDEF DEBUG}
- else debugWriteln('ServiceManager: Try to readd Service: ' + ServiceName);
- {$ENDIF}
- end;
-end;
-
-//------------
-// Function Destroys a Service, 0 on success, not 0 on Failure
-//------------
-Function TServiceManager.DelService(const hService: THandle): integer;
-var
- Last, Cur: PServiceInfo;
- I: Integer;
-begin
- Result := -1;
-
- Last := nil;
- Cur := FirstService;
-
- //Search for Service to Delete
- While (Cur <> nil) do
- begin
- If (Cur.Self = hService) then
- begin //Found Service => Delete it
-
- //Delete from List
- If (Last = nil) then //Found first Service
- FirstService := Cur.Next
- Else //Service behind the first
- Last.Next := Cur.Next;
-
- //IF this is the LastService, correct LastService
- If (Cur = LastService) then
- LastService := Last;
-
- //Search for Service in Cache and delete it if found
- For I := 0 to High(ServiceCache) do
- If (ServiceCache[I] = Cur) then
- begin
- ServiceCache[I] := nil;
- end;
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Removed Service succesful: ' + Cur.Name);
- {$ENDIF}
-
- //Free Memory
- Freemem(Cur, SizeOf(TServiceInfo));
-
- //Break the Loop
- Break;
- end;
-
- //Go to Next Service
- Last := Cur;
- Cur := Cur.Next;
- end;
-end;
-
-//------------
-// Function Calls a Services Proc
-// Returns Services Return Value or SERVICE_NOT_FOUND on Failure
-//------------
-Function TServiceManager.CallService(const ServiceName: PChar; const wParam: TwParam; lParam: TlParam): integer;
-var
- SExists: Integer;
- Service: PServiceInfo;
- CurExecutedBackup: Integer; //backup of Core.CurExecuted Attribute
-begin
- Result := SERVICE_NOT_FOUND;
- SExists := ServiceExists(ServiceName);
- If (SExists <> 0) then
- begin
- //Backup CurExecuted
- CurExecutedBackup := Core.CurExecuted;
-
- Service := Pointer(SExists);
-
- If (Service.isClass) then
- //Use Proc of Class
- Result := Service.ProcOfClass(wParam, lParam)
- Else
- //Use normal Proc
- Result := Service.Proc(wParam, lParam);
-
- //Restore CurExecuted
- Core.CurExecuted := CurExecutedBackup;
- end;
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Service ''' + ServiceName + ''' called. Result: ' + InttoStr(Result));
- {$ENDIF}
-end;
-
-//------------
-// Generates the Hash for the given Name
-//------------
-Function TServiceManager.NametoHash(const ServiceName: TServiceName): Integer;
-// FIXME: check if the non-asm version is fast enough and use it by default if so
-{$IF Defined(CPUX86_64)}
-{$IFDEF FPC}
- {$ASMMODE Intel}
-{$ENDIF}
-asm
- { CL: Counter; RAX: Result; RDX: Current Memory Address }
- Mov RCX, 14
- Mov RDX, ServiceName {Save Address of String that should be "Hashed"}
- Mov RAX, [RDX]
- @FoldLoop: ADD RDX, 4 {jump 4 Byte(32 Bit) to the next tile }
- ADD RAX, [RDX] {Add the Value of the next 4 Byte of the String to the Hash}
- LOOP @FoldLoop {Fold again if there are Chars Left}
-end;
-{$ELSEIF Defined(CPU386) or Defined(CPUI386)}
-{$IFDEF FPC}
- {$ASMMODE Intel}
-{$ENDIF}
-asm
- { CL: Counter; EAX: Result; EDX: Current Memory Address }
- Mov ECX, 14 {Init Counter, Fold 14 Times to get 4 Bytes out of 60}
- Mov EDX, ServiceName {Save Address of String that should be "Hashed"}
- Mov EAX, [EDX]
- @FoldLoop: ADD EDX, 4 {jump 4 Byte(32 Bit) to the next tile }
- ADD EAX, [EDX] {Add the Value of the next 4 Byte of the String to the Hash}
- LOOP @FoldLoop {Fold again if there are Chars Left}
-end;
-{$ELSE}
-var
- i: integer;
- ptr: ^integer;
-begin
- ptr := @ServiceName;
- Result := 0;
- for i := 1 to 14 do
- begin
- Result := Result + ptr^;
- Inc(ptr);
- end;
-end;
-{$IFEND}
-
-
-//------------
-// Function Returns Non Zero if a Service with the given Name Exists, otherwise 0
-//------------
-Function TServiceManager.ServiceExists(const ServiceName: PChar): Integer;
-var
- Name: TServiceName;
- Hash: Integer;
- Cur: PServiceInfo;
- I: Byte;
-begin
- Result := 0;
- // to-do : Write a Metbod (in ASM) to Zero and Add in one turn (faster then this dirty hack ;)
- //Zero Name:
- Name := #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0;
- //Add Service Name
- Name := String(ServiceName);
- Hash := NametoHash(Name);
-
- //First of all Look for the Service in Cache
- For I := 0 to High(ServiceCache) do
- begin
- If (ServiceCache[I] <> nil) AND (ServiceCache[I].Hash = Hash) then
- begin
- If (ServiceCache[I].Name = Name) then
- begin //Found Service in Cache
- Result := Integer(ServiceCache[I]);
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Found Service in Cache: ''' + ServiceName + '''');
- {$ENDIF}
-
- Break;
- end;
- end;
- end;
-
- If (Result = 0) then
- begin
- Cur := FirstService;
- While (Cur <> nil) do
- begin
- If (Cur.Hash = Hash) then
- begin
- If (Cur.Name = Name) then
- begin //Found the Service
- Result := Integer(Cur);
-
- {$IFDEF DEBUG}
- debugWriteln('ServiceManager: Found Service in List: ''' + ServiceName + '''');
- {$ENDIF}
-
- //Add to Cache
- ServiceCache[NextCacheItem] := Cur;
- NextCacheItem := (NextCacheItem + 1) AND 3;
- Break;
- end;
- end;
-
- Cur := Cur.Next;
- end;
- end;
-end;
-
-end.
diff --git a/Game/Code/Classes/USingNotes.pas b/Game/Code/Classes/USingNotes.pas
deleted file mode 100644
index 3b268d10..00000000
--- a/Game/Code/Classes/USingNotes.pas
+++ /dev/null
@@ -1,13 +0,0 @@
-unit USingNotes;
-
-interface
-
-{$I switches.inc}
-
-{ Dummy Unit atm
- For further expantation
- Placeholder for Class that will handle the Notes Drawing}
-
-implementation
-
-end.
diff --git a/Game/Code/Classes/USingScores.pas b/Game/Code/Classes/USingScores.pas
deleted file mode 100644
index 77d40b84..00000000
--- a/Game/Code/Classes/USingScores.pas
+++ /dev/null
@@ -1,973 +0,0 @@
-unit USingScores;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses UThemes,
- gl,
- UTexture;
-
-//////////////////////////////////////////////////////////////
-// ATTENTION: //
-// Enabled Flag does not Work atm. This should cause Popups //
-// Not to Move and Scores to stay until Renenabling. //
-// To use e.g. in Pause Mode //
-// Also InVisible Flag causes Attributes not to change. //
-// This should be fixed after next Draw when Visible = True,//
-// but not testet yet //
-//////////////////////////////////////////////////////////////
-
-//Some constants containing options that could change by time
-const
- MaxPlayers = 6; //Maximum of Players that could be added
- MaxPositions = 6; //Maximum of Score Positions that could be added
-
-type
- //-----------
- // TScorePlayer - Record Containing Information about a Players Score
- //-----------
- TScorePlayer = record
- Position: Byte; //Index of the Position where the Player should be Drawn
- Enabled: Boolean; //Is the Score Display Enabled
- Visible: Boolean; //Is the Score Display Visible
- Score: Word; //Current Score of the Player
- ScoreDisplayed: Word; //Score cur. Displayed(for counting up)
- ScoreBG: TTexture;//Texture of the Players Scores BG
- Color: TRGB; //Teh Players Color
- RBPos: Real; //Cur. Percentille of the Rating Bar
- RBTarget: Real; //Target Position of Rating Bar
- RBVisible:Boolean; //Is Rating bar Drawn
- end;
- aScorePlayer = array[0..MaxPlayers-1] of TScorePlayer;
-
- //-----------
- // TScorePosition - Record Containing Information about a Score Position, that can be used
- //-----------
- PScorePosition = ^TScorePosition;
- TScorePosition = record
- //The Position is Used for Which Playercount
- PlayerCount: Byte;
- // 1 - One Player per Screen
- // 2 - 2 Players per Screen
- // 4 - 3 Players per Screen
- // 6 would be 2 and 3 Players per Screen
-
- BGX: Real; //X Position of the Score BG
- BGY: Real; //Y Position of the Score BG
- BGW: Real; //Width of the Score BG
- BGH: Real; //Height of the Score BG
-
- RBX: Real; //X Position of the Rating Bar
- RBY: Real; //Y Position of the Rating Bar
- RBW: Real; //Width of the Rating Bar
- RBH: Real; //Height of the Rating Bar
-
- TextX: Real; //X Position of the Score Text
- TextY: Real; //Y Position of the Score Text
- TextFont: Byte; //Font of the Score Text
- TextSize: Byte; //Size of the Score Text
-
- PUW: Real; //Width of the LineBonus Popup
- PUH: Real; //Height of the LineBonus Popup
- PUFont: Byte; //Font for the PopUps
- PUFontSize: Byte; //FontSize for the PopUps
- PUStartX: Real; //X Start Position of the LineBonus Popup
- PUStartY: Real; //Y Start Position of the LineBonus Popup
- PUTargetX: Real; //X Target Position of the LineBonus Popup
- PUTargetY: Real; //Y Target Position of the LineBonus Popup
- end;
- aScorePosition = array[0..MaxPositions-1] of TScorePosition;
-
- //-----------
- // TScorePopUp - Record Containing Information about a LineBonus Popup
- // List, Next Item is Saved in Next attribute
- //-----------
- PScorePopUp = ^TScorePopUp;
- TScorePopUp = record
- Player: Byte; //Index of the PopUps Player
- TimeStamp: Cardinal; //Timestamp of Popups Spawn
- Rating: Byte; //0 to 8, Type of Rating (Cool, bad, etc.)
- ScoreGiven:Word; //Score that has already been given to the Player
- ScoreDiff: Word; //Difference Between Cur Score at Spawn and Old Score
- Next: PScorePopUp; //Next Item in List
- end;
- aScorePopUp = array of TScorePopUp;
-
- //-----------
- // TSingScores - Class containing Scores Positions and Drawing Scores, Rating Bar + Popups
- //-----------
- TSingScores = class
- private
- Positions: aScorePosition;
- aPlayers: aScorePlayer;
- oPositionCount: Byte;
- oPlayerCount: Byte;
-
- //Saves the First and Last Popup of the List
- FirstPopUp: PScorePopUp;
- LastPopUp: PScorePopUp;
-
- //Procedure Draws a Popup by Pointer
- Procedure DrawPopUp(const PopUp: PScorePopUp);
-
- //Procedure Draws a Score by Playerindex
- Procedure DrawScore(const Index: Integer);
-
- //Procedure Draws the RatingBar by Playerindex
- Procedure DrawRatingBar(const Index: Integer);
-
- //Procedure Removes a PopUp w/o destroying the List
- Procedure KillPopUp(const last, cur: PScorePopUp);
- public
- Settings: record //Record containing some Displaying Options
- Phase1Time: Real; //time for Phase 1 to complete (in msecs)
- //The Plop Up of the PopUp
- Phase2Time: Real; //time for Phase 2 to complete (in msecs)
- //The Moving (mainly Upwards) of the Popup
- Phase3Time: Real; //time for Phase 3 to complete (in msecs)
- //The Fade out and Score adding
-
- PopUpTex: Array [0..8] of TTexture; //Textures for every Popup Rating
-
- RatingBar_BG_Tex: TTexture; //Rating Bar Texs
- RatingBar_FG_Tex: TTexture;
- RatingBar_Bar_Tex: TTexture;
-
- end;
-
- Visible: Boolean; //Visibility of all Scores
- Enabled: Boolean; //Scores are changed, PopUps are Moved etc.
- RBVisible: Boolean; //Visibility of all Rating Bars
-
- //Propertys for Reading Position and Playercount
- Property PositionCount: Byte read oPositionCount;
- Property PlayerCount: Byte read oPlayerCount;
- Property Players: aScorePlayer read aPlayers;
-
- //Constructor just sets some standard Settings
- Constructor Create;
-
- //Procedure Adds a Position to Array and Increases Position Count
- Procedure AddPosition(const pPosition: PScorePosition);
-
- //Procedure Adds a Player to Array and Increases Player Count
- Procedure AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word = 0; const Enabled: Boolean = True; const Visible: Boolean = True);
-
- //Change a Players Visibility, Enable
- Procedure ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
- Procedure ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
-
- //Procedure Deletes all Player Information
- Procedure ClearPlayers;
-
- //Procedure Deletes Positions and Playerinformation
- Procedure Clear;
-
- //Procedure Loads some Settings and the Positions from Theme
- Procedure LoadfromTheme;
-
- //Procedure has to be called after Positions and Players have been added, before first call of Draw
- //It gives every Player a Score Position
- Procedure Init;
-
- //Spawns a new Line Bonus PopUp for the Player
- Procedure SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
-
- //Removes all PopUps from Mem
- Procedure KillAllPopUps;
-
- //Procedure Draws Scores and Linebonus PopUps
- Procedure Draw;
- end;
-
-
-implementation
-
-uses SDL,
- SysUtils,
- ULog,
- UGraphic,
- TextGL;
-
-//-----------
-//Constructor just sets some standard Settings
-//-----------
-Constructor TSingScores.Create;
-begin
- inherited;
-
- //Clear PopupList Pointers
- FirstPopUp := nil;
- LastPopUp := nil;
-
- //Clear Variables
- Visible := True;
- Enabled := True;
- RBVisible := True;
-
- //Clear Position Index
- oPositionCount := 0;
- oPlayerCount := 0;
-
- Settings.Phase1Time := 350; // plop it up . -> [ ]
- Settings.Phase2Time := 550; // shift it up ^[ ]^
- Settings.Phase3Time := 200; // increase score [s++]
-
- Settings.PopUpTex[0].TexNum := 0;
- Settings.PopUpTex[1].TexNum := 0;
- Settings.PopUpTex[2].TexNum := 0;
- Settings.PopUpTex[3].TexNum := 0;
- Settings.PopUpTex[4].TexNum := 0;
- Settings.PopUpTex[5].TexNum := 0;
- Settings.PopUpTex[6].TexNum := 0;
- Settings.PopUpTex[7].TexNum := 0;
- Settings.PopUpTex[8].TexNum := 0;
-
- Settings.RatingBar_BG_Tex.TexNum := 0;
- Settings.RatingBar_FG_Tex.TexNum := 0;
- Settings.RatingBar_Bar_Tex.TexNum := 0;
-end;
-
-//-----------
-//Procedure Adds a Position to Array and Increases Position Count
-//-----------
-Procedure TSingScores.AddPosition(const pPosition: PScorePosition);
-begin
- if (PositionCount < MaxPositions) then
- begin
- Positions[PositionCount] := pPosition^;
-
- Inc(oPositionCount);
- end;
-end;
-
-//-----------
-//Procedure Adds a Player to Array and Increases Player Count
-//-----------
-Procedure TSingScores.AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word; const Enabled: Boolean; const Visible: Boolean);
-begin
- if (PlayerCount < MaxPlayers) then
- begin
- aPlayers[PlayerCount].Position := High(byte);
- aPlayers[PlayerCount].Enabled := Enabled;
- aPlayers[PlayerCount].Visible := Visible;
- aPlayers[PlayerCount].Score := Score;
- aPlayers[PlayerCount].ScoreDisplayed := Score;
- aPlayers[PlayerCount].ScoreBG := ScoreBG;
- aPlayers[PlayerCount].Color := Color;
- aPlayers[PlayerCount].RBPos := 0.5;
- aPlayers[PlayerCount].RBTarget := 0.5;
- aPlayers[PlayerCount].RBVisible := True;
-
- Inc(oPlayerCount);
- end;
-end;
-
-//-----------
-//Change a Players Visibility
-//-----------
-Procedure TSingScores.ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
-begin
- if (Index < MaxPlayers) then
- aPlayers[Index].Visible := pVisible;
-end;
-
-//-----------
-//Change Player Enabled
-//-----------
-Procedure TSingScores.ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
-begin
- if (Index < MaxPlayers) then
- aPlayers[Index].Enabled := pEnabled;
-end;
-
-//-----------
-//Procedure Deletes all Player Information
-//-----------
-Procedure TSingScores.ClearPlayers;
-begin
- KillAllPopUps;
- oPlayerCount := 0;
-end;
-
-//-----------
-//Procedure Deletes Positions and Playerinformation
-//-----------
-Procedure TSingScores.Clear;
-begin
- KillAllPopUps;
- oPlayerCount := 0;
- oPositionCount := 0;
-end;
-
-//-----------
-//Procedure Loads some Settings and the Positions from Theme
-//-----------
-Procedure TSingScores.LoadfromTheme;
-var I: Integer;
- Procedure AddbyStatics(const PC: Byte; const ScoreStatic, SingBarStatic: TThemeStatic; ScoreText: TThemeText);
- var nPosition: TScorePosition;
- begin
- nPosition.PlayerCount := PC; //Only for one Player Playing
-
- nPosition.BGX := ScoreStatic.X;
- nPosition.BGY := ScoreStatic.Y;
- nPosition.BGW := ScoreStatic.W;
- nPosition.BGH := ScoreStatic.H;
-
- nPosition.TextX := ScoreText.X;
- nPosition.TextY := ScoreText.Y;
- nPosition.TextFont := ScoreText.Font;
- nPosition.TextSize := ScoreText.Size;
-
- nPosition.RBX := SingBarStatic.X;
- nPosition.RBY := SingBarStatic.Y;
- nPosition.RBW := SingBarStatic.W;
- nPosition.RBH := SingBarStatic.H;
-
- nPosition.PUW := nPosition.BGW;
- nPosition.PUH := nPosition.BGH;
-
- nPosition.PUFont := 2;
- nPosition.PUFontSize := 6;
-
- nPosition.PUStartX := nPosition.BGX;
- nPosition.PUStartY := nPosition.TextY + 65;
-
- nPosition.PUTargetX := nPosition.BGX;
- nPosition.PUTargetY := nPosition.TextY;
-
- AddPosition(@nPosition);
- end;
-begin
- Clear;
-
- //Set Textures
- //Popup Tex
- For I := 0 to 8 do
- Settings.PopUpTex[I] := Tex_SingLineBonusBack[I];
-
- //Rating Bar Tex
- Settings.RatingBar_BG_Tex := Tex_SingBar_Back;
- Settings.RatingBar_FG_Tex := Tex_SingBar_Front;
- Settings.RatingBar_Bar_Tex := Tex_SingBar_Bar;
-
- //Load Positions from Theme
-
- // Player1:
- AddByStatics(1, Theme.Sing.StaticP1ScoreBG, Theme.Sing.StaticP1SingBar, Theme.Sing.TextP1Score);
- AddByStatics(2, Theme.Sing.StaticP1TwoPScoreBG, Theme.Sing.StaticP1TwoPSingBar, Theme.Sing.TextP1TwoPScore);
- AddByStatics(4, Theme.Sing.StaticP1ThreePScoreBG, Theme.Sing.StaticP1ThreePSingBar, Theme.Sing.TextP1ThreePScore);
-
- // Player2:
- AddByStatics(2, Theme.Sing.StaticP2RScoreBG, Theme.Sing.StaticP2RSingBar, Theme.Sing.TextP2RScore);
- AddByStatics(4, Theme.Sing.StaticP2MScoreBG, Theme.Sing.StaticP2MSingBar, Theme.Sing.TextP2MScore);
-
- // Player3:
- AddByStatics(4, Theme.Sing.StaticP3RScoreBG, Theme.Sing.StaticP3RScoreBG, Theme.Sing.TextP3RScore);
-end;
-
-//-----------
-//Spawns a new Line Bonus PopUp for the Player
-//-----------
-Procedure TSingScores.SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
-var Cur: PScorePopUp;
-begin
- if (PlayerIndex < PlayerCount) then
- begin
- //Get Memory and Add Data
- GetMem(Cur, SizeOf(TScorePopUp));
-
- Cur.Player := PlayerIndex;
- Cur.TimeStamp := SDL_GetTicks;
- Cur.Rating := Rating;
- Cur.ScoreGiven:= 0;
- If (Players[PlayerIndex].Score < Score) then
- begin
- Cur.ScoreDiff := Score - Players[PlayerIndex].Score;
- aPlayers[PlayerIndex].Score := Score;
- end
- else
- Cur.ScoreDiff := 0;
- Cur.Next := nil;
-
- //Log.LogError('TSingScores.SpawnPopUp| Player: ' + InttoStr(PlayerIndex) + ', Score: ' + InttoStr(Score) + ', ScoreDiff: ' + InttoStr(Cur.ScoreDiff));
-
- //Add it to the Chain
- if (FirstPopUp = nil) then
- //the first PopUp in the List
- FirstPopUp := Cur
- else
- //second or earlier popup
- LastPopUp.Next := Cur;
-
- //Set new Popup to Last PopUp in the List
- LastPopUp := Cur;
- end
- else
- Log.LogError('TSingScores: Try to add PopUp for not existing player');
-end;
-
-//-----------
-// Removes a PopUp w/o destroying the List
-//-----------
-Procedure TSingScores.KillPopUp(const last, cur: PScorePopUp);
-var
- lTempA ,
- lTempB : real;
-begin
- //Give Player the Last Points that missing till now
- aPlayers[Cur.Player].ScoreDisplayed := aPlayers[Cur.Player].ScoreDisplayed + Cur.ScoreDiff - Cur.ScoreGiven;
-
- //Change Bars Position
- lTempA := ( aPlayers[Cur.Player].RBTarget + (Cur.ScoreDiff - Cur.ScoreGiven) );
- lTempB := ( Cur.ScoreDiff * (Cur.Rating / 20 - 0.26) );
-
- if ( lTempA > 0 ) AND
- ( lTempB > 0 ) THEN
- begin
- aPlayers[Cur.Player].RBTarget := lTempA / lTempB;
- end;
-
- If (aPlayers[Cur.Player].RBTarget > 1) then
- aPlayers[Cur.Player].RBTarget := 1
- else
- If (aPlayers[Cur.Player].RBTarget < 0) then
- aPlayers[Cur.Player].RBTarget := 0;
-
- //If this is the First PopUp => Make Next PopUp the First
- If (Cur = FirstPopUp) then
- FirstPopUp := Cur.Next
- //Else => Remove Curent Popup from Chain
- else
- Last.Next := Cur.Next;
-
- //If this is the Last PopUp, Make PopUp before the Last
- If (Cur = LastPopUp) then
- LastPopUp := Last;
-
- //Free the Memory
- FreeMem(Cur, SizeOf(TScorePopUp));
-end;
-
-//-----------
-//Removes all PopUps from Mem
-//-----------
-Procedure TSingScores.KillAllPopUps;
-var
- Cur: PScorePopUp;
- Last: PScorePopUp;
-begin
- Cur := FirstPopUp;
-
- //Remove all PopUps:
- While (Cur <> nil) do
- begin
- Last := Cur;
- Cur := Cur.Next;
- FreeMem(Last, SizeOf(TScorePopUp));
- end;
-
- FirstPopUp := nil;
- LastPopUp := nil;
-end;
-
-//-----------
-//Init - has to be called after Positions and Players have been added, before first call of Draw
-//It gives every Player a Score Position
-//-----------
-Procedure TSingScores.Init;
-var
- PlC: Array [0..1] of Byte; //Playercount First Screen and Second Screen
- I, J: Integer;
- MaxPlayersperScreen: Byte;
- CurPlayer: Byte;
-
- Function GetPositionCountbyPlayerCount(bPlayerCount: Byte): Byte;
- var I: Integer;
- begin
- Result := 0;
- bPlayerCount := 1 shl (bPlayerCount - 1);
-
- For I := 0 to PositionCount-1 do
- begin
- If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
- Inc(Result);
- end;
- end;
-
- Function GetPositionbyPlayernum(bPlayerCount, bPlayer: Byte): Byte;
- var I: Integer;
- begin
- bPlayerCount := 1 shl (bPlayerCount - 1);
- Result := High(Byte);
-
- For I := 0 to PositionCount-1 do
- begin
- If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
- begin
- If (bPlayer = 0) then
- begin
- Result := I;
- Break;
- end
- else
- Dec(bPlayer);
- end;
- end;
- end;
-
-begin
- MaxPlayersPerScreen := 0;
-
- For I := 1 to 6 do
- begin
- //If there are enough Positions -> Write to MaxPlayers
- If (GetPositionCountbyPlayerCount(I) = I) then
- MaxPlayersPerScreen := I
- else
- Break;
- end;
-
-
- //Split Players to both Screen or Display on One Screen
- if (Screens = 2) and (MaxPlayersPerScreen < PlayerCount) then
- begin
- PlC[0] := PlayerCount div 2 + PlayerCount mod 2;
- PlC[1] := PlayerCount div 2;
- end
- else
- begin
- PlC[0] := PlayerCount;
- PlC[1] := 0;
- end;
-
-
- //Check if there are enough Positions for all Players
- For I := 0 to Screens - 1 do
- begin
- if (PlC[I] > MaxPlayersperScreen) then
- begin
- PlC[I] := MaxPlayersperScreen;
- Log.LogError('More Players than available Positions, TSingScores');
- end;
- end;
-
- CurPlayer := 0;
- //Give every Player a Position
- For I := 0 to Screens - 1 do
- For J := 0 to PlC[I]-1 do
- begin
- aPlayers[CurPlayer].Position := GetPositionbyPlayernum(PlC[I], J) OR (I shl 7);
- //Log.LogError('Player ' + InttoStr(CurPlayer) + ' gets Position: ' + InttoStr(aPlayers[CurPlayer].Position));
- Inc(CurPlayer);
- end;
-end;
-
-//-----------
-//Procedure Draws Scores and Linebonus PopUps
-//-----------
-Procedure TSingScores.Draw;
-var
- I: Integer;
- CurTime: Cardinal;
- CurPopUp, LastPopUp: PScorePopUp;
-begin
- CurTime := SDL_GetTicks;
-
- If Visible then
- begin
- //Draw Popups
- LastPopUp := nil;
- CurPopUp := FirstPopUp;
-
- While (CurPopUp <> nil) do
- begin
- if (CurTime - CurPopUp.TimeStamp > Settings.Phase1Time + Settings.Phase2Time + Settings.Phase3Time) then
- begin
- KillPopUp(LastPopUp, CurPopUp);
- if (LastPopUp = nil) then
- CurPopUp := FirstPopUp
- else
- CurPopUp := LastPopUp.Next;
- end
- else
- begin
- DrawPopUp(CurPopUp);
- LastPopUp := CurPopUp;
- CurPopUp := LastPopUp.Next;
- end;
- end;
-
-
- IF (RBVisible) then
- //Draw Players w/ Rating Bar
- For I := 0 to PlayerCount-1 do
- begin
- DrawScore(I);
- DrawRatingBar(I);
- end
- else
- //Draw Players w/o Rating Bar
- For I := 0 to PlayerCount-1 do
- begin
- DrawScore(I);
- end;
-
- end; //eo Visible
-end;
-
-//-----------
-//Procedure Draws a Popup by Pointer
-//-----------
-Procedure TSingScores.DrawPopUp(const PopUp: PScorePopUp);
-var
- Progress: Real;
- CurTime: Cardinal;
- X, Y, W, H, Alpha: Real;
- FontSize: Byte;
- TimeDiff: Cardinal;
- PIndex: Byte;
- TextLen: Real;
- ScoretoAdd: Word;
- PosDiff: Real;
-begin
- if (PopUp <> nil) then
- begin
- //Only Draw if Player has a Position
- PIndex := Players[PopUp.Player].Position;
- If PIndex <> high(byte) then
- begin
- //Only Draw if Player is on Cur Screen
- If ((Players[PopUp.Player].Position AND 128) = 0) = (ScreenAct = 1) then
- begin
- CurTime := SDL_GetTicks;
- If Not (Enabled AND Players[PopUp.Player].Enabled) then
- //Increase Timestamp with TIem where there is no Movement ...
- begin
- //Inc(PopUp.TimeStamp, LastRender);
- end;
- TimeDiff := CurTime - PopUp.TimeStamp;
-
- //Get Position of PopUp
- PIndex := PIndex AND 127;
-
-
- //Check for Phase ...
- If (TimeDiff <= Settings.Phase1Time) then
- begin
- //Phase 1 - The Ploping up
- Progress := TimeDiff / Settings.Phase1Time;
-
-
- W := Positions[PIndex].PUW * Sin(Progress/2*Pi);
- H := Positions[PIndex].PUH * Sin(Progress/2*Pi);
-
- X := Positions[PIndex].PUStartX + (Positions[PIndex].PUW - W)/2;
- Y := Positions[PIndex].PUStartY + (Positions[PIndex].PUH - H)/2;
-
- FontSize := Round(Progress * Positions[PIndex].PUFontSize);
- Alpha := 1;
- end
-
- Else If (TimeDiff <= Settings.Phase2Time + Settings.Phase1Time) then
- begin
- //Phase 2 - The Moving
- Progress := (TimeDiff - Settings.Phase1Time) / Settings.Phase2Time;
-
- W := Positions[PIndex].PUW;
- H := Positions[PIndex].PUH;
-
- PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
- If PosDiff > 0 then
- PosDiff := PosDiff + W;
- X := Positions[PIndex].PUStartX + PosDiff * sqr(Progress);
-
- PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
- If PosDiff < 0 then
- PosDiff := PosDiff + Positions[PIndex].BGH;
- Y := Positions[PIndex].PUStartY + PosDiff * sqr(Progress);
-
- FontSize := Positions[PIndex].PUFontSize;
- Alpha := 1 - 0.3 * Progress;
- end
-
- else
- begin
- //Phase 3 - The Fading out + Score adding
- Progress := (TimeDiff - Settings.Phase1Time - Settings.Phase2Time) / Settings.Phase3Time;
-
- If (PopUp.Rating > 0) then
- begin
- //Add Scores if Player Enabled
- If (Enabled AND Players[PopUp.Player].Enabled) then
- begin
- ScoreToAdd := Round(PopUp.ScoreDiff * Progress) - PopUp.ScoreGiven;
- Inc(PopUp.ScoreGiven, ScoreToAdd);
- aPlayers[PopUp.Player].ScoreDisplayed := Players[PopUp.Player].ScoreDisplayed + ScoreToAdd;
-
- //Change Bars Position
- aPlayers[PopUp.Player].RBTarget := aPlayers[PopUp.Player].RBTarget + ScoreToAdd/PopUp.ScoreDiff * (PopUp.Rating / 20 - 0.26);
- If (aPlayers[PopUp.Player].RBTarget > 1) then
- aPlayers[PopUp.Player].RBTarget := 1
- else If (aPlayers[PopUp.Player].RBTarget < 0) then
- aPlayers[PopUp.Player].RBTarget := 0;
- end;
-
- //Set Positions etc.
- Alpha := 0.7 - 0.7 * Progress;
-
- W := Positions[PIndex].PUW;
- H := Positions[PIndex].PUH;
-
- PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
- If (PosDiff > 0) then
- PosDiff := W
- else
- PosDiff := 0;
- X := Positions[PIndex].PUTargetX + PosDiff * Progress;
-
- PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
- If (PosDiff < 0) then
- PosDiff := -Positions[PIndex].BGH
- else
- PosDiff := 0;
- Y := Positions[PIndex].PUTargetY - PosDiff * (1-Progress);
-
- FontSize := Positions[PIndex].PUFontSize;
- end
- else
- begin
- //Here the Effect that Should be shown if a PopUp without Score is Drawn
- //And or Spawn with the GraphicObjects etc.
- //Some Work for Blindy to do :P
-
- //ATM: Just Let it Slide in the Scores just like the Normal PopUp
- Alpha := 0;
- end;
- end;
-
- //Draw PopUp
-
- if (Alpha > 0) AND (Players[PopUp.Player].Visible) then
- begin
- //Draw BG:
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4f(1,1,1, Alpha);
- glBindTexture(GL_TEXTURE_2D, Settings.PopUpTex[PopUp.Rating].TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X, Y + H);
- glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X + W, Y + H);
- glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, 0); glVertex2f(X + W, Y);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- //Set FontStyle and Size
- SetFontStyle(Positions[PIndex].PUFont);
- SetFontItalic(False);
- SetFontSize(FontSize);
-
- //Draw Text
- TextLen := glTextWidth(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
-
- //Color and Pos
- SetFontPos (X + (W - TextLen) / 2, Y + 12);
- glColor4f(1, 1, 1, Alpha);
-
- //Draw
- glPrint(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
- end; //eo Alpha check
- end; //eo Right Screen
- end; //eo Player has Position
- end
- else
- Log.LogError('TSingScores: Try to Draw a not existing PopUp');
-end;
-
-//-----------
-//Procedure Draws a Score by Playerindex
-//-----------
-Procedure TSingScores.DrawScore(const Index: Integer);
-var
- Position: PScorePosition;
- ScoreStr: String;
-begin
- //Only Draw if Player has a Position
- If Players[Index].Position <> high(byte) then
- begin
- //Only Draw if Player is on Cur Screen
- If (((Players[Index].Position AND 128) = 0) = (ScreenAct = 1)) AND Players[Index].Visible then
- begin
- Position := @Positions[Players[Index].Position and 127];
-
- //Draw ScoreBG
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4f(1,1,1, 1);
- glBindTexture(GL_TEXTURE_2D, Players[Index].ScoreBG.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Position.BGX, Position.BGY);
- glTexCoord2f(0, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX, Position.BGY + Position.BGH);
- glTexCoord2f(Players[Index].ScoreBG.TexW, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX + Position.BGW, Position.BGY + Position.BGH);
- glTexCoord2f(Players[Index].ScoreBG.TexW, 0); glVertex2f(Position.BGX + Position.BGW, Position.BGY);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- //Draw Score Text
- SetFontStyle(Position.TextFont);
- SetFontItalic(False);
- SetFontSize(Position.TextSize);
- SetFontPos(Position.TextX, Position.TextY);
-
- ScoreStr := InttoStr(Players[Index].ScoreDisplayed div 10) + '0';
- While (Length(ScoreStr) < 5) do
- ScoreStr := '0' + ScoreStr;
-
- glPrint(PChar(ScoreStr));
-
- end; //eo Right Screen
- end; //eo Player has Position
-end;
-
-
-Procedure TSingScores.DrawRatingBar(const Index: Integer);
-var
- Position: PScorePosition;
- R,G,B, Size: Real;
- Diff: Real;
-begin
- //Only Draw if Player has a Position
- if Players[Index].Position <> high(byte) then
- begin
- //Only Draw if Player is on Cur Screen
- if (((Players[Index].Position and 128) = 0) = (ScreenAct = 1) and
- Players[index].RBVisible and
- Players[index].Visible) then
- begin
- Position := @Positions[Players[Index].Position and 127];
-
- if (Enabled AND Players[Index].Enabled) then
- begin
- //Move Position if Enabled
- Diff := Players[Index].RBTarget - Players[Index].RBPos;
- If(Abs(Diff) < 0.02) then
- aPlayers[Index].RBPos := aPlayers[Index].RBTarget
- else
- aPlayers[Index].RBPos := aPlayers[Index].RBPos + Diff*0.1;
- end;
-
- //Get Colors for RatingBar
- if (Players[index].RBPos <= 0.22) then
- begin
- R := 1;
- G := 0;
- B := 0;
- end
- else if (Players[index].RBPos <= 0.42) then
- begin
- R := 1;
- G := Players[index].RBPos*5;
- B := 0;
- end
- else if (Players[index].RBPos <= 0.57) then
- begin
- R := 1;
- G := 1;
- B := 0;
- end
- else if (Players[index].RBPos <= 0.77) then
- begin
- R := 1-(Players[index].RBPos-0.57)*5;
- G := 1;
- B := 0;
- end
- else
- begin
- R := 0;
- G := 1;
- B := 0;
- end;
-
- //Enable all glFuncs Needed
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- //Draw RatingBar BG
- glColor4f(1, 1, 1, 0.8);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_BG_Tex.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_BG_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY+Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, Settings.RatingBar_BG_Tex.TexH);
- glVertex2f(Position.RBX+Position.RBW, Position.RBY+Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, 0);
- glVertex2f(Position.RBX+Position.RBW, Position.RBY);
- glEnd;
-
- //Draw Rating bar itself
- Size := Position.RBX + Position.RBW * Players[Index].RBPos;
- glColor4f(R, G, B, 1);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_Bar_Tex.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_Bar_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, Settings.RatingBar_Bar_Tex.TexH);
- glVertex2f(Size, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, 0);
- glVertex2f(Size, Position.RBY);
- glEnd;
-
- //Draw Ratingbar FG (Teh thing with the 3 lines to get better readability)
- glColor4f(1, 1, 1, 0.6);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_FG_Tex.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_FG_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, Settings.RatingBar_FG_Tex.TexH);
- glVertex2f(Position.RBX + Position.RBW, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, 0);
- glVertex2f(Position.RBX + Position.RBW, Position.RBY);
- glEnd;
-
- //Disable all Enabled glFuncs
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- end; //eo Right Screen
- end; //eo Player has Position
-end;
-
-end.
diff --git a/Game/Code/Classes/USkins.pas b/Game/Code/Classes/USkins.pas
deleted file mode 100644
index 88549c9f..00000000
--- a/Game/Code/Classes/USkins.pas
+++ /dev/null
@@ -1,185 +0,0 @@
-unit USkins;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-type
- TSkinTexture = record
- Name: string;
- FileName: string;
- end;
-
- TSkinEntry = record
- Theme: string;
- Name: string;
- Path: string;
- FileName: string;
- Creator: string; // not used yet
- end;
-
- TSkin = class
- Skin: array of TSkinEntry;
- SkinTexture: array of TSkinTexture;
- SkinPath: string;
- Color: integer;
- constructor Create;
- procedure LoadList;
- procedure ParseDir(Dir: string);
- procedure LoadHeader(FileName: string);
- procedure LoadSkin(Name: string);
- function GetTextureFileName(TextureName: string): string;
- function GetSkinNumber(Name: string): integer;
- procedure onThemeChange;
- end;
-
-var
- Skin: TSkin;
-
-implementation
-
-uses IniFiles,
- Classes,
- SysUtils,
- UMain,
- ULog,
- UIni;
-
-constructor TSkin.Create;
-begin
- inherited;
- LoadList;
-// LoadSkin('Lisek');
-// SkinColor := Color;
-end;
-
-procedure TSkin.LoadList;
-var
- SR: TSearchRec;
-begin
- if FindFirst(SkinsPath+'*', faDirectory, SR) = 0 then begin
- repeat
- if (SR.Name <> '.') and (SR.Name <> '..') then
- ParseDir(SkinsPath + SR.Name + PathDelim);
- until FindNext(SR) <> 0;
- end; // if
- FindClose(SR);
-end;
-
-procedure TSkin.ParseDir(Dir: string);
-var
- SR: TSearchRec;
-begin
- if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then begin
- repeat
-
- if (SR.Name <> '.') and (SR.Name <> '..') then
- LoadHeader(Dir + SR.Name);
-
- until FindNext(SR) <> 0;
- end;
-end;
-
-procedure TSkin.LoadHeader(FileName: string);
-var
- SkinIni: TMemIniFile;
- S: integer;
-begin
- SkinIni := TMemIniFile.Create(FileName);
-
- S := Length(Skin);
- SetLength(Skin, S+1);
-
- Skin[S].Path := IncludeTrailingPathDelimiter(ExtractFileDir(FileName));
- Skin[S].FileName := ExtractFileName(FileName);
- Skin[S].Theme := SkinIni.ReadString('Skin', 'Theme', '');
- Skin[S].Name := SkinIni.ReadString('Skin', 'Name', '');
- Skin[S].Creator := SkinIni.ReadString('Skin', 'Creator', '');
-
- SkinIni.Free;
-end;
-
-procedure TSkin.LoadSkin(Name: string);
-var
- SkinIni: TMemIniFile;
- SL: TStringList;
- T: integer;
- S: integer;
-begin
- S := GetSkinNumber(Name);
- SkinPath := Skin[S].Path;
-
- SkinIni := TMemIniFile.Create(SkinPath + Skin[S].FileName);
-
- SL := TStringList.Create;
- SkinIni.ReadSection('Textures', SL);
-
- SetLength(SkinTexture, SL.Count);
- for T := 0 to SL.Count-1 do
- begin
- SkinTexture[T].Name := SL.Strings[T];
- SkinTexture[T].FileName := SkinIni.ReadString('Textures', SL.Strings[T], '');
- end;
-
- SL.Free;
- SkinIni.Free;
-end;
-
-function TSkin.GetTextureFileName(TextureName: string): string;
-var
- T: integer;
-begin
- Result := '';
-
- for T := 0 to High(SkinTexture) do
- begin
- if ( SkinTexture[T].Name = TextureName ) AND
- ( SkinTexture[T].FileName <> '' ) then
- begin
- Result := SkinPath + SkinTexture[T].FileName;
- end;
- end;
-
- if ( TextureName <> '' ) AND
- ( Result <> '' ) THEN
- begin
- //Log.LogError('', '-----------------------------------------');
- //Log.LogError(TextureName+' - '+ Result, 'TSkin.GetTextureFileName');
- end;
-
-{ Result := SkinPath + 'Bar.jpg';
- if TextureName = 'Ball' then Result := SkinPath + 'Ball.bmp';
- if Copy(TextureName, 1, 4) = 'Gray' then Result := SkinPath + 'Ball.bmp';
- if Copy(TextureName, 1, 6) = 'NoteBG' then Result := SkinPath + 'Ball.bmp';}
-end;
-
-function TSkin.GetSkinNumber(Name: string): integer;
-var
- S: integer;
-begin
- Result := 0; // set default to the first available skin
- for S := 0 to High(Skin) do
- if Skin[S].Name = Name then Result := S;
-end;
-
-procedure TSkin.onThemeChange;
-var
- S: integer;
- Name: String;
-begin
- Ini.SkinNo:=0;
- SetLength(ISkin, 0);
- Name := Uppercase(ITheme[Ini.Theme]);
- for S := 0 to High(Skin) do
- if Name = Uppercase(Skin[S].Theme) then begin
- SetLength(ISkin, Length(ISkin)+1);
- ISkin[High(ISkin)] := Skin[S].Name;
- end;
-
-end;
-
-end.
diff --git a/Game/Code/Classes/USong.pas b/Game/Code/Classes/USong.pas
deleted file mode 100644
index 3517bce6..00000000
--- a/Game/Code/Classes/USong.pas
+++ /dev/null
@@ -1,1027 +0,0 @@
-unit USong;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- {$IFDEF MSWINDOWS}
- Windows,
- {$ELSE}
- {$IFNDEF DARWIN}
- syscall,
- {$ENDIF}
- baseunix,
- UnixType,
- {$ENDIF}
- SysUtils,
- Classes,
- UPlatform,
- ULog,
- UTexture,
- UCommon,
- {$IFDEF DARWIN}
- cthreads,
- {$ENDIF}
- {$IFDEF USE_PSEUDO_THREAD}
- PseudoThread,
- {$ENDIF}
- UCatCovers,
- UXMLSong;
-
-type
-
- TSingMode = ( smNormal, smPartyMode, smPlaylistRandom );
-
- TBPM = record
- BPM: real;
- StartBeat: real;
- end;
-
- TScore = record
- Name: WideString;
- Score: integer;
- Length: string;
- end;
-
- TSong = class
- FileLineNo : integer; //Line which is readed at Last, for error reporting
-
- procedure ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
- procedure NewSentence(LineNumberP: integer; Param1, Param2: integer);
-
- function ReadTXTHeader( const aFileName : WideString ): boolean;
- function ReadXMLHeader( const aFileName : WideString ): boolean;
- public
- Path: WideString;
- Folder: WideString; // for sorting by folder
- fFileName,
- FileName: WideString;
-
- // sorting methods
- Category: array of WideString; // TODO: do we need this?
- Genre: WideString;
- Edition: WideString;
- Language: WideString;
-
- Title: WideString;
- Artist: WideString;
-
- Text: WideString;
- Creator: WideString;
-
- Cover: WideString;
- CoverTex: TTexture;
- Mp3: WideString;
- Background: WideString;
- Video: WideString;
- VideoGAP: real;
- VideoLoaded: boolean; // true if the video has been loaded
- NotesGAP: integer;
- Start: real; // in seconds
- Finish: integer; // in miliseconds
- Relative: boolean;
- Resolution: integer;
- BPM: array of TBPM;
- GAP: real; // in miliseconds
-
- Score: array[0..2] of array of TScore;
-
- // these are used when sorting is enabled
- Visible: boolean; // false if hidden, true if visible
- Main: boolean; // false for songs, true for category buttons
- OrderNum: integer; // has a number of category for category buttons and songs
- OrderTyp: integer; // type of sorting for this button (0=name)
- CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs
-
- SongFile: TextFile; // all procedures in this unit operate on this file
-
- Base : array[0..1] of integer;
- Rel : array[0..1] of integer;
- Mult : integer;
- MultBPM : integer;
-
- constructor Create (); overload;
- constructor Create ( const aFileName : WideString ); overload;
- function LoadSong: boolean;
- function LoadXMLSong: boolean;
- function Analyse(): boolean;
- function AnalyseXML(): boolean;
- procedure Clear();
- end;
-
-implementation
-
-uses
- TextGL,
- UIni,
- UMusic, //needed for Lines
- UMain; //needed for Player
-
-constructor TSong.Create();
-begin
- inherited;
-end;
-
-constructor TSong.Create( const aFileName : WideString );
-begin
- inherited Create();
-
- Mult := 1;
- MultBPM := 4;
- fFileName := aFileName;
-
- if fileexists( aFileName ) then
- begin
- self.Path := ExtractFilePath( aFileName );
- self.Folder := ExtractFilePath( aFileName );
- self.FileName := ExtractFileName( aFileName );
- (*
- if ReadTXTHeader( aFileName ) then
- begin
- LoadSong();
- end
- else
- begin
- Log.LogError('Error Loading SongHeader, abort Song Loading');
- Exit;
- end;
- *)
- end;
-end;
-
-//Load TXT Song
-function TSong.LoadSong(): boolean;
-
-var
- TempC: char;
- Text: string;
- CP: integer; // Current Player (0 or 1)
- Count: integer;
- Both: boolean;
- Param1: integer;
- Param2: integer;
- Param3: integer;
- ParamS: string;
- I: integer;
-begin
- Result := false;
-
- if not FileExists(Path + PathDelim + FileName) then
- begin
- Log.LogError('File not found: "' + Path + PathDelim + FileName + '"', 'TSong.LoadSong()');
- exit;
- end;
-
- MultBPM := 4; // multiply beat-count of note by 4
- Mult := 1; // accuracy of measurement of note
- Base[0] := 100; // high number
- Lines[0].ScoreValue := 0;
- self.Relative := false;
- Rel[0] := 0;
- CP := 0;
- Both := false;
-
- if Length(Player) = 2 then
- Both := true;
-
- try
- // Open song file for reading.....
- FileMode := fmOpenRead;
- AssignFile(SongFile, fFileName);
- Reset(SongFile);
-
- //Clear old Song Header
- if (self.Path = '') then
- self.Path := ExtractFilePath(FileName);
-
- if (self.FileName = '') then
- self.Filename := ExtractFileName(FileName);
-
- Result := False;
-
- Reset(SongFile);
- FileLineNo := 0;
- //Search for Note Begining
- repeat
- ReadLn(SongFile, Text);
- Inc(FileLineNo);
-
- if (EoF(SongFile)) then
- begin //Song File Corrupted - No Notes
- CloseFile(SongFile);
- Log.LogError('Could not load txt File, no Notes found: ' + FileName);
- Result := False;
- Exit;
- end;
- Read(SongFile, TempC);
- until ((TempC = ':') or (TempC = 'F') or (TempC = '*'));
-
- SetLength(Lines, 2);
- for Count := 0 to High(Lines) do
- begin
- SetLength(Lines[Count].Line, 1);
- Lines[Count].High := 0;
- Lines[Count].Number := 1;
- Lines[Count].Current := 0;
- Lines[Count].Resolution := self.Resolution;
- Lines[Count].NotesGAP := self.NotesGAP;
- Lines[Count].Line[0].HighNote := -1;
- Lines[Count].Line[0].LastLine := False;
- end;
-
- // TempC := ':';
- // TempC := Text[1]; // read from backup variable, don't use default ':' value
-
- while (TempC <> 'E') AND (not EOF(SongFile)) do
- begin
-
- if (TempC = ':') or (TempC = '*') or (TempC = 'F') then
- begin
- // read notes
- Read(SongFile, Param1);
- Read(SongFile, Param2);
- Read(SongFile, Param3);
- Read(SongFile, ParamS);
-
-
- //Check for ZeroNote
- if Param2 = 0 then Log.LogError('Found ZeroNote at "'+TempC+' '+IntToStr(Param1)+' '+IntToStr(Param2)+' '+IntToStr(Param3)+ParamS+'" -> Note ignored!') else
- begin
- // add notes
- if not Both then
- // P1
- ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
- else begin
- // P1 + P2
- ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
- ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
- end;
- end; //Zeronote check
- end; // if
-
- if TempC = '-' then
- begin
- // reads sentence
- Read(SongFile, Param1);
- if self.Relative then Read(SongFile, Param2); // read one more data for relative system
-
- // new sentence
- if not Both then
- // P1
- NewSentence(0, (Param1 + Rel[0]) * Mult, Param2)
- else begin
- // P1 + P2
- NewSentence(0, (Param1 + Rel[0]) * Mult, Param2);
- NewSentence(1, (Param1 + Rel[1]) * Mult, Param2);
- end;
- end; // if
-
- if TempC = 'B' then
- begin
- SetLength(self.BPM, Length(self.BPM) + 1);
- Read(SongFile, self.BPM[High(self.BPM)].StartBeat);
- self.BPM[High(self.BPM)].StartBeat := self.BPM[High(self.BPM)].StartBeat + Rel[0];
-
- Read(SongFile, Text);
- self.BPM[High(self.BPM)].BPM := StrToFloat(Text);
- self.BPM[High(self.BPM)].BPM := self.BPM[High(self.BPM)].BPM * Mult * MultBPM;
- end;
-
-
- if not Both then
- begin
- Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
- Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(PChar(Lines[CP].Line[Lines[CP].High].Lyric));
- //Total Notes Patch
- Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
- for I := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do
- begin
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
-
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
- end;
- //Total Notes Patch End
- end else begin
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
- Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(PChar(Lines[Count].Line[Lines[Count].High].Lyric));
- //Total Notes Patch
- Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
- for I := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do
- begin
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
- end;
- //Total Notes Patch End
- end;
- end;
- Read(SongFile, TempC);
- Inc(FileLineNo);
- end; // while}
-
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
- end;
-
- CloseFile(SongFile);
- except
- try
- CloseFile(SongFile);
- except
-
- end;
-
- Log.LogError('Error Loading File: "' + fFileName + '" in Line ' + inttostr(FileLineNo));
- exit;
- end;
-
- Result := true;
-end;
-
-//Load XML Song
-function TSong.LoadXMLSong(): boolean;
-var
- //TempC: char;
- Text: string;
- CP: integer; // Current Player (0 or 1)
- Count: integer;
- Both: boolean;
- Param1: integer;
- Param2: integer;
- Param3: integer;
- ParamS: string;
- I,J,X: integer;
-
- NoteType: Char;
- SentenceEnd, Rest, Time: Integer;
- Parser: TParser;
-begin
- Result := false;
-
- if not FileExists(Path + PathDelim + FileName) then
- begin
- Log.LogError('File not found: "' + Path + PathDelim + FileName + '"', 'TSong.LoadSong()');
- exit;
- end;
-
- MultBPM := 4; // multiply beat-count of note by 4
- Mult := 1; // accuracy of measurement of note
- Base[0] := 100; // high number
- Lines[0].ScoreValue := 0;
- self.Relative := false;
- Rel[0] := 0;
- CP := 0;
- Both := false;
-
- if Length(Player) = 2 then
- Both := true;
-
- Parser := TParser.Create;
- Parser.Settings.DashReplacement := '~';
-
- for Count := 0 to High(Lines) do
- begin
- SetLength(Lines[Count].Line, 1);
- Lines[Count].High := 0;
- Lines[Count].Number := 1;
- Lines[Count].Current := 0;
- Lines[Count].Resolution := self.Resolution;
- Lines[Count].NotesGAP := self.NotesGAP;
- Lines[Count].Line[0].HighNote := -1;
- Lines[Count].Line[0].LastLine := False;
- end;
-
-//Try to Parse the Song
-
- if Parser.ParseSong(Path + PathDelim + FileName) then
- begin
-// Writeln('XML Inputfile Parsed succesful');
- //Start write parsed information to Song
- //Notes Part
- for I := 0 to High(Parser.SongInfo.Sentences) do
- begin
- //Add Notes
- for J := 0 to High(Parser.SongInfo.Sentences[I].Notes) do
- begin
- case Parser.SongInfo.Sentences[I].Notes[J].NoteTyp of
- NT_Normal: NoteType := ':';
- NT_Golden: NoteType := '*';
- NT_Freestyle: NoteType := 'F';
- end;
-
- Param1:=Parser.SongInfo.Sentences[I].Notes[J].Start; //Note Start
- Param2:=Parser.SongInfo.Sentences[I].Notes[J].Duration; //Note Duration
- Param3:=Parser.SongInfo.Sentences[I].Notes[J].Tone; //Note Tone
- ParamS:=' ' + Parser.SongInfo.Sentences[I].Notes[J].Lyric; //Note Lyric
-
- if not Both then
- // P1
- ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
- else
- begin
- // P1 + P2
- ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
- ParseNote(1, NoteType, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
- end;
-
- if not Both then
- begin
- Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
- Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(PChar(Lines[CP].Line[Lines[CP].High].Lyric));
- //Total Notes Patch
- Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
- for X := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do
- begin
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length;
-
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length;
- end;
- //Total Notes Patch End
- end
- else
- begin
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
- Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(PChar(Lines[Count].Line[Lines[Count].High].Lyric));
- //Total Notes Patch
- Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
- for X := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do
- begin
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length;
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length;
-
- end;
- //Total Notes Patch End
- end;
- end; { end of for loop }
-
- end; //J Forloop
-
- //Add Sentence break
- if (I < High(Parser.SongInfo.Sentences)) then
- begin
-
- SentenceEnd := Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Start + Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Duration;
- Rest := Parser.SongInfo.Sentences[I+1].Notes[0].Start - SentenceEnd;
-
- //Calculate Time
- case Rest of
- 0, 1: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start;
- 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1;
- 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2;
- else
- if (Rest >= 4) then
- Time := SentenceEnd + 2
- else //Sentence overlapping :/
- Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start;
- end;
- // new sentence
- if not Both then
- // P1
- NewSentence(0, (Time + Rel[0]) * Mult, Param2)
- else
- begin
- // P1 + P2
- NewSentence(0, (Time + Rel[0]) * Mult, Param2);
- NewSentence(1, (Time + Rel[1]) * Mult, Param2);
- end;
-
- end;
- end;
- //End write parsed information to Song
- Parser.Free;
- end
- else
- begin
- Log.LogError('Could not parse Inputfile: ' + Path + PathDelim + FileName);
- exit;
- end;
-
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
- end;
-
- Result := true;
-end;
-
-function TSong.ReadXMLHeader(const aFileName : WideString): boolean;
-var
- Line, Identifier, Value: string;
- Temp : word;
- Done : byte;
- Parser : TParser;
-begin
- Result := true;
- Done := 0;
-
-//Parse XML
- Parser := TParser.Create;
- Parser.Settings.DashReplacement := '~';
-
-
- if Parser.ParseSong(self.Path + self.FileName) then
- begin
- //-----------
- //Required Attributes
- //-----------
-
- //Title
- self.Title := Parser.SongInfo.Header.Title;
-
- //Add Title Flag to Done
- Done := Done or 1;
-
- //Artist
- self.Artist := Parser.SongInfo.Header.Artist;
-
- //Add Artist Flag to Done
- Done := Done or 2;
-
- //MP3 File //Test if Exists
- self.Mp3 := platform.FindSongFile(Path, '*.mp3');
- if (FileExists(self.Path + self.Mp3)) then
- //Add Mp3 Flag to Done
- Done := Done or 4;
-
- //Beats per Minute
- SetLength(self.BPM, 1);
- self.BPM[0].StartBeat := 0;
-
- self.BPM[0].BPM := (Parser.SongInfo.Header.BPM * Parser.SongInfo.Header.Resolution/4 ) * Mult * MultBPM;
-
- if self.BPM[0].BPM <> 0 then
- //Add BPM Flag to Done
- Done := Done or 8;
-
- //---------
- //Additional Header Information
- //---------
-
- // Gap
- self.GAP := Parser.SongInfo.Header.Gap;
-
- //Cover Picture
- self.Cover := platform.FindSongFile(Path, '*[CO].jpg');
-
- //Background Picture
- self.Background := platform.FindSongFile(Path, '*[BG].jpg');
-
- // Video File
- // self.Video := Value
-
- // Video Gap
- // self.VideoGAP := song_StrtoFloat( Value )
-
- //Genre Sorting
- self.Genre := Parser.SongInfo.Header.Genre;
-
- //Edition Sorting
- self.Edition := Parser.SongInfo.Header.Edition;
-
- //Year Sorting
- //Parser.SongInfo.Header.Year
-
- //Language Sorting
- self.Language := Parser.SongInfo.Header.Language;
- end else
- Log.LogError('File Incomplete or not SingStar XML (A): ' + aFileName);
-
- Parser.Free;
-
- //Check if all Required Values are given
- if (Done <> 15) then
- begin
- Result := False;
- if (Done and 8) = 0 then //No BPM Flag
- Log.LogError('BPM Tag Missing: ' + self.FileName)
- else if (Done and 4) = 0 then //No MP3 Flag
- Log.LogError('MP3 Tag/File Missing: ' + self.FileName)
- else if (Done and 2) = 0 then //No Artist Flag
- Log.LogError('Artist Tag Missing: ' + self.FileName)
- else if (Done and 1) = 0 then //No Title Flag
- Log.LogError('Title Tag Missing: ' + self.FileName)
- else //unknown Error
- Log.LogError('File Incomplete or not SingStar XML (B - '+ inttostr(Done) +'): ' + aFileName);
- end;
-
-end;
-
-
-function TSong.ReadTXTHeader(const aFileName : WideString): boolean;
-
- function song_StrtoFloat( aValue : string ) : Extended;
- var
- lValue : string;
-// lOldDecimalSeparator : Char; // Auto Removed, Unused Variable
- begin
- lValue := aValue;
-
- if (Pos(',', lValue) <> 0) then
- lValue[Pos(',', lValue)] := '.';
-
- Result := StrToFloatDef(lValue, 0);
- end;
-
-var
- Line, Identifier, Value: string;
- Temp : word;
- Done : byte;
-begin
- Result := true;
- Done := 0;
-
- //Read first Line
- ReadLn (SongFile, Line);
-
- if (Length(Line)<=0) then
- begin
- Log.LogError('File Starts with Empty Line: ' + aFileName);
- Result := False;
- Exit;
- end;
-
- //Read Lines while Line starts with # or its empty
- while ( Length(Line) = 0 ) or
- ( Line[1] = '#' ) do
- begin
- //Increase Line Number
- Inc (FileLineNo);
- Temp := Pos(':', Line);
-
- //Line has a Seperator-> Headerline
- if (Temp <> 0) then
- begin
- //Read Identifier and Value
- Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks
- Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp));
-
- //Check the Identifier (If Value is given)
- if (Length(Value) <> 0) then
- begin
-
- //-----------
- //Required Attributes
- //-----------
-
- {$IFDEF UTF8_FILENAMES}
- if ((Identifier = 'MP3') or (Identifier = 'BACKGROUND') or (Identifier = 'COVER') or (Identifier = 'VIDEO')) then
- Value := Utf8Encode(Value);
- {$ENDIF}
-
- //Title
- if (Identifier = 'TITLE') then
- begin
- self.Title := Value;
-
- //Add Title Flag to Done
- Done := Done or 1;
- end
-
- //Artist
- else if (Identifier = 'ARTIST') then
- begin
- self.Artist := Value;
-
- //Add Artist Flag to Done
- Done := Done or 2;
- end
-
- //MP3 File //Test if Exists
- else if (Identifier = 'MP3') AND
- (FileExists(self.Path + Value)) then
- begin
- self.Mp3 := Value;
-
- //Add Mp3 Flag to Done
- Done := Done or 4;
- end
-
- //Beats per Minute
- else if (Identifier = 'BPM') then
- begin
- SetLength(self.BPM, 1);
- self.BPM[0].StartBeat := 0;
-
- self.BPM[0].BPM := song_StrtoFloat( Value ) * Mult * MultBPM;
-
- if self.BPM[0].BPM <> 0 then
- begin
- //Add BPM Flag to Done
- Done := Done or 8;
- end;
- end
-
- //---------
- //Additional Header Information
- //---------
-
- // Gap
- else if (Identifier = 'GAP') then
- self.GAP := song_StrtoFloat( Value )
-
- //Cover Picture
- else if (Identifier = 'COVER') then
- self.Cover := Value
-
- //Background Picture
- else if (Identifier = 'BACKGROUND') then
- self.Background := Value
-
- // Video File
- else if (Identifier = 'VIDEO') then
- begin
- if (FileExists(self.Path + Value)) then
- self.Video := Value
- else
- Log.LogError('Can''t find Video File in Song: ' + aFileName);
- end
-
- // Video Gap
- else if (Identifier = 'VIDEOGAP') then
- self.VideoGAP := song_StrtoFloat( Value )
-
- //Genre Sorting
- else if (Identifier = 'GENRE') then
- self.Genre := Value
-
- //Edition Sorting
- else if (Identifier = 'EDITION') then
- self.Edition := Value
-
- //Creator Tag
- else if (Identifier = 'CREATOR') then
- self.Creator := Value
-
- //Language Sorting
- else if (Identifier = 'LANGUAGE') then
- self.Language := Value
-
- // Song Start
- else if (Identifier = 'START') then
- self.Start := song_StrtoFloat( Value )
-
- // Song Ending
- else if (Identifier = 'END') then
- TryStrtoInt(Value, self.Finish)
-
- // Resolution
- else if (Identifier = 'RESOLUTION') then
- TryStrtoInt(Value, self.Resolution)
-
- // Notes Gap
- else if (Identifier = 'NOTESGAP') then
- TryStrtoInt(Value, self.NotesGAP)
- // Relative Notes
- else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then
- self.Relative := True;
-
- end;
- end;
-
- if not EOf(SongFile) then
- ReadLn (SongFile, Line)
- else
- begin
- Result := False;
- Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + aFileName);
- break;
- end;
-
- end;
-
- if self.Cover = '' then
- self.Cover := platform.FindSongFile(Path, '*[CO].jpg');
-
- //Check if all Required Values are given
- if (Done <> 15) then
- begin
- Result := False;
- if (Done and 8) = 0 then //No BPM Flag
- Log.LogError('BPM Tag Missing: ' + self.FileName)
- else if (Done and 4) = 0 then //No MP3 Flag
- Log.LogError('MP3 Tag/File Missing: ' + self.FileName)
- else if (Done and 2) = 0 then //No Artist Flag
- Log.LogError('Artist Tag Missing: ' + self.FileName)
- else if (Done and 1) = 0 then //No Title Flag
- Log.LogError('Title Tag Missing: ' + self.FileName)
- else //unknown Error
- Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + aFileName);
- end;
-
-end;
-
-procedure TSong.ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
-//var
-// Space: boolean; // Auto Removed, Unused Variable
-begin
- case Ini.Solmization of
- 1: // european
- begin
- case (NoteP mod 12) of
- 0..1: LyricS := ' do ';
- 2..3: LyricS := ' re ';
- 4: LyricS := ' mi ';
- 5..6: LyricS := ' fa ';
- 7..8: LyricS := ' sol ';
- 9..10: LyricS := ' la ';
- 11: LyricS := ' si ';
- end;
- end;
- 2: // japanese
- begin
- case (NoteP mod 12) of
- 0..1: LyricS := ' do ';
- 2..3: LyricS := ' re ';
- 4: LyricS := ' mi ';
- 5..6: LyricS := ' fa ';
- 7..8: LyricS := ' so ';
- 9..10: LyricS := ' la ';
- 11: LyricS := ' shi ';
- end;
- end;
- 3: // american
- begin
- case (NoteP mod 12) of
- 0..1: LyricS := ' do ';
- 2..3: LyricS := ' re ';
- 4: LyricS := ' mi ';
- 5..6: LyricS := ' fa ';
- 7..8: LyricS := ' sol ';
- 9..10: LyricS := ' la ';
- 11: LyricS := ' ti ';
- end;
- end;
- end; // case
-
- with Lines[LineNumber].Line[Lines[LineNumber].High] do
- begin
- SetLength(Note, Length(Note) + 1);
- HighNote := High(Note);
-
- Note[HighNote].Start := StartP;
- if HighNote = 0 then
- begin
- if Lines[LineNumber].Number = 1 then
- Start := -100;
-// Start := Note[HighNote].Start;
- end;
-
- Note[HighNote].Length := DurationP;
-
- // back to the normal system with normal, golden and now freestyle notes
- case TypeP of
- 'F': Note[HighNote].NoteType := ntFreestyle;
- ':': Note[HighNote].NoteType := ntNormal;
- '*': Note[HighNote].NoteType := ntGolden;
- end;
-
- if (Note[HighNote].NoteType = ntGolden) then
- Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
-
- if (Note[HighNote].NoteType <> ntFreestyle) then
- Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
-
- Note[HighNote].Tone := NoteP;
- if Note[HighNote].Tone < Base[LineNumber] then Base[LineNumber] := Note[HighNote].Tone;
-
- Note[HighNote].Text := Copy(LyricS, 2, 100);
- Lyric := Lyric + Note[HighNote].Text;
-
- End_ := Note[HighNote].Start + Note[HighNote].Length;
- end; // with
-end;
-
-procedure TSong.NewSentence(LineNumberP: integer; Param1, Param2: integer);
-var
- I: integer;
-begin
-
- // stara czesc //Alter Satz //Update Old Part
- Lines[LineNumberP].Line[Lines[LineNumberP].High].BaseNote := Base[LineNumberP];
- Lines[LineNumberP].Line[Lines[LineNumberP].High].LyricWidth := glTextWidth(PChar(Lines[LineNumberP].Line[Lines[LineNumberP].High].Lyric));
-
- //Total Notes Patch
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := 0;
- for I := low(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) to high(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) do
- begin
- if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType = ntGolden) then
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
-
- if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType <> ntFreestyle) then
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
- end;
- //Total Notes Patch End
-
-
- // nowa czesc //Neuer Satz //Update New Part
- SetLength(Lines[LineNumberP].Line, Lines[LineNumberP].Number + 1);
- Lines[LineNumberP].High := Lines[LineNumberP].High + 1;
- Lines[LineNumberP].Number := Lines[LineNumberP].Number + 1;
- Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote := -1;
-
- if self.Relative then
- begin
- Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
- Rel[LineNumberP] := Rel[LineNumberP] + Param2;
- end
- else
- Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
-
- Lines[LineNumberP].Line[Lines[LineNumberP].High].LastLine := False;
-
- Base[LineNumberP] := 100; // high number
-end;
-
-procedure TSong.clear();
-begin
- //Main Information
- Title := '';
- Artist := '';
-
- //Sortings:
- Genre := 'Unknown';
- Edition := 'Unknown';
- Language := 'Unknown'; //Language Patch
-
- //Required Information
- Mp3 := '';
- {$IFDEF FPC}
- setlength( BPM, 0 );
- {$ELSE}
- BPM := nil;
- {$ENDIF}
-
- GAP := 0;
- Start := 0;
- Finish := 0;
-
- //Additional Information
- Background := '';
- Cover := '';
- Video := '';
- VideoGAP := 0;
- NotesGAP := 0;
- Resolution := 4;
- Creator := '';
-
-end;
-
-function TSong.Analyse(): boolean;
-begin
- Result := False;
-
- //Reset LineNo
- FileLineNo := 0;
-
- //Open File and set File Pointer to the beginning
- AssignFile(SongFile, self.Path + self.FileName);
-
- try
- Reset(SongFile);
-
- //Clear old Song Header
- self.clear;
-
- //Read Header
- Result := self.ReadTxTHeader( FileName )
-
- //And Close File
- finally
- CloseFile(SongFile);
- end;
-end;
-
-
-function TSong.AnalyseXML(): boolean;
-begin
- Result := False;
-
- //Reset LineNo
- FileLineNo := 0;
-
- //Clear old Song Header
- self.clear;
-
- //Read Header
- Result := self.ReadXMLHeader( FileName );
-
-end;
-
-end.
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
deleted file mode 100644
index 710cd44f..00000000
--- a/Game/Code/Classes/USongs.pas
+++ /dev/null
@@ -1,806 +0,0 @@
-unit USongs;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-{$IFDEF DARWIN}
- {$IFDEF DEBUG}
- {$DEFINE USE_PSEUDO_THREAD}
- {$ENDIF}
-{$ENDIF}
-
-uses
- {$IFDEF MSWINDOWS}
- Windows,
- DirWatch,
- {$ELSE}
- {$IFNDEF DARWIN}
- syscall,
- {$ENDIF}
- baseunix,
- UnixType,
- {$ENDIF}
- SysUtils,
- Classes,
- UPlatform,
- ULog,
- UTexture,
- UCommon,
- {$IFDEF DARWIN}
- cthreads,
- {$ENDIF}
- {$IFDEF USE_PSEUDO_THREAD}
- PseudoThread,
- {$ENDIF}
- USong,
- UCatCovers;
-
-type
-
- TBPM = record
- BPM: real;
- StartBeat: real;
- end;
-
- TScore = record
- Name: widestring;
- Score: integer;
- Length: string;
- end;
-
- {$IFDEF USE_PSEUDO_THREAD}
- TSongs = class( TPseudoThread )
- {$ELSE}
- TSongs = class( TThread )
- {$ENDIF}
- private
- fNotify, fWatch : longint;
- fParseSongDirectory : boolean;
- fProcessing : boolean;
- {$ifdef MSWINDOWS}
- fDirWatch : TDirectoryWatch;
- {$endif}
- procedure int_LoadSongList;
- procedure DoDirChanged(Sender: TObject);
- protected
- procedure Execute; override;
- public
- SongList : TList; // array of songs
- Selected : integer; // selected song index
- constructor Create();
- destructor Destroy(); override;
-
-
- procedure LoadSongList; // load all songs
- procedure BrowseDir(Dir: widestring); // should return number of songs in the future
- procedure BrowseTXTFiles(Dir: widestring);
- procedure BrowseXMLFiles(Dir: widestring);
- procedure Sort(Order: integer);
- function FindSongFile(Dir, Mask: widestring): widestring;
- property Processing : boolean read fProcessing;
- end;
-
-
- TCatSongs = class
- Song: array of TSong; // array of categories with songs
- Selected: integer; // selected song index
- Order: integer; // order type (0=title)
- CatNumShow: integer; // Category Number being seen
- CatCount: integer; //Number of Categorys
-
- procedure SortSongs();
- procedure Refresh; // refreshes arrays by recreating them from Songs array
- procedure ShowCategory(Index: integer); // expands all songs in category
- procedure HideCategory(Index: integer); // hides all songs in category
- procedure ClickCategoryButton(Index: integer); // uses ShowCategory and HideCategory when needed
- procedure ShowCategoryList; //Hides all Songs And Show the List of all Categorys
- function FindNextVisible(SearchFrom:integer): integer; //Find Next visible Song
- function VisibleSongs: integer; // returns number of visible songs (for tabs)
- function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
-
- function SetFilter(FilterStr: string; const fType: Byte): Cardinal;
- end;
-
-var
- Songs: TSongs; // all songs
- CatSongs: TCatSongs; // categorized songs
-
-const
- IN_ACCESS = $00000001; //* File was accessed */
- IN_MODIFY = $00000002; //* File was modified */
- IN_ATTRIB = $00000004; //* Metadata changed */
- IN_CLOSE_WRITE = $00000008; //* Writtable file was closed */
- IN_CLOSE_NOWRITE = $00000010; //* Unwrittable file closed */
- IN_OPEN = $00000020; //* File was opened */
- IN_MOVED_FROM = $00000040; //* File was moved from X */
- IN_MOVED_TO = $00000080; //* File was moved to Y */
- IN_CREATE = $00000100; //* Subfile was created */
- IN_DELETE = $00000200; //* Subfile was deleted */
- IN_DELETE_SELF = $00000400; //* Self was deleted */
-
-
-implementation
-
-uses StrUtils,
- UGraphic,
- UCovers,
- UFiles,
- UMain,
- UIni;
-
-constructor TSongs.Create();
-begin
- // do not start thread BEFORE initialization (suspended = true)
- inherited Create(true);
- Self.FreeOnTerminate := true;
-
- SongList := TList.Create();
-
- // FIXME: threaded loading does not work this way.
- // It will just cause crashes but nothing else at the moment.
- (*
- {$ifdef MSWINDOWS}
- fDirWatch := TDirectoryWatch.create(nil);
- fDirWatch.OnChange := DoDirChanged;
- fDirWatch.Directory := SongPath;
- fDirWatch.WatchSubDirs := true;
- fDirWatch.active := true;
- {$ENDIF}
-
- // now we can start the thread
- Resume();
- *)
-
- // until it is fixed, simply load the song-list
- int_LoadSongList();
-end;
-
-destructor TSongs.Destroy();
-begin
- FreeAndNil( SongList );
- inherited;
-end;
-
-procedure TSongs.DoDirChanged(Sender: TObject);
-begin
- LoadSongList();
-end;
-
-procedure TSongs.Execute();
-var
- fChangeNotify : THandle;
-begin
-{$IFDEF USE_PSEUDO_THREAD}
- int_LoadSongList();
-{$ELSE}
- fParseSongDirectory := true;
-
- while not terminated do
- begin
-
- if fParseSongDirectory then
- begin
- Log.LogStatus('Calling int_LoadSongList', 'TSongs.Execute');
- int_LoadSongList();
- end;
-
- Suspend();
- end;
-{$ENDIF}
-end;
-
-procedure TSongs.int_LoadSongList;
-var
- I: integer;
-begin
- try
- fProcessing := true;
-
- Log.LogStatus('Searching For Songs', 'SongList');
-
- // browse directories
- for I := 0 to SongPaths.Count-1 do
- BrowseDir(SongPaths[I]);
-
- if assigned( CatSongs ) then
- CatSongs.Refresh;
-
- if assigned( CatCovers ) then
- CatCovers.Load;
-
- //if assigned( Covers ) then
- // Covers.Load;
-
- if assigned(ScreenSong) then
- begin
- ScreenSong.GenerateThumbnails();
- ScreenSong.OnShow; // refresh ScreenSong
- end;
-
- finally
- Log.LogStatus('Search Complete', 'SongList');
-
- fParseSongDirectory := false;
- fProcessing := false;
- end;
-end;
-
-
-procedure TSongs.LoadSongList;
-begin
- fParseSongDirectory := true;
- Resume();
-end;
-
-procedure TSongs.BrowseDir(Dir: widestring);
-begin
- BrowseTXTFiles(Dir);
- BrowseXMLFiles(Dir);
-end;
-
-procedure TSongs.BrowseTXTFiles(Dir: widestring);
-var
- i : integer;
- Files : TDirectoryEntryArray;
- lSong : TSong;
-begin
-
- Files := Platform.DirectoryFindFiles( Dir, '.txt', true);
-
- for i := 0 to Length(Files)-1 do
- begin
- if Files[i].IsDirectory then
- begin
- BrowseTXTFiles( Dir + Files[i].Name + PathDelim ); //Recursive Call
- end
- else
- begin
- lSong := TSong.create( Dir + Files[i].Name );
-
- if lSong.Analyse then
- SongList.add( lSong )
- else
- begin
- Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".');
- freeandnil( lSong );
- end;
-
- end;
- end;
- SetLength( Files, 0);
-
-end;
-
-procedure TSongs.BrowseXMLFiles(Dir: widestring);
-var
- i : integer;
- Files : TDirectoryEntryArray;
- lSong : TSong;
-begin
-
- Files := Platform.DirectoryFindFiles( Dir, '.xml', true);
-
- for i := 0 to Length(Files)-1 do
- begin
- if Files[i].IsDirectory then
- begin
- BrowseXMLFiles( Dir + Files[i].Name + PathDelim ); //Recursive Call
- end
- else
- begin
- lSong := TSong.create( Dir + Files[i].Name );
-
- if lSong.AnalyseXML then
- SongList.add( lSong )
- else
- begin
- Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".');
- freeandnil( lSong );
- end;
-
- end;
- end;
- SetLength( Files, 0);
-
-end;
-
-(*
- * Comparison functions for sorting
- *)
-
-function CompareByEdition(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Edition, TSong(Song2).Edition);
-end;
-
-function CompareByGenre(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Genre, TSong(Song2).Genre);
-end;
-
-function CompareByTitle(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Title, TSong(Song2).Title);
-end;
-
-function CompareByArtist(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Artist, TSong(Song2).Artist);
-end;
-
-function CompareByFolder(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Folder, TSong(Song2).Folder);
-end;
-
-function CompareByLanguage(Song1, Song2: Pointer): integer;
-begin
- Result := CompareText(TSong(Song1).Language, TSong(Song2).Language);
-end;
-
-procedure TSongs.Sort(Order: integer);
-var
- CompareFunc: TListSortCompare;
-begin
- // FIXME: what is the difference between artist and artist2, etc.?
- case Order of
- sEdition: // by edition
- CompareFunc := CompareByEdition;
- sGenre: // by genre
- CompareFunc := CompareByGenre;
- sTitle: // by title
- CompareFunc := CompareByTitle;
- sArtist: // by artist
- CompareFunc := CompareByArtist;
- sFolder: // by folder
- CompareFunc := CompareByFolder;
- sTitle2: // by title2
- CompareFunc := CompareByTitle;
- sArtist2: // by artist2
- CompareFunc := CompareByArtist;
- sLanguage: // by Language
- CompareFunc := CompareByLanguage;
- else
- Log.LogCritical('Unsupported comparison', 'TSongs.Sort');
- Exit; // suppress warning
- end; // case
-
- // Note: Do not use TList.Sort() as it uses QuickSort which is instable.
- // For example, if a list is sorted by title first and
- // by artist afterwards, the songs of an artist will not be sorted by title anymore.
- // The stable MergeSort guarantees to maintain this order.
- MergeSort(SongList, CompareFunc);
-end;
-
-function TSongs.FindSongFile(Dir, Mask: widestring): widestring;
-var
- SR: TSearchRec; // for parsing song directory
-begin
- Result := '';
- if FindFirst(Dir + Mask, faDirectory, SR) = 0 then
- begin
- Result := SR.Name;
- end; // if
- FindClose(SR);
-end;
-
-procedure TCatSongs.SortSongs();
-begin
- case Ini.Sorting of
- sEdition: begin
- Songs.Sort(sTitle);
- Songs.Sort(sArtist);
- Songs.Sort(sEdition);
- end;
- sGenre: begin
- Songs.Sort(sTitle);
- Songs.Sort(sArtist);
- Songs.Sort(sGenre);
- end;
- sLanguage: begin
- Songs.Sort(sTitle);
- Songs.Sort(sArtist);
- Songs.Sort(sLanguage);
- end;
- sFolder: begin
- Songs.Sort(sTitle);
- Songs.Sort(sArtist);
- Songs.Sort(sFolder);
- end;
- sTitle: begin
- Songs.Sort(sTitle);
- end;
- sArtist: begin
- Songs.Sort(sTitle);
- Songs.Sort(sArtist);
- end;
- sTitle2: begin
- Songs.Sort(sArtist2);
- Songs.Sort(sTitle2);
- end;
- sArtist2: begin
- Songs.Sort(sTitle2);
- Songs.Sort(sArtist2);
- end;
- end; // case
-end;
-
-procedure TCatSongs.Refresh;
-var
- SongIndex: integer;
- CurSong: TSong;
- CatIndex: integer; // index of current song in Song
- Letter: char; // current letter for sorting using letter
- CurCategory: string; // current edition for sorting using edition, genre etc.
- Order: integer; // number used for ordernum
- LetterTmp: char;
- CatNumber: integer; // Number of Song in Category
-
- procedure AddCategoryButton(const CategoryName: string);
- var
- PrevCatBtnIndex: integer;
- begin
- Inc(Order);
- CatIndex := Length(Song);
- SetLength(Song, CatIndex+1);
- Song[CatIndex] := TSong.Create();
- Song[CatIndex].Artist := '[' + CategoryName + ']';
- Song[CatIndex].Main := true;
- Song[CatIndex].OrderTyp := 0;
- Song[CatIndex].OrderNum := Order;
- Song[CatIndex].Cover := CatCovers.GetCover(Ini.Sorting, CategoryName);
- Song[CatIndex].Visible := true;
-
- // set number of songs in previous category
- PrevCatBtnIndex := CatIndex - CatNumber - 1;
- if ((PrevCatBtnIndex >= 0) and Song[PrevCatBtnIndex].Main) then
- Song[PrevCatBtnIndex].CatNumber := CatNumber;
-
- CatNumber := 0;
- end;
-
-begin
- CatNumShow := -1;
-
- SortSongs();
-
- CurCategory := '';
- Order := 0;
- CatNumber := 0;
-
- // Note: do NOT set Letter to ' ', otherwise no category-button will be
- // created for songs beginning with ' ' if songs of this category exist.
- // TODO: trim song-properties so ' ' will not occur as first chararcter.
- Letter := #0;
-
- // clear song-list
- for SongIndex := 0 to Songs.SongList.Count-1 do
- begin
- // free category buttons
- // Note: do NOT delete songs, they are just references to Songs.SongList entries
- CurSong := TSong(Songs.SongList[SongIndex]);
- if (CurSong.Main) then
- CurSong.Free;
- end;
- SetLength(Song, 0);
-
- for SongIndex := 0 to Songs.SongList.Count-1 do
- begin
- CurSong := TSong(Songs.SongList[SongIndex]);
- // if tabs are on, add section buttons for each new section
- if (Ini.Tabs = 1) then
- begin
- if (Ini.Sorting = sEdition) and
- (CompareText(CurCategory, CurSong.Edition) <> 0) then
- begin
- CurCategory := CurSong.Edition;
-
- // TODO: remove this block if it is not needed anymore
- {
- if CurSection = 'Singstar Part 2' then CoverName := 'Singstar';
- if CurSection = 'Singstar German' then CoverName := 'Singstar';
- if CurSection = 'Singstar Spanish' then CoverName := 'Singstar';
- if CurSection = 'Singstar Italian' then CoverName := 'Singstar';
- if CurSection = 'Singstar French' then CoverName := 'Singstar';
- if CurSection = 'Singstar 80s Polish' then CoverName := 'Singstar 80s';
- }
-
- // add Category Button
- AddCategoryButton(CurCategory);
- end
-
- else if (Ini.Sorting = sGenre) and
- (CompareText(CurCategory, CurSong.Genre) <> 0) then
- begin
- CurCategory := CurSong.Genre;
- // add Genre Button
- AddCategoryButton(CurCategory);
- end
-
- else if (Ini.Sorting = sLanguage) and
- (CompareText(CurCategory, CurSong.Language) <> 0) then
- begin
- CurCategory := CurSong.Language;
- // add Language Button
- AddCategoryButton(CurCategory);
- end
-
- else if (Ini.Sorting = sTitle) and
- (Length(CurSong.Title) >= 1) and
- (Letter <> UpperCase(CurSong.Title)[1]) then
- begin
- Letter := Uppercase(CurSong.Title)[1];
- // add a letter Category Button
- AddCategoryButton(Letter);
- end
-
- else if (Ini.Sorting = sArtist) and
- (Length(CurSong.Artist) >= 1) and
- (Letter <> UpperCase(CurSong.Artist)[1]) then
- begin
- Letter := UpperCase(CurSong.Artist)[1];
- // add a letter Category Button
- AddCategoryButton(Letter);
- end
-
- else if (Ini.Sorting = sFolder) and
- (CompareText(CurCategory, CurSong.Folder) <> 0) then
- begin
- CurCategory := CurSong.Folder;
- // add folder tab
- AddCategoryButton(CurCategory);
- end
-
- else if (Ini.Sorting = sTitle2) and
- (Length(CurSong.Title) >= 1) then
- begin
- // pack all numbers into a category named '#'
- if (CurSong.Title[1] >= '0') and (CurSong.Title[1] <= '9') then
- LetterTmp := '#'
- else
- LetterTmp := UpperCase(CurSong.Title)[1];
-
- if (Letter <> LetterTmp) then
- begin
- Letter := LetterTmp;
- // add a letter Category Button
- AddCategoryButton(Letter);
- end;
- end
-
- else if (Ini.Sorting = sArtist2) and
- (Length(CurSong.Artist)>=1) then
- begin
- // pack all numbers into a category named '#'
- if (CurSong.Artist[1] >= '0') and (CurSong.Artist[1] <= '9') then
- LetterTmp := '#'
- else
- LetterTmp := UpperCase(CurSong.Artist)[1];
-
- if (Letter <> LetterTmp) then
- begin
- Letter := LetterTmp;
- // add a letter Category Button
- AddCategoryButton(Letter);
- end;
- end;
- end;
-
- CatIndex := Length(Song);
- SetLength(Song, CatIndex+1);
-
- Inc(CatNumber); // increase number of songs in category
-
- // copy reference to current song
- Song[CatIndex] := CurSong;
-
- // set song's category info
- CurSong.OrderNum := Order; // assigns category
- CurSong.CatNumber := CatNumber;
-
- if (Ini.Tabs = 0) then
- CurSong.Visible := true
- else if (Ini.Tabs = 1) then
- CurSong.Visible := false;
-
- {
- if (Ini.Tabs = 1) and (Order = 1) then
- begin
- //open first tab
- CurSong.Visible := true;
- end;
- CurSong.Visible := true;
- }
- end;
-
- // set CatNumber of last category
- if (Ini.Tabs_at_startup = 1) and (High(Song) >= 1) then
- begin
- // set number of songs in previous category
- SongIndex := CatIndex - CatNumber;
- if ((SongIndex >= 0) and Song[SongIndex].Main) then
- Song[SongIndex].CatNumber := CatNumber;
- end;
-
- // update number of categories
- CatCount := Order;
-end;
-
-procedure TCatSongs.ShowCategory(Index: integer);
-var
- S: integer; // song
-begin
- CatNumShow := Index;
- for S := 0 to high(CatSongs.Song) do
- begin
-{
- if (CatSongs.Song[S].OrderNum = Index) and (not CatSongs.Song[S].Main) then
- CatSongs.Song[S].Visible := true
- else
- CatSongs.Song[S].Visible := false;
-}
-// KMS: This should be the same, but who knows :-)
- CatSongs.Song[S].Visible := ( (CatSongs.Song[S].OrderNum = Index) and (not CatSongs.Song[S].Main) );
- end;
-end;
-
-procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category
-var
- S: integer; // song
-begin
- for S := 0 to high(CatSongs.Song) do
- begin
- if not CatSongs.Song[S].Main then
- CatSongs.Song[S].Visible := false // hides all at now
- end;
-end;
-
-procedure TCatSongs.ClickCategoryButton(Index: integer);
-var
- Num, S: integer;
-begin
- Num := CatSongs.Song[Index].OrderNum;
- if Num <> CatNumShow then
- begin
- ShowCategory(Num);
- end
- else
- begin
- ShowCategoryList;
- end;
-end;
-
-//Hide Categorys when in Category Hack
-procedure TCatSongs.ShowCategoryList;
-var
- Num, S: integer;
-begin
- // Hide All Songs Show All Cats
- for S := 0 to high(CatSongs.Song) do
- CatSongs.Song[S].Visible := CatSongs.Song[S].Main;
- CatSongs.Selected := CatNumShow; //Show last shown Category
- CatNumShow := -1;
-end;
-//Hide Categorys when in Category Hack End
-
-//Wrong song selected when tabs on bug
-function TCatSongs.FindNextVisible(SearchFrom:integer): integer;//Find next Visible Song
-var
- I: integer;
-begin
- Result := -1;
- I := SearchFrom + 1;
- while not CatSongs.Song[I].Visible do
- begin
- Inc (I);
- if (I>high(CatSongs.Song)) then
- I := low(CatSongs.Song);
- if (I = SearchFrom) then //Make One Round and no song found->quit
- break;
- end;
-end;
-//Wrong song selected when tabs on bug End
-
-(**
- * Returns the number of visible songs.
- *)
-function TCatSongs.VisibleSongs: integer;
-var
- SongIndex: integer;
-begin
- Result := 0;
- for SongIndex := 0 to High(CatSongs.Song) do
- begin
- if (CatSongs.Song[SongIndex].Visible) then
- Inc(Result);
- end;
-end;
-
-(**
- * Returns the index of a song in the subset of all visible songs.
- * If all songs are visible, the result will be equal to the Index parameter.
- *)
-function TCatSongs.VisibleIndex(Index: integer): integer;
-var
- SongIndex: integer;
-begin
- Result := 0;
- for SongIndex := 0 to Index-1 do
- begin
- if (CatSongs.Song[SongIndex].Visible) then
- Inc(Result);
- end;
-end;
-
-function TCatSongs.SetFilter(FilterStr: string; const fType: Byte): Cardinal;
-var
- I, J: integer;
- cString: string;
- SearchStr: array of string;
-begin
- {fType: 0: All
- 1: Title
- 2: Artist}
- FilterStr := Trim(FilterStr);
- if FilterStr<>'' then
- begin
- Result := 0;
- //Create Search Array
- SetLength(SearchStr, 1);
- I := Pos (' ', FilterStr);
- while (I <> 0) do
- begin
- SetLength (SearchStr, Length(SearchStr) + 1);
- cString := Copy(FilterStr, 1, I-1);
- if (cString <> ' ') and (cString <> '') then
- SearchStr[High(SearchStr)-1] := cString;
- Delete (FilterStr, 1, I);
-
- I := Pos (' ', FilterStr);
- end;
- //Copy last Word
- if (FilterStr <> ' ') and (FilterStr <> '') then
- SearchStr[High(SearchStr)] := FilterStr;
-
- for I:=0 to High(Song) do
- begin
- if not Song[i].Main then
- begin
- case fType of
- 0: cString := Song[I].Artist + ' ' + Song[i].Title + ' ' + Song[i].Folder;
- 1: cString := Song[I].Title;
- 2: cString := Song[I].Artist;
- end;
- Song[i].Visible:=True;
- //Look for every Searched Word
- for J := 0 to High(SearchStr) do
- begin
- Song[i].Visible := Song[i].Visible and AnsiContainsText(cString, SearchStr[J])
- end;
- if Song[i].Visible then
- Inc(Result);
- end
- else
- Song[i].Visible:=False;
- end;
- CatNumShow := -2;
- end
- else
- begin
- for i:=0 to High(Song) do
- begin
- Song[i].Visible := (Ini.Tabs=1) = Song[i].Main;
- CatNumShow := -1;
- end;
- Result := 0;
- end;
-end;
-
-// -----------------------------------------------------------------------------
-
-end.
diff --git a/Game/Code/Classes/UTextClasses.pas b/Game/Code/Classes/UTextClasses.pas
deleted file mode 100644
index 9a12e1f5..00000000
--- a/Game/Code/Classes/UTextClasses.pas
+++ /dev/null
@@ -1,60 +0,0 @@
-unit UTextClasses;
-
-interface
-
-{$I switches.inc}
-
-uses
- gl,
- SDL,
- UTexture,
- Classes,
-// SDL_ttf,
- ULog;
-
-{
-// okay i just outline what should be here, so we can create a nice and clean implementation of sdl_ttf
-// based up on this uml: http://jnr.sourceforge.net/fusion_images/www_FRS.png
-// thanks to Bob Pendelton and Koshmaar!
-// (1) let's start with a glyph, this represents one character in a word
-
-type
- TGlyph = record
- character : Char; // unsigned char, uchar is something else in delphi
- glyphsSolid[8] : GlyphTexture; // fast, but not that
- glyphsBlended[8] : GlyphTexture; // slower than solid, but it look's more pretty
-
-//this class has a method, which should be a deconstructor (mog is on his way to understand the principles of oop :P)
- deconstructor procedure ReleaseTextures();
-end;
-
-// (2) okay, we now need the stuff that's even beneath this glyph - we're right at the birth of text in here :P
-
- GlyphTexture = record
- textureID : GLuint; // we need this for caching the letters, if the texture wasn't created before create it, should be very fast because of this one
- width,
- height : Cardinal;
- charWidth,
- charHeight : Integer;
- advance : Integer; // don't know yet for what this one is
-}
-
-{
-// after the glyph is done, we now start to build whole words - this one is pretty important, and does most of the work we need
- TGlyphsContainer = record
- glyphs array of TGlyph;
- FontName array of string;
- refCount : uChar; // unsigned char, uchar is something else in delphi
- font : PTTF_font;
- size,
- lineSkip : Cardinal; // vertical distance between multi line text output
- descent : Integer;
-
-
-
-}
-
-
-implementation
-
-end.
diff --git a/Game/Code/Classes/UTexture.pas b/Game/Code/Classes/UTexture.pas
deleted file mode 100644
index 4879760a..00000000
--- a/Game/Code/Classes/UTexture.pas
+++ /dev/null
@@ -1,525 +0,0 @@
-unit UTexture;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- gl,
- glu,
- glext,
- Classes,
- SysUtils,
- UCommon,
- SDL,
- SDL_Image;
-
-type
- PTexture = ^TTexture;
- TTexture = record
- TexNum: GLuint;
- X: real;
- Y: real;
- Z: real;
- W: real;
- H: real;
- ScaleW: real; // for dynamic scalling while leaving width constant
- ScaleH: real; // for dynamic scalling while leaving height constant
- Rot: real; // 0 - 2*pi
- Int: real; // intensity
- ColR: real;
- ColG: real;
- ColB: real;
- TexW: real; // percentage of width to use [0..1]
- TexH: real; // percentage of height to use [0..1]
- TexX1: real;
- TexY1: real;
- TexX2: real;
- TexY2: real;
- Alpha: real;
- Name: string; // experimental for handling cache images. maybe it's useful for dynamic skins
- end;
-
-type
- TTextureType = (
- TEXTURE_TYPE_PLAIN, // Plain (alpha = 1)
- TEXTURE_TYPE_TRANSPARENT, // Alpha is used
- TEXTURE_TYPE_COLORIZED // Alpha is used; Hue of the HSV color-model will be replaced by a new value
- );
-
-const
- TextureTypeStr: array[TTextureType] of string = (
- 'Plain',
- 'Transparent',
- 'Colorized'
- );
-
-function TextureTypeToStr(TexType: TTextureType): string;
-function ParseTextureType(const TypeStr: string; Default: TTextureType): TTextureType;
-
-procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: TTextureType);
-
-type
- PTextureEntry = ^TTextureEntry;
- TTextureEntry = record
- Name: string;
- Typ: TTextureType;
- Color: Cardinal;
-
- // we use normal TTexture, it's easier to implement and if needed - we copy ready data
- Texture: TTexture; // Full-size texture
- TextureCache: TTexture; // Thumbnail texture
- end;
-
- TTextureDatabase = class
- private
- Texture: array of TTextureEntry;
- public
- procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
- function FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
- end;
-
- TTextureUnit = class
- private
- TextureDatabase: TTextureDatabase;
- public
- Limit: integer;
-
- procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean = false); overload;
- procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean = false); overload;
- function GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean = false): TTexture; overload;
- function GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean = false): TTexture; overload;
- function LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload;
- function LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload;
- function LoadTexture(const Identifier: string): TTexture; overload;
- function CreateTexture(Data: PChar; const Name: string; Width, Height: word; BitsPerPixel: byte): TTexture;
- procedure UnloadTexture(const Name: string; Typ: TTextureType; FromCache: boolean); overload;
- procedure UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean); overload;
- //procedure FlushTextureDatabase();
-
- constructor Create;
- destructor Destroy; override;
- end;
-
-var
- Texture: TTextureUnit;
-
-implementation
-
-uses
- DateUtils,
- StrUtils,
- Math,
- ULog,
- UCovers,
- UThemes,
- UImage;
-
-procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: TTextureType);
-var
- TempSurface: PSDL_Surface;
- NeededPixFmt: PSDL_Pixelformat;
-begin
- if (Typ = TEXTURE_TYPE_PLAIN) then
- NeededPixFmt := @PixelFmt_RGB
- else if (Typ = TEXTURE_TYPE_TRANSPARENT) or
- (Typ = TEXTURE_TYPE_COLORIZED) then
- NeededPixFmt := @PixelFmt_RGBA
- else
- NeededPixFmt := @PixelFmt_RGB;
-
- if not PixelformatEquals(TexSurface^.format, NeededPixFmt) then
- begin
- TempSurface := TexSurface;
- TexSurface := SDL_ConvertSurface(TempSurface, NeededPixFmt, SDL_SWSURFACE);
- SDL_FreeSurface(TempSurface);
- end;
-end;
-
-{ TTextureDatabase }
-
-procedure TTextureDatabase.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
-var
- TextureIndex: integer;
-begin
- TextureIndex := FindTexture(Tex.Name, Typ, Color);
- if (TextureIndex = -1) then
- begin
- TextureIndex := Length(Texture);
- SetLength(Texture, TextureIndex+1);
-
- Texture[TextureIndex].Name := Tex.Name;
- Texture[TextureIndex].Typ := Typ;
- Texture[TextureIndex].Color := Color;
- end;
-
- if (Cache) then
- Texture[TextureIndex].TextureCache := Tex
- else
- Texture[TextureIndex].Texture := Tex;
-end;
-
-function TTextureDatabase.FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
-var
- TextureIndex: integer;
- CurrentTexture: PTextureEntry;
-begin
- Result := -1;
- for TextureIndex := 0 to High(Texture) do
- begin
- CurrentTexture := @Texture[TextureIndex];
- if (CurrentTexture.Name = Name) and
- (CurrentTexture.Typ = Typ) then
- begin
- // colorized textures must match in their color too
- if (CurrentTexture.Typ <> TEXTURE_TYPE_COLORIZED) or
- (CurrentTexture.Color = Color) then
- begin
- Result := TextureIndex;
- Break;
- end;
- end;
- end;
-end;
-
-
-{ TTextureUnit }
-
-constructor TTextureUnit.Create;
-begin
- inherited Create;
- TextureDatabase := TTextureDatabase.Create;
-end;
-
-destructor TTextureUnit.Destroy;
-begin
- TextureDatabase.Free;
- inherited Destroy;
-end;
-
-
-procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean);
-begin
- TextureDatabase.AddTexture(Tex, Typ, 0, Cache);
-end;
-
-procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
-begin
- TextureDatabase.AddTexture(Tex, Typ, Color, Cache);
-end;
-
-function TTextureUnit.LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture;
-begin
- // FIXME: what is the FromRegistry parameter supposed to do?
- Result := LoadTexture(Identifier, Typ, Col);
-end;
-
-function TTextureUnit.LoadTexture(const Identifier: string): TTexture;
-begin
- Result := LoadTexture(Identifier, TEXTURE_TYPE_PLAIN, 0);
-end;
-
-function TTextureUnit.LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture;
-var
- TexSurface: PSDL_Surface;
- MipmapSurface: PSDL_Surface;
- newWidth, newHeight: Cardinal;
- oldWidth, oldHeight: Cardinal;
- ActTex: GLuint;
-begin
- // zero texture data
- FillChar(Result, SizeOf(Result), 0);
-
- // load texture data into memory
- TexSurface := LoadImage(Identifier);
- if not assigned(TexSurface) then
- begin
- Log.LogError('Could not load texture: "' + Identifier +' '+ TextureTypeToStr(Typ) +'"',
- 'TTextureUnit.LoadTexture');
- Exit;
- end;
-
- // convert pixel format as needed
- AdjustPixelFormat(TexSurface, Typ);
-
- // adjust texture size (scale down, if necessary)
- newWidth := TexSurface.W;
- newHeight := TexSurface.H;
-
- if (newWidth > Limit) then
- newWidth := Limit;
-
- if (newHeight > Limit) then
- newHeight := Limit;
-
- if (TexSurface.W > newWidth) or (TexSurface.H > newHeight) then
- ScaleImage(TexSurface, newWidth, newHeight);
-
- // now we might colorize the whole thing
- if (Typ = TEXTURE_TYPE_COLORIZED) then
- ColorizeImage(TexSurface, Col);
-
- // save actual dimensions of our texture
- oldWidth := newWidth;
- oldHeight := newHeight;
-
- // make texture dimensions be powers of 2
- newWidth := Round(Power(2, Ceil(Log2(newWidth))));
- newHeight := Round(Power(2, Ceil(Log2(newHeight))));
- if (newHeight <> oldHeight) or (newWidth <> oldWidth) then
- FitImage(TexSurface, newWidth, newHeight);
-
- // at this point we have the image in memory...
- // scaled to be at most 1024x1024 pixels large
- // scaled so that dimensions are powers of 2
- // and converted to either RGB or RGBA
-
- // if we got a Texture of Type Plain, Transparent or Colorized,
- // then we're done manipulating it
- // and could now create our openGL texture from it
-
- // prepare OpenGL texture
- glGenTextures(1, @ActTex);
-
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- // load data into gl texture
- if (Typ = TEXTURE_TYPE_TRANSPARENT) or
- (Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- glTexImage2D(GL_TEXTURE_2D, 0, 4, newWidth, newHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, TexSurface.pixels);
- end
- else //if Typ = TEXTURE_TYPE_PLAIN then
- begin
- glTexImage2D(GL_TEXTURE_2D, 0, 3, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, TexSurface.pixels);
- end;
-
- // setup texture struct
- with Result do
- begin
- X := 0;
- Y := 0;
- Z := 0;
- W := 0;
- H := 0;
- ScaleW := 1;
- ScaleH := 1;
- Rot := 0;
- TexNum := ActTex;
- TexW := oldWidth / newWidth;
- TexH := oldHeight / newHeight;
-
- Int := 1;
- ColR := 1;
- ColG := 1;
- ColB := 1;
- Alpha := 1;
-
- // new test - default use whole texure, taking TexW and TexH as const and changing these
- TexX1 := 0;
- TexY1 := 0;
- TexX2 := 1;
- TexY2 := 1;
-
- Name := Identifier;
- end;
-
- SDL_FreeSurface(TexSurface);
-end;
-
-function TTextureUnit.GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean): TTexture;
-begin
- Result := GetTexture(Name, Typ, 0, FromCache);
-end;
-
-function TTextureUnit.GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean): TTexture;
-var
- TextureIndex: integer;
- CoverIndex: integer;
-begin
- if (Name = '') then
- begin
- // zero texture data
- FillChar(Result, SizeOf(Result), 0);
- Exit;
- end;
-
- if (FromCache) then
- begin
- (*
- // use cache texture
- CoverIndex := Covers.FindCover(Name);
-
- if TextureDatabase.Texture[TextureIndex].TextureCache.TexNum = 0 then
- begin
- // load texture
- Covers.PrepareData(Name);
- TextureDatabase.Texture[TextureIndex].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[CoverIndex].Width, Covers.Cover[CoverIndex].Height, 24);
- end;
- *)
-
- // use texture
- TextureIndex := TextureDatabase.FindTexture(Name, Typ, Col);
- if (TextureIndex > -1) then
- Result := TextureDatabase.Texture[TextureIndex].TextureCache;
- Exit;
- end;
-
- // find texture entry in database
- TextureIndex := TextureDatabase.FindTexture(Name, Typ, Col);
- if (TextureIndex = -1) then
- begin
- // create texture entry in database
- TextureIndex := Length(TextureDatabase.Texture);
- SetLength(TextureDatabase.Texture, TextureIndex+1);
-
- TextureDatabase.Texture[TextureIndex].Name := Name;
- TextureDatabase.Texture[TextureIndex].Typ := Typ;
- TextureDatabase.Texture[TextureIndex].Color := Col;
-
- // inform database that no textures have been loaded into memory
- TextureDatabase.Texture[TextureIndex].Texture.TexNum := 0;
- TextureDatabase.Texture[TextureIndex].TextureCache.TexNum := 0;
- end;
-
- // load full texture
- if (TextureDatabase.Texture[TextureIndex].Texture.TexNum = 0) then
- TextureDatabase.Texture[TextureIndex].Texture := LoadTexture(false, Name, Typ, Col);
-
- // use texture
- Result := TextureDatabase.Texture[TextureIndex].Texture;
-end;
-
-function TTextureUnit.CreateTexture(Data: PChar; const Name: string; Width, Height: word; BitsPerPixel: byte): TTexture;
-var
- Error: integer;
- ActTex: GLuint;
-begin
- glGenTextures(1, @ActTex); // ActText = new texture number
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, 3, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
-
- {
- if Mipmapping then
- begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
- if Error > 0 then
- Log.LogError('gluBuild2DMipmaps() failed', 'TTextureUnit.CreateTexture');
- end;
- }
-
- Result.X := 0;
- Result.Y := 0;
- Result.Z := 0;
- Result.W := 0;
- Result.H := 0;
- Result.ScaleW := 1;
- Result.ScaleH := 1;
- Result.Rot := 0;
- Result.TexNum := ActTex;
- Result.TexW := 1;
- Result.TexH := 1;
-
- Result.Int := 1;
- Result.ColR := 1;
- Result.ColG := 1;
- Result.ColB := 1;
- Result.Alpha := 1;
-
- // new test - default use whole texure, taking TexW and TexH as const and changing these
- Result.TexX1 := 0;
- Result.TexY1 := 0;
- Result.TexX2 := 1;
- Result.TexY2 := 1;
-
- Result.Name := Name;
-end;
-
-procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; FromCache: boolean);
-begin
- UnloadTexture(Name, Typ, 0, FromCache);
-end;
-
-procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean);
-var
- T: integer;
- TexNum: GLuint;
-begin
- T := TextureDatabase.FindTexture(Name, Typ, Col);
-
- if not FromCache then
- begin
- TexNum := TextureDatabase.Texture[T].Texture.TexNum;
- if TexNum > 0 then
- begin
- glDeleteTextures(1, PGLuint(@TexNum));
- TextureDatabase.Texture[T].Texture.TexNum := 0;
- //Log.LogError('Unload texture no '+IntToStr(TexNum));
- end;
- end
- else
- begin
- TexNum := TextureDatabase.Texture[T].TextureCache.TexNum;
- if TexNum > 0 then
- begin
- glDeleteTextures(1, @TexNum);
- TextureDatabase.Texture[T].TextureCache.TexNum := 0;
- //Log.LogError('Unload texture cache no '+IntToStr(TexNum));
- end;
- end;
-end;
-
-(* This needs some work
-procedure TTextureUnit.FlushTextureDatabase();
-var
- i: integer;
- Tex: ^TTexture;
-begin
- for i := 0 to High(TextureDatabase.Texture) do
- begin
- // only delete non-cached entries
- if (TextureDatabase.Texture[i].Texture.TexNum > 0) then
- begin
- Tex := @TextureDatabase.Texture[i].Texture;
- glDeleteTextures(1, PGLuint(Tex^.TexNum));
- Tex^.TexNum := 0;
- end;
- end;
-end;
-*)
-
-function TextureTypeToStr(TexType: TTextureType): string;
-begin
- Result := TextureTypeStr[TexType];
-end;
-
-function ParseTextureType(const TypeStr: string; Default: TTextureType): TTextureType;
-var
- TexType: TTextureType;
- UpCaseStr: string;
-begin
- UpCaseStr := UpperCase(TypeStr);
- for TexType := Low(TextureTypeStr) to High(TextureTypeStr) do
- begin
- if (UpCaseStr = UpperCase(TextureTypeStr[TexType])) then
- begin
- Result := TexType;
- Exit;
- end;
- end;
- Log.LogWarn('Unknown texture-type: "' + TypeStr + '"', 'ParseTextureType');
- Result := TEXTURE_TYPE_PLAIN;
-end;
-
-end.
diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas
deleted file mode 100644
index fca75c24..00000000
--- a/Game/Code/Classes/UThemes.pas
+++ /dev/null
@@ -1,2234 +0,0 @@
-unit UThemes;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- ULog,
- IniFiles,
- SysUtils,
- Classes,
- UTexture;
-
-type
- TRGB = record
- R: single;
- G: single;
- B: single;
- end;
-
- TRGBA = record
- R, G, B, A: Double;
- end;
-
- TThemeBackground = record
- Tex: string;
- end;
-
- TThemeStatic = record
- X: integer;
- Y: integer;
- Z: real;
- W: integer;
- H: integer;
- Color: string;
- ColR: real;
- ColG: real;
- ColB: real;
- Tex: string;
- Typ: TTextureType;
- TexX1: real;
- TexY1: real;
- TexX2: real;
- TexY2: real;
- //Reflection
- Reflection: boolean;
- Reflectionspacing: Real;
- end;
- AThemeStatic = array of TThemeStatic;
-
- TThemeText = record
- X: integer;
- Y: integer;
- W: integer;
- Z: real;
- Color: string;
- ColR: real;
- ColG: real;
- ColB: real;
- Font: integer;
- Size: integer;
- Align: integer;
- Text: string;
- //Reflection
- Reflection: boolean;
- ReflectionSpacing: Real;
- end;
- AThemeText = array of TThemeText;
-
- TThemeButton = record
- Text: AThemeText;
- X: integer;
- Y: integer;
- Z: Real;
- W: integer;
- H: integer;
- Color: string;
- ColR: real;
- ColG: real;
- ColB: real;
- Int: real;
- DColor: string;
- DColR: real;
- DColG: real;
- DColB: real;
- DInt: real;
- Tex: string;
- Typ: TTextureType;
-
- Visible: Boolean;
-
- //Reflection Mod
- Reflection: boolean;
- Reflectionspacing: Real;
- //Fade Mod
- SelectH: integer;
- SelectW: integer;
- Fade: boolean;
- FadeText: boolean;
- DeSelectReflectionspacing : Real;
- FadeTex: string;
- FadeTexPos: integer;
-
- //Button Collection Mod
- Parent: Byte; //Number of the Button Collection this Button is assigned to. IF 0: No Assignement
- end;
-
- //Button Collection Mod
- TThemeButtonCollection = record
- Style: TThemeButton;
- ChildCount: Byte; //No of assigned Childs
- FirstChild: Byte; //No of Child on whose Interaction Position the Button should be
- end;
-
- AThemeButtonCollection = array of TThemeButtonCollection;
- PAThemeButtonCollection = ^AThemeButtonCollection;
-
- TThemeSelectSlide = record
- Tex: string;
- TexSBG: string;
- X: integer;
- Y: integer;
- W: integer;
- H: integer;
- Z: real;
-
- TextSize: integer;
-
- //SBGW Mod
- SBGW: integer;
-
- Text: string;
- ColR, ColG, ColB, Int: real;
- DColR, DColG, DColB, DInt: real;
- TColR, TColG, TColB, TInt: real;
- TDColR, TDColG, TDColB, TDInt: real;
- SBGColR, SBGColG, SBGColB, SBGInt: real;
- SBGDColR, SBGDColG, SBGDColB, SBGDInt: real;
- STColR, STColG, STColB, STInt: real;
- STDColR, STDColG, STDColB, STDInt: real;
- SkipX: integer;
- end;
-
- PThemeBasic = ^TThemeBasic;
- TThemeBasic = class
- Background: TThemeBackground;
- Text: AThemeText;
- Static: AThemeStatic;
-
- //Button Collection Mod
- ButtonCollection: AThemeButtonCollection;
- end;
-
- TThemeLoading = class(TThemeBasic)
- StaticAnimation: TThemeStatic;
- TextLoading: TThemeText;
- end;
-
- TThemeMain = class(TThemeBasic)
- ButtonSolo: TThemeButton;
- ButtonMulti: TThemeButton;
- ButtonStat: TThemeButton;
- ButtonEditor: TThemeButton;
- ButtonOptions: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- TextDescriptionLong: TThemeText;
- Description: array[0..5] of string;
- DescriptionLong: array[0..5] of string;
- end;
-
- TThemeName = class(TThemeBasic)
- ButtonPlayer: array[1..6] of TThemeButton;
- end;
-
- TThemeLevel = class(TThemeBasic)
- ButtonEasy: TThemeButton;
- ButtonMedium: TThemeButton;
- ButtonHard: TThemeButton;
- end;
-
- TThemeSong = class(TThemeBasic)
- TextArtist: TThemeText;
- TextTitle: TThemeText;
- TextNumber: TThemeText;
-
- //Video Icon Mod
- VideoIcon: TThemeStatic;
-
- //Show Cat in TopLeft Mod
- TextCat: TThemeText;
- StaticCat: TThemeStatic;
-
- //Cover Mod
- Cover: record
- Reflections: Boolean;
- X: Integer;
- Y: Integer;
- Z: Integer;
- W: Integer;
- H: Integer;
- Style: Integer;
- end;
-
- //Equalizer Mod
- Equalizer: record
- Visible: Boolean;
- Direction: Boolean;
- Alpha: real;
- X: Integer;
- Y: Integer;
- Z: Real;
- W: Integer;
- H: Integer;
- Space: Integer;
- Bands: Integer;
- Length: Integer;
- ColR, ColG, ColB: Real;
- end;
-
-
- //Party and Non Party specific Statics and Texts
- StaticParty: AThemeStatic;
- TextParty: AThemeText;
-
- StaticNonParty: AThemeStatic;
- TextNonParty: AThemeText;
-
- //Party Mode
- StaticTeam1Joker1: TThemeStatic;
- StaticTeam1Joker2: TThemeStatic;
- StaticTeam1Joker3: TThemeStatic;
- StaticTeam1Joker4: TThemeStatic;
- StaticTeam1Joker5: TThemeStatic;
- StaticTeam2Joker1: TThemeStatic;
- StaticTeam2Joker2: TThemeStatic;
- StaticTeam2Joker3: TThemeStatic;
- StaticTeam2Joker4: TThemeStatic;
- StaticTeam2Joker5: TThemeStatic;
- StaticTeam3Joker1: TThemeStatic;
- StaticTeam3Joker2: TThemeStatic;
- StaticTeam3Joker3: TThemeStatic;
- StaticTeam3Joker4: TThemeStatic;
- StaticTeam3Joker5: TThemeStatic;
-
-
- end;
-
- TThemeSing = class(TThemeBasic)
-
- //TimeBar mod
- StaticTimeProgress: TThemeStatic;
- TextTimeText : TThemeText;
- //eoa TimeBar mod
-
- StaticP1: TThemeStatic;
- TextP1: TThemeText;
- StaticP1ScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1Score: TThemeText;
-
- //moveable singbar mod
- StaticP1SingBar: TThemeStatic;
- StaticP1ThreePSingBar: TThemeStatic;
- StaticP1TwoPSingBar: TThemeStatic;
- StaticP2RSingBar: TThemeStatic;
- StaticP2MSingBar: TThemeStatic;
- StaticP3SingBar: TThemeStatic;
- //eoa moveable singbar
-
- //added for ps3 skin
- //game in 2/4 player modi
- StaticP1TwoP: TThemeStatic;
- StaticP1TwoPScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1TwoP: TThemeText;
- TextP1TwoPScore: TThemeText;
- //game in 3/6 player modi
- StaticP1ThreeP: TThemeStatic;
- StaticP1ThreePScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1ThreeP: TThemeText;
- TextP1ThreePScore: TThemeText;
- //eoa
-
- StaticP2R: TThemeStatic;
- StaticP2RScoreBG: TThemeStatic; //Static for ScoreBG
- TextP2R: TThemeText;
- TextP2RScore: TThemeText;
-
- StaticP2M: TThemeStatic;
- StaticP2MScoreBG: TThemeStatic; //Static for ScoreBG
- TextP2M: TThemeText;
- TextP2MScore: TThemeText;
-
- StaticP3R: TThemeStatic;
- StaticP3RScoreBG: TThemeStatic; //Static for ScoreBG
- TextP3R: TThemeText;
- TextP3RScore: TThemeText;
-
- //Linebonus Translations
- LineBonusText: Array [0..8] of String;
-
- //Pause Popup
- PausePopUp: TThemeStatic;
- end;
-
- TThemeScore = class(TThemeBasic)
- TextArtist: TThemeText;
- TextTitle: TThemeText;
-
- TextArtistTitle: TThemeText;
-
- PlayerStatic: array[1..6] of AThemeStatic;
- PlayerTexts: array[1..6] of AThemeText;
-
- TextName: array[1..6] of TThemeText;
- TextScore: array[1..6] of TThemeText;
-
- TextNotes: array[1..6] of TThemeText;
- TextNotesScore: array[1..6] of TThemeText;
- TextLineBonus: array[1..6] of TThemeText;
- TextLineBonusScore: array[1..6] of TThemeText;
- TextGoldenNotes: array[1..6] of TThemeText;
- TextGoldenNotesScore: array[1..6] of TThemeText;
- TextTotal: array[1..6] of TThemeText;
- TextTotalScore: array[1..6] of TThemeText;
-
- StaticBoxLightest: array[1..6] of TThemeStatic;
- StaticBoxLight: array[1..6] of TThemeStatic;
- StaticBoxDark: array[1..6] of TThemeStatic;
-
- StaticRatings: array[1..6] of TThemeStatic;
-
- StaticBackLevel: array[1..6] of TThemeStatic;
- StaticBackLevelRound: array[1..6] of TThemeStatic;
- StaticLevel: array[1..6] of TThemeStatic;
- StaticLevelRound: array[1..6] of TThemeStatic;
-
-// Description: array[0..5] of string;}
- end;
-
- TThemeTop5 = class(TThemeBasic)
- TextLevel: TThemeText;
- TextArtistTitle: TThemeText;
-
- StaticNumber: AThemeStatic;
- TextNumber: AThemeText;
- TextName: AThemeText;
- TextScore: AThemeText;
- end;
-
- TThemeOptions = class(TThemeBasic)
- ButtonGame: TThemeButton;
- ButtonGraphics: TThemeButton;
- ButtonSound: TThemeButton;
- ButtonLyrics: TThemeButton;
- ButtonThemes: TThemeButton;
- ButtonRecord: TThemeButton;
- ButtonAdvanced: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- Description: array[0..7] of string;
- end;
-
- TThemeOptionsGame = class(TThemeBasic)
- SelectPlayers: TThemeSelectSlide;
- SelectDifficulty: TThemeSelectSlide;
- SelectLanguage: TThemeSelectSlide;
- SelectTabs: TThemeSelectSlide;
- SelectSorting: TThemeSelectSlide;
- SelectDebug: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsGraphics = class(TThemeBasic)
- SelectFullscreen: TThemeSelectSlide;
- SelectResolution: TThemeSelectSlide;
- SelectDepth: TThemeSelectSlide;
- SelectVisualizer: TThemeSelectSlide;
- SelectOscilloscope: TThemeSelectSlide;
- SelectLineBonus: TThemeSelectSlide;
- SelectMovieSize: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsSound = class(TThemeBasic)
- SelectMicBoost: TThemeSelectSlide;
- SelectBackgroundMusic: TThemeSelectSlide;
- SelectClickAssist: TThemeSelectSlide;
- SelectBeatClick: TThemeSelectSlide;
- SelectThreshold: TThemeSelectSlide;
- SelectSlidePreviewVolume: TThemeSelectSlide;
- SelectSlidePreviewFading: TThemeSelectSlide;
- SelectSlideVoicePassthrough: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsLyrics = class(TThemeBasic)
- SelectLyricsFont: TThemeSelectSlide;
- SelectLyricsEffect: TThemeSelectSlide;
-// SelectSolmization: TThemeSelectSlide;
- SelectNoteLines: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsThemes = class(TThemeBasic)
- SelectTheme: TThemeSelectSlide;
- SelectSkin: TThemeSelectSlide;
- SelectColor: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsRecord = class(TThemeBasic)
- SelectSlideCard: TThemeSelectSlide;
- SelectSlideInput: TThemeSelectSlide;
- SelectSlideChannel: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- TThemeOptionsAdvanced = class(TThemeBasic)
- SelectLoadAnimation: TThemeSelectSlide;
- SelectEffectSing: TThemeSelectSlide;
- SelectScreenFade: TThemeSelectSlide;
- SelectLineBonus: TThemeSelectSlide;
- SelectAskbeforeDel: TThemeSelectSlide;
- SelectOnSongClick: TThemeSelectSlide;
- SelectPartyPopup: TThemeSelectSlide;
- ButtonExit: TThemeButton;
- end;
-
- //Error- and Check-Popup
- TThemeError = class(TThemeBasic)
- Button1: TThemeButton;
- TextError: TThemeText;
- end;
-
- TThemeCheck = class(TThemeBasic)
- Button1: TThemeButton;
- Button2: TThemeButton;
- TextCheck: TThemeText;
- end;
-
-
- //ScreenSong Menue
- TThemeSongMenu = class(TThemeBasic)
- Button1: TThemeButton;
- Button2: TThemeButton;
- Button3: TThemeButton;
- Button4: TThemeButton;
-
- SelectSlide3: TThemeSelectSlide;
-
- TextMenu: TThemeText;
- end;
-
- TThemeSongJumpTo = class(TThemeBasic)
- ButtonSearchText: TThemeButton;
- SelectSlideType: TThemeSelectSlide;
- TextFound: TThemeText;
-
- //Translated Texts
- Songsfound: String;
- NoSongsfound: String;
- CatText: String;
- IType: array [0..2] of String;
- end;
-
- //Party Screens
- TThemePartyNewRound = class(TThemeBasic)
- TextRound1: TThemeText;
- TextRound2: TThemeText;
- TextRound3: TThemeText;
- TextRound4: TThemeText;
- TextRound5: TThemeText;
- TextRound6: TThemeText;
- TextRound7: TThemeText;
- TextWinner1: TThemeText;
- TextWinner2: TThemeText;
- TextWinner3: TThemeText;
- TextWinner4: TThemeText;
- TextWinner5: TThemeText;
- TextWinner6: TThemeText;
- TextWinner7: TThemeText;
- TextNextRound: TThemeText;
- TextNextRoundNo: TThemeText;
- TextNextPlayer1: TThemeText;
- TextNextPlayer2: TThemeText;
- TextNextPlayer3: TThemeText;
-
- StaticRound1: TThemeStatic;
- StaticRound2: TThemeStatic;
- StaticRound3: TThemeStatic;
- StaticRound4: TThemeStatic;
- StaticRound5: TThemeStatic;
- StaticRound6: TThemeStatic;
- StaticRound7: TThemeStatic;
-
- TextScoreTeam1: TThemeText;
- TextScoreTeam2: TThemeText;
- TextScoreTeam3: TThemeText;
- TextNameTeam1: TThemeText;
- TextNameTeam2: TThemeText;
- TextNameTeam3: TThemeText;
- TextTeam1Players: TThemeText;
- TextTeam2Players: TThemeText;
- TextTeam3Players: TThemeText;
-
- StaticTeam1: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticNextPlayer1: TThemeStatic;
- StaticNextPlayer2: TThemeStatic;
- StaticNextPlayer3: TThemeStatic;
- end;
-
- TThemePartyScore = class(TThemeBasic)
- TextScoreTeam1: TThemeText;
- TextScoreTeam2: TThemeText;
- TextScoreTeam3: TThemeText;
- TextNameTeam1: TThemeText;
- TextNameTeam2: TThemeText;
- TextNameTeam3: TThemeText;
- StaticTeam1: TThemeStatic;
- StaticTeam1BG: TThemeStatic;
- StaticTeam1Deco: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam2BG: TThemeStatic;
- StaticTeam2Deco: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticTeam3BG: TThemeStatic;
- StaticTeam3Deco: TThemeStatic;
-
- DecoTextures: record
- ChangeTextures: Boolean;
-
- FirstTexture: String;
- FirstTyp: TTextureType;
- FirstColor: String;
-
- SecondTexture: String;
- SecondTyp: TTextureType;
- SecondColor: String;
-
- ThirdTexture: String;
- ThirdTyp: TTextureType;
- ThirdColor: String;
- end;
-
-
- TextWinner: TThemeText;
- end;
-
- TThemePartyWin = class(TThemeBasic)
- TextScoreTeam1: TThemeText;
- TextScoreTeam2: TThemeText;
- TextScoreTeam3: TThemeText;
- TextNameTeam1: TThemeText;
- TextNameTeam2: TThemeText;
- TextNameTeam3: TThemeText;
- StaticTeam1: TThemeStatic;
- StaticTeam1BG: TThemeStatic;
- StaticTeam1Deco: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam2BG: TThemeStatic;
- StaticTeam2Deco: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticTeam3BG: TThemeStatic;
- StaticTeam3Deco: TThemeStatic;
-
- TextWinner: TThemeText;
- end;
-
- TThemePartyOptions = class(TThemeBasic)
- SelectLevel: TThemeSelectSlide;
- SelectPlayList: TThemeSelectSlide;
- SelectPlayList2: TThemeSelectSlide;
- SelectRounds: TThemeSelectSlide;
- SelectTeams: TThemeSelectSlide;
- SelectPlayers1: TThemeSelectSlide;
- SelectPlayers2: TThemeSelectSlide;
- SelectPlayers3: TThemeSelectSlide;
-
- {ButtonNext: TThemeButton;
- ButtonPrev: TThemeButton;}
- end;
-
- TThemePartyPlayer = class(TThemeBasic)
- Team1Name: TThemeButton;
- Player1Name: TThemeButton;
- Player2Name: TThemeButton;
- Player3Name: TThemeButton;
- Player4Name: TThemeButton;
-
- Team2Name: TThemeButton;
- Player5Name: TThemeButton;
- Player6Name: TThemeButton;
- Player7Name: TThemeButton;
- Player8Name: TThemeButton;
-
- Team3Name: TThemeButton;
- Player9Name: TThemeButton;
- Player10Name: TThemeButton;
- Player11Name: TThemeButton;
- Player12Name: TThemeButton;
-
- {ButtonNext: TThemeButton;
- ButtonPrev: TThemeButton;}
- end;
-
- //Stats Screens
- TThemeStatMain = class(TThemeBasic)
- ButtonScores: TThemeButton;
- ButtonSingers: TThemeButton;
- ButtonSongs: TThemeButton;
- ButtonBands: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextOverview: TThemeText;
- end;
-
- TThemeStatDetail = class(TThemeBasic)
- ButtonNext: TThemeButton;
- ButtonPrev: TThemeButton;
- ButtonReverse: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- TextPage: TThemeText;
- TextList: AThemeText;
-
- Description: array[0..3] of string;
- DescriptionR: array[0..3] of string;
- FormatStr: array[0..3] of string;
- PageStr: String;
- end;
-
- //Playlist Translations
- TThemePlaylist = record
- CatText: string;
- end;
-
- TTheme = class
- private
- {$IFDEF THEMESAVE}
- ThemeIni: TIniFile;
- {$ELSE}
- ThemeIni: TMemIniFile;
- {$ENDIF}
-
- LastThemeBasic: TThemeBasic;
- procedure create_theme_objects();
- public
-
- Loading: TThemeLoading;
- Main: TThemeMain;
- Name: TThemeName;
- Level: TThemeLevel;
- Song: TThemeSong;
- Sing: TThemeSing;
- Score: TThemeScore;
- Top5: TThemeTop5;
- Options: TThemeOptions;
- OptionsGame: TThemeOptionsGame;
- OptionsGraphics: TThemeOptionsGraphics;
- OptionsSound: TThemeOptionsSound;
- OptionsLyrics: TThemeOptionsLyrics;
- OptionsThemes: TThemeOptionsThemes;
- OptionsRecord: TThemeOptionsRecord;
- OptionsAdvanced: TThemeOptionsAdvanced;
- //error and check popup
- ErrorPopup: TThemeError;
- CheckPopup: TThemeCheck;
- //ScreenSong extensions
- SongMenu: TThemeSongMenu;
- SongJumpto: TThemeSongJumpTo;
- //Party Screens:
- PartyNewRound: TThemePartyNewRound;
- PartyScore: TThemePartyScore;
- PartyWin: TThemePartyWin;
- PartyOptions: TThemePartyOptions;
- PartyPlayer: TThemePartyPlayer;
-
- //Stats Screens:
- StatMain: TThemeStatMain;
- StatDetail: TThemeStatDetail;
-
- Playlist: TThemePlaylist;
-
- ILevel: array[0..2] of String;
-
- constructor Create(FileName: string); overload; // Initialize theme system
- constructor Create(FileName: string; Color: integer); overload; // Initialize theme system with color
- function LoadTheme(FileName: string; sColor: integer): boolean; // Load some theme settings from file
-
- procedure LoadColors;
-
- procedure ThemeLoadBasic(Theme: TThemeBasic; Name: string);
- procedure ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
- procedure ThemeLoadText(var ThemeText: TThemeText; Name: string);
- procedure ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
- procedure ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
- procedure ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
- procedure ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection = nil);
- procedure ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
- procedure ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string);
- procedure ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
-
- procedure ThemeSave(FileName: string);
- procedure ThemeSaveBasic(Theme: TThemeBasic; Name: string);
- procedure ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
- procedure ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
- procedure ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
- procedure ThemeSaveText(ThemeText: TThemeText; Name: string);
- procedure ThemeSaveTexts(ThemeText: AThemeText; Name: string);
- procedure ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
-
- end;
-
- TColor = record
- Name: string;
- RGB: TRGB;
- end;
-
-function ColorExists(Name: string): integer;
-procedure LoadColor(var R, G, B: real; ColorName: string);
-function GetSystemColor(Color: integer): TRGB;
-function ColorSqrt(RGB: TRGB): TRGB;
-
-var
- //Skin: TSkin;
- Theme: TTheme;
- Color: array of TColor;
-
-implementation
-
-uses
- UCommon,
- ULanguage,
- USkins,
- UIni;
-
-constructor TTheme.Create(FileName: string);
-begin
- Create(FileName, 0);
-end;
-
-constructor TTheme.Create(FileName: string; Color: integer);
-begin
- inherited Create();
-
- Loading := TThemeLoading.Create;
- Main := TThemeMain.Create;
- Name := TThemeName.Create;
- Level := TThemeLevel.Create;
- Song := TThemeSong.Create;
- Sing := TThemeSing.Create;
- Score := TThemeScore.Create;
- Top5 := TThemeTop5.Create;
- Options := TThemeOptions.Create;
- OptionsGame := TThemeOptionsGame.Create;
- OptionsGraphics := TThemeOptionsGraphics.Create;
- OptionsSound := TThemeOptionsSound.Create;
- OptionsLyrics := TThemeOptionsLyrics.Create;
- OptionsThemes := TThemeOptionsThemes.Create;
- OptionsRecord := TThemeOptionsRecord.Create;
- OptionsAdvanced := TThemeOptionsAdvanced.Create;
-
- ErrorPopup := TThemeError.Create;
- CheckPopup := TThemeCheck.Create;
-
- SongMenu := TThemeSongMenu.Create;
- SongJumpto := TThemeSongJumpto.Create;
- //Party Screens
- PartyNewRound := TThemePartyNewRound.Create;
- PartyWin := TThemePartyWin.Create;
- PartyScore := TThemePartyScore.Create;
- PartyOptions := TThemePartyOptions.Create;
- PartyPlayer := TThemePartyPlayer.Create;
-
- //Stats Screens:
- StatMain := TThemeStatMain.Create;
- StatDetail := TThemeStatDetail.Create;
-
- LoadTheme(FileName, Color);
-
-end;
-
-
-function TTheme.LoadTheme(FileName: string; sColor: integer): boolean;
-var
- I: integer;
- Path: string;
-begin
- Result := false;
-
- create_theme_objects();
-
- Log.LogStatus('Loading: '+ FileName, 'TTheme.LoadTheme');
-
- FileName := AdaptFilePaths( FileName );
-
- if not FileExists(FileName) then
- begin
- Log.LogError('Theme does not exist ('+ FileName +')', 'TTheme.LoadTheme');
- end;
-
- if FileExists(FileName) then
- begin
- Result := true;
-
- {$IFDEF THEMESAVE}
- ThemeIni := TIniFile.Create(FileName);
- {$ELSE}
- ThemeIni := TMemIniFile.Create(FileName);
- {$ENDIF}
-
- if ThemeIni.ReadString('Theme', 'Name', '') <> '' then
- begin
-
- {Skin.SkinName := ThemeIni.ReadString('Theme', 'Name', 'Singstar');
- Skin.SkinPath := 'Skins\' + Skin.SkinName + '\';
- Skin.SkinReg := false; }
- Skin.Color := sColor;
-
- Skin.LoadSkin(ISkin[Ini.SkinNo]);
-
- LoadColors;
-
-// ThemeIni.Free;
-// ThemeIni := TIniFile.Create('Themes\Singstar\Main.ini');
-
- // Loading
- ThemeLoadBasic(Loading, 'Loading');
- ThemeLoadText(Loading.TextLoading, 'LoadingTextLoading');
- ThemeLoadStatic(Loading.StaticAnimation, 'LoadingStaticAnimation');
-
- // Main
- ThemeLoadBasic(Main, 'Main');
-
- ThemeLoadText(Main.TextDescription, 'MainTextDescription');
- ThemeLoadText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
- ThemeLoadButton(Main.ButtonSolo, 'MainButtonSolo');
- ThemeLoadButton(Main.ButtonMulti, 'MainButtonMulti');
- ThemeLoadButton(Main.ButtonStat, 'MainButtonStats');
- ThemeLoadButton(Main.ButtonEditor, 'MainButtonEditor');
- ThemeLoadButton(Main.ButtonOptions, 'MainButtonOptions');
- ThemeLoadButton(Main.ButtonExit, 'MainButtonExit');
-
- //Main Desc Text Translation Start
-
- Main.Description[0] := Language.Translate('SING_SING');
- Main.DescriptionLong[0] := Language.Translate('SING_SING_DESC');
- Main.Description[1] := Language.Translate('SING_MULTI');
- Main.DescriptionLong[1] := Language.Translate('SING_MULTI_DESC');
- Main.Description[2] := Language.Translate('SING_STATS');
- Main.DescriptionLong[2] := Language.Translate('SING_STATS_DESC');
- Main.Description[3] := Language.Translate('SING_EDITOR');
- Main.DescriptionLong[3] := Language.Translate('SING_EDITOR_DESC');
- Main.Description[4] := Language.Translate('SING_GAME_OPTIONS');
- Main.DescriptionLong[4] := Language.Translate('SING_GAME_OPTIONS_DESC');
- Main.Description[5] := Language.Translate('SING_EXIT');
- Main.DescriptionLong[5] := Language.Translate('SING_EXIT_DESC');
-
- //Main Desc Text Translation End
-
- Main.TextDescription.Text := Main.Description[0];
- Main.TextDescriptionLong.Text := Main.DescriptionLong[0];
-
- // Name
- ThemeLoadBasic(Name, 'Name');
-
- for I := 1 to 6 do
- ThemeLoadButton(Name.ButtonPlayer[I], 'NameButtonPlayer'+IntToStr(I));
-
- // Level
- ThemeLoadBasic(Level, 'Level');
-
- ThemeLoadButton(Level.ButtonEasy, 'LevelButtonEasy');
- ThemeLoadButton(Level.ButtonMedium, 'LevelButtonMedium');
- ThemeLoadButton(Level.ButtonHard, 'LevelButtonHard');
-
-
- // Song
- ThemeLoadBasic(Song, 'Song');
-
- ThemeLoadText(Song.TextArtist, 'SongTextArtist');
- ThemeLoadText(Song.TextTitle, 'SongTextTitle');
- ThemeLoadText(Song.TextNumber, 'SongTextNumber');
-
- //Video Icon Mod
- ThemeLoadStatic(Song.VideoIcon, 'SongVideoIcon');
-
- //Show Cat in TopLeft Mod
- ThemeLoadStatic(Song.StaticCat, 'SongStaticCat');
- ThemeLoadText(Song.TextCat, 'SongTextCat');
-
- //Load Cover Pos and Size from Theme Mod
- Song.Cover.X := ThemeIni.ReadInteger('SongCover', 'X', 300);
- Song.Cover.Y := ThemeIni.ReadInteger('SongCover', 'Y', 190);
- Song.Cover.W := ThemeIni.ReadInteger('SongCover', 'W', 300);
- Song.Cover.H := ThemeIni.ReadInteger('SongCover', 'H', 200);
- Song.Cover.Style := ThemeIni.ReadInteger('SongCover', 'Style', 4);
- Song.Cover.Reflections := (ThemeIni.ReadInteger('SongCover', 'Reflections', 0) = 1);
- //Load Cover Pos and Size from Theme Mod End
-
- //Load Equalizer Pos and Size from Theme Mod
- Song.Equalizer.Visible := (ThemeIni.ReadInteger('SongEqualizer', 'Visible', 0) = 1);
- Song.Equalizer.Direction := (ThemeIni.ReadInteger('SongEqualizer', 'Direction', 0) = 1);
- Song.Equalizer.Alpha := ThemeIni.ReadInteger('SongEqualizer', 'Alpha', 1);
- Song.Equalizer.Space := ThemeIni.ReadInteger('SongEqualizer', 'Space', 1);
- Song.Equalizer.X := ThemeIni.ReadInteger('SongEqualizer', 'X', 0);
- Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 0);
- Song.Equalizer.Z := ThemeIni.ReadInteger('SongEqualizer', 'Z', 1);
- Song.Equalizer.W := ThemeIni.ReadInteger('SongEqualizer', 'PieceW', 8);
- Song.Equalizer.H := ThemeIni.ReadInteger('SongEqualizer', 'PieceH', 8);
- Song.Equalizer.Bands := ThemeIni.ReadInteger('SongEqualizer', 'Bands', 5);
- Song.Equalizer.Length := ThemeIni.ReadInteger('SongEqualizer', 'Length', 12);
-
- //Color
- I := ColorExists(ThemeIni.ReadString('SongEqualizer', 'Color', 'Black'));
- if I >= 0 then begin
- Song.Equalizer.ColR := Color[I].RGB.R;
- Song.Equalizer.ColG := Color[I].RGB.G;
- Song.Equalizer.ColB := Color[I].RGB.B;
- end
- else begin
- Song.Equalizer.ColR := 0;
- Song.Equalizer.ColG := 0;
- Song.Equalizer.ColB := 0;
- end;
- //Load Equalizer Pos and Size from Theme Mod End
-
- //Party and Non Party specific Statics and Texts
- ThemeLoadStatics (Song.StaticParty, 'SongStaticParty');
- ThemeLoadTexts (Song.TextParty, 'SongTextParty');
-
- ThemeLoadStatics (Song.StaticNonParty, 'SongStaticNonParty');
- ThemeLoadTexts (Song.TextNonParty, 'SongTextNonParty');
-
- //Party Mode
- ThemeLoadStatic(Song.StaticTeam1Joker1, 'SongStaticTeam1Joker1');
- ThemeLoadStatic(Song.StaticTeam1Joker2, 'SongStaticTeam1Joker2');
- ThemeLoadStatic(Song.StaticTeam1Joker3, 'SongStaticTeam1Joker3');
- ThemeLoadStatic(Song.StaticTeam1Joker4, 'SongStaticTeam1Joker4');
- ThemeLoadStatic(Song.StaticTeam1Joker5, 'SongStaticTeam1Joker5');
-
- ThemeLoadStatic(Song.StaticTeam2Joker1, 'SongStaticTeam2Joker1');
- ThemeLoadStatic(Song.StaticTeam2Joker2, 'SongStaticTeam2Joker2');
- ThemeLoadStatic(Song.StaticTeam2Joker3, 'SongStaticTeam2Joker3');
- ThemeLoadStatic(Song.StaticTeam2Joker4, 'SongStaticTeam2Joker4');
- ThemeLoadStatic(Song.StaticTeam2Joker5, 'SongStaticTeam2Joker5');
-
- ThemeLoadStatic(Song.StaticTeam3Joker1, 'SongStaticTeam3Joker1');
- ThemeLoadStatic(Song.StaticTeam3Joker2, 'SongStaticTeam3Joker2');
- ThemeLoadStatic(Song.StaticTeam3Joker3, 'SongStaticTeam3Joker3');
- ThemeLoadStatic(Song.StaticTeam3Joker4, 'SongStaticTeam3Joker4');
- ThemeLoadStatic(Song.StaticTeam3Joker5, 'SongStaticTeam3Joker5');
-
-
- // Sing
- ThemeLoadBasic(Sing, 'Sing');
-
- //TimeBar mod
- ThemeLoadStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
- ThemeLoadText(Sing.TextTimeText, 'SingTimeText');
- //eoa TimeBar mod
-
- //moveable singbar mod
- ThemeLoadStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
- ThemeLoadStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
- ThemeLoadStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
- ThemeLoadStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
- ThemeLoadStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
- ThemeLoadStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
- //eoa moveable singbar
-
- ThemeLoadStatic(Sing.StaticP1, 'SingP1Static');
- ThemeLoadText(Sing.TextP1, 'SingP1Text');
- ThemeLoadStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
- ThemeLoadText(Sing.TextP1Score, 'SingP1TextScore');
- //Added for ps3 skin
- //This one is shown in 2/4P mode
- //if it exists, otherwise the one Player equivaltents are used
- if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
- begin
- ThemeLoadStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
- ThemeLoadText(Sing.TextP1TwoP, 'SingP1TwoPText');
- ThemeLoadStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
- ThemeLoadText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
- end
- else
- begin
- Sing.StaticP1TwoP := Sing.StaticP1;
- Sing.TextP1TwoP := Sing.TextP1;
- Sing.StaticP1TwoPScoreBG := Sing.StaticP1ScoreBG;
- Sing.TextP1TwoPScore := Sing.TextP1Score;
- end;
-
- //This one is shown in 3/6P mode
- //if it exists, otherwise the one Player equivaltents are used
- if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
- begin
- ThemeLoadStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
- ThemeLoadText(Sing.TextP1ThreeP, 'SingP1ThreePText');
- ThemeLoadStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
- ThemeLoadText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
- end
- else
- begin
- Sing.StaticP1ThreeP := Sing.StaticP1;
- Sing.TextP1ThreeP := Sing.TextP1;
- Sing.StaticP1ThreePScoreBG := Sing.StaticP1ScoreBG;
- Sing.TextP1ThreePScore := Sing.TextP1Score;
- end;
- //eoa
- ThemeLoadStatic(Sing.StaticP2R, 'SingP2RStatic');
- ThemeLoadText(Sing.TextP2R, 'SingP2RText');
- ThemeLoadStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
- ThemeLoadText(Sing.TextP2RScore, 'SingP2RTextScore');
-
- ThemeLoadStatic(Sing.StaticP2M, 'SingP2MStatic');
- ThemeLoadText(Sing.TextP2M, 'SingP2MText');
- ThemeLoadStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
- ThemeLoadText(Sing.TextP2MScore, 'SingP2MTextScore');
-
- ThemeLoadStatic(Sing.StaticP3R, 'SingP3RStatic');
- ThemeLoadText(Sing.TextP3R, 'SingP3RText');
- ThemeLoadStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
- ThemeLoadText(Sing.TextP3RScore, 'SingP3RTextScore');
-
- //Line Bonus Texts
- Sing.LineBonusText[0] := Language.Translate('POPUP_AWFUL');
- Sing.LineBonusText[1] := Sing.LineBonusText[0];
- Sing.LineBonusText[2] := Language.Translate('POPUP_POOR');
- Sing.LineBonusText[3] := Language.Translate('POPUP_BAD');
- Sing.LineBonusText[4] := Language.Translate('POPUP_NOTBAD');
- Sing.LineBonusText[5] := Language.Translate('POPUP_GOOD');
- Sing.LineBonusText[6] := Language.Translate('POPUP_GREAT');
- Sing.LineBonusText[7] := Language.Translate('POPUP_AWESOME');
- Sing.LineBonusText[8] := Language.Translate('POPUP_PERFECT');
-
- //PausePopup
- ThemeLoadStatic(Sing.PausePopUp, 'PausePopUpStatic');
-
- // Score
- ThemeLoadBasic(Score, 'Score');
-
- ThemeLoadText(Score.TextArtist, 'ScoreTextArtist');
- ThemeLoadText(Score.TextTitle, 'ScoreTextTitle');
- ThemeLoadText(Score.TextArtistTitle, 'ScoreTextArtistTitle');
-
- for I := 1 to 6 do begin
- ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
- ThemeLoadTexts(Score.PlayerTexts[I], 'ScorePlayer' + IntToStr(I) + 'Text');
-
- ThemeLoadText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
- ThemeLoadText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
- ThemeLoadText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
- ThemeLoadText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
- ThemeLoadText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
- ThemeLoadText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
- ThemeLoadText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
- ThemeLoadText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
- ThemeLoadText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
- ThemeLoadText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
-
- ThemeLoadStatic(Score.StaticBoxLightest[I], 'ScoreStaticBoxLightest' + IntToStr(I));
- ThemeLoadStatic(Score.StaticBoxLight[I], 'ScoreStaticBoxLight' + IntToStr(I));
- ThemeLoadStatic(Score.StaticBoxDark[I], 'ScoreStaticBoxDark' + IntToStr(I));
-
- ThemeLoadStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
- ThemeLoadStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
- ThemeLoadStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
- ThemeLoadStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
-
- ThemeLoadStatic(Score.StaticRatings[I], 'ScoreStaticRatingPicture' + IntToStr(I));
- end;
-
- // Top5
- ThemeLoadBasic(Top5, 'Top5');
-
- ThemeLoadText(Top5.TextLevel, 'Top5TextLevel');
- ThemeLoadText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
- ThemeLoadStatics(Top5.StaticNumber, 'Top5StaticNumber');
- ThemeLoadTexts(Top5.TextNumber, 'Top5TextNumber');
- ThemeLoadTexts(Top5.TextName, 'Top5TextName');
- ThemeLoadTexts(Top5.TextScore, 'Top5TextScore');
-
- // Options
- ThemeLoadBasic(Options, 'Options');
-
- ThemeLoadButton(Options.ButtonGame, 'OptionsButtonGame');
- ThemeLoadButton(Options.ButtonGraphics, 'OptionsButtonGraphics');
- ThemeLoadButton(Options.ButtonSound, 'OptionsButtonSound');
- ThemeLoadButton(Options.ButtonLyrics, 'OptionsButtonLyrics');
- ThemeLoadButton(Options.ButtonThemes, 'OptionsButtonThemes');
- ThemeLoadButton(Options.ButtonRecord, 'OptionsButtonRecord');
- ThemeLoadButton(Options.ButtonAdvanced, 'OptionsButtonAdvanced');
- ThemeLoadButton(Options.ButtonExit, 'OptionsButtonExit');
-
- Options.Description[0] := Language.Translate('SING_OPTIONS_GAME_DESC');
- Options.Description[1] := Language.Translate('SING_OPTIONS_GRAPHICS_DESC');
- Options.Description[2] := Language.Translate('SING_OPTIONS_SOUND_DESC');
- Options.Description[3] := Language.Translate('SING_OPTIONS_LYRICS_DESC');
- Options.Description[4] := Language.Translate('SING_OPTIONS_THEMES_DESC');
- Options.Description[5] := Language.Translate('SING_OPTIONS_RECORD_DESC');
- Options.Description[6] := Language.Translate('SING_OPTIONS_ADVANCED_DESC');
- Options.Description[7] := Language.Translate('SING_OPTIONS_EXIT');
-
- ThemeLoadText(Options.TextDescription, 'OptionsTextDescription');
- Options.TextDescription.Text := Options.Description[0];
-
- // Options Game
- ThemeLoadBasic(OptionsGame, 'OptionsGame');
-
- ThemeLoadSelectSlide(OptionsGame.SelectPlayers, 'OptionsGameSelectPlayers');
- ThemeLoadSelectSlide(OptionsGame.SelectDifficulty, 'OptionsGameSelectDifficulty');
- ThemeLoadSelectSlide(OptionsGame.SelectLanguage, 'OptionsGameSelectSlideLanguage');
- ThemeLoadSelectSlide(OptionsGame.SelectTabs, 'OptionsGameSelectTabs');
- ThemeLoadSelectSlide(OptionsGame.SelectSorting, 'OptionsGameSelectSlideSorting');
- ThemeLoadSelectSlide(OptionsGame.SelectDebug, 'OptionsGameSelectDebug');
- ThemeLoadButton(OptionsGame.ButtonExit, 'OptionsGameButtonExit');
-
- // Options Graphics
- ThemeLoadBasic(OptionsGraphics, 'OptionsGraphics');
-
- ThemeLoadSelectSlide(OptionsGraphics.SelectFullscreen, 'OptionsGraphicsSelectFullscreen');
- ThemeLoadSelectSlide(OptionsGraphics.SelectResolution, 'OptionsGraphicsSelectSlideResolution');
- ThemeLoadSelectSlide(OptionsGraphics.SelectDepth, 'OptionsGraphicsSelectDepth');
- ThemeLoadSelectSlide(OptionsGraphics.SelectVisualizer, 'OptionsGraphicsSelectVisualizer');
- ThemeLoadSelectSlide(OptionsGraphics.SelectOscilloscope, 'OptionsGraphicsSelectOscilloscope');
- ThemeLoadSelectSlide(OptionsGraphics.SelectLineBonus, 'OptionsGraphicsSelectLineBonus');
- ThemeLoadSelectSlide(OptionsGraphics.SelectMovieSize, 'OptionsGraphicsSelectMovieSize');
- ThemeLoadButton(OptionsGraphics.ButtonExit, 'OptionsGraphicsButtonExit');
-
- // Options Sound
- ThemeLoadBasic(OptionsSound, 'OptionsSound');
-
- ThemeLoadSelectSlide(OptionsSound.SelectBackgroundMusic, 'OptionsSoundSelectBackgroundMusic');
- ThemeLoadSelectSlide(OptionsSound.SelectMicBoost, 'OptionsSoundSelectMicBoost');
- ThemeLoadSelectSlide(OptionsSound.SelectClickAssist, 'OptionsSoundSelectClickAssist');
- ThemeLoadSelectSlide(OptionsSound.SelectBeatClick, 'OptionsSoundSelectBeatClick');
- ThemeLoadSelectSlide(OptionsSound.SelectThreshold, 'OptionsSoundSelectThreshold');
- //Song Preview
- ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewVolume, 'OptionsSoundSelectSlidePreviewVolume');
- ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewFading, 'OptionsSoundSelectSlidePreviewFading');
- ThemeLoadSelectSlide(OptionsSound.SelectSlideVoicePassthrough, 'OptionsSoundSelectVoicePassthrough');
-
- ThemeLoadButton(OptionsSound.ButtonExit, 'OptionsSoundButtonExit');
-
- // Options Lyrics
- ThemeLoadBasic(OptionsLyrics, 'OptionsLyrics');
-
- ThemeLoadSelectSlide(OptionsLyrics.SelectLyricsFont, 'OptionsLyricsSelectLyricsFont');
- ThemeLoadSelectSlide(OptionsLyrics.SelectLyricsEffect, 'OptionsLyricsSelectLyricsEffect');
- //ThemeLoadSelectSlide(OptionsLyrics.SelectSolmization, 'OptionsLyricsSelectSolmization');
- ThemeLoadSelectSlide(OptionsLyrics.SelectNoteLines, 'OptionsLyricsSelectNoteLines');
- ThemeLoadButton(OptionsLyrics.ButtonExit, 'OptionsLyricsButtonExit');
-
- // Options Themes
- ThemeLoadBasic(OptionsThemes, 'OptionsThemes');
-
- ThemeLoadSelectSlide(OptionsThemes.SelectTheme, 'OptionsThemesSelectTheme');
- ThemeLoadSelectSlide(OptionsThemes.SelectSkin, 'OptionsThemesSelectSkin');
- ThemeLoadSelectSlide(OptionsThemes.SelectColor, 'OptionsThemesSelectColor');
- ThemeLoadButton(OptionsThemes.ButtonExit, 'OptionsThemesButtonExit');
-
- // Options Record
- ThemeLoadBasic(OptionsRecord, 'OptionsRecord');
-
- ThemeLoadSelectSlide(OptionsRecord.SelectSlideCard, 'OptionsRecordSelectSlideCard');
- ThemeLoadSelectSlide(OptionsRecord.SelectSlideInput, 'OptionsRecordSelectSlideInput');
- ThemeLoadSelectSlide(OptionsRecord.SelectSlideChannel, 'OptionsRecordSelectSlideChannel');
- ThemeLoadButton(OptionsRecord.ButtonExit, 'OptionsRecordButtonExit');
-
- //Options Advanced
- ThemeLoadBasic(OptionsAdvanced, 'OptionsAdvanced');
-
- ThemeLoadSelectSlide(OptionsAdvanced.SelectLoadAnimation, 'OptionsAdvancedSelectLoadAnimation');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectScreenFade, 'OptionsAdvancedSelectScreenFade');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectEffectSing, 'OptionsAdvancedSelectEffectSing');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectLineBonus, 'OptionsAdvancedSelectLineBonus');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectOnSongClick, 'OptionsAdvancedSelectSlideOnSongClick');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectAskbeforeDel, 'OptionsAdvancedSelectAskbeforeDel');
- ThemeLoadSelectSlide(OptionsAdvanced.SelectPartyPopup, 'OptionsAdvancedSelectPartyPopup');
- ThemeLoadButton (OptionsAdvanced.ButtonExit, 'OptionsAdvancedButtonExit');
-
- //error and check popup
- ThemeLoadBasic (ErrorPopup, 'ErrorPopup');
- ThemeLoadButton(ErrorPopup.Button1, 'ErrorPopupButton1');
- ThemeLoadText (ErrorPopup.TextError,'ErrorPopupText');
- ThemeLoadBasic (CheckPopup, 'CheckPopup');
- ThemeLoadButton(CheckPopup.Button1, 'CheckPopupButton1');
- ThemeLoadButton(CheckPopup.Button2, 'CheckPopupButton2');
- ThemeLoadText(CheckPopup.TextCheck , 'CheckPopupText');
-
- //Song Menu
- ThemeLoadBasic (SongMenu, 'SongMenu');
- ThemeLoadButton(SongMenu.Button1, 'SongMenuButton1');
- ThemeLoadButton(SongMenu.Button2, 'SongMenuButton2');
- ThemeLoadButton(SongMenu.Button3, 'SongMenuButton3');
- ThemeLoadButton(SongMenu.Button4, 'SongMenuButton4');
- ThemeLoadSelectSlide(SongMenu.SelectSlide3, 'SongMenuSelectSlide3');
-
- ThemeLoadText(SongMenu.TextMenu, 'SongMenuTextMenu');
-
- //Song Jumpto
- ThemeLoadBasic (SongJumpto, 'SongJumpto');
- ThemeLoadButton(SongJumpto.ButtonSearchText, 'SongJumptoButtonSearchText');
- ThemeLoadSelectSlide(SongJumpto.SelectSlideType, 'SongJumptoSelectSlideType');
- ThemeLoadText(SongJumpto.TextFound, 'SongJumptoTextFound');
- //Translations
- SongJumpto.IType[0] := Language.Translate('SONG_JUMPTO_TYPE1');
- SongJumpto.IType[1] := Language.Translate('SONG_JUMPTO_TYPE2');
- SongJumpto.IType[2] := Language.Translate('SONG_JUMPTO_TYPE3');
- SongJumpto.SongsFound := Language.Translate('SONG_JUMPTO_SONGSFOUND');
- SongJumpto.NoSongsFound := Language.Translate('SONG_JUMPTO_NOSONGSFOUND');
- SongJumpto.CatText := Language.Translate('SONG_JUMPTO_CATTEXT');
-
- //Party Screens:
- //Party NewRound
- ThemeLoadBasic(PartyNewRound, 'PartyNewRound');
-
- ThemeLoadText (PartyNewRound.TextRound1, 'PartyNewRoundTextRound1');
- ThemeLoadText (PartyNewRound.TextRound2, 'PartyNewRoundTextRound2');
- ThemeLoadText (PartyNewRound.TextRound3, 'PartyNewRoundTextRound3');
- ThemeLoadText (PartyNewRound.TextRound4, 'PartyNewRoundTextRound4');
- ThemeLoadText (PartyNewRound.TextRound5, 'PartyNewRoundTextRound5');
- ThemeLoadText (PartyNewRound.TextRound6, 'PartyNewRoundTextRound6');
- ThemeLoadText (PartyNewRound.TextRound7, 'PartyNewRoundTextRound7');
- ThemeLoadText (PartyNewRound.TextWinner1, 'PartyNewRoundTextWinner1');
- ThemeLoadText (PartyNewRound.TextWinner2, 'PartyNewRoundTextWinner2');
- ThemeLoadText (PartyNewRound.TextWinner3, 'PartyNewRoundTextWinner3');
- ThemeLoadText (PartyNewRound.TextWinner4, 'PartyNewRoundTextWinner4');
- ThemeLoadText (PartyNewRound.TextWinner5, 'PartyNewRoundTextWinner5');
- ThemeLoadText (PartyNewRound.TextWinner6, 'PartyNewRoundTextWinner6');
- ThemeLoadText (PartyNewRound.TextWinner7, 'PartyNewRoundTextWinner7');
- ThemeLoadText (PartyNewRound.TextNextRound, 'PartyNewRoundTextNextRound');
- ThemeLoadText (PartyNewRound.TextNextRoundNo, 'PartyNewRoundTextNextRoundNo');
- ThemeLoadText (PartyNewRound.TextNextPlayer1, 'PartyNewRoundTextNextPlayer1');
- ThemeLoadText (PartyNewRound.TextNextPlayer2, 'PartyNewRoundTextNextPlayer2');
- ThemeLoadText (PartyNewRound.TextNextPlayer3, 'PartyNewRoundTextNextPlayer3');
-
- ThemeLoadStatic (PartyNewRound.StaticRound1, 'PartyNewRoundStaticRound1');
- ThemeLoadStatic (PartyNewRound.StaticRound2, 'PartyNewRoundStaticRound2');
- ThemeLoadStatic (PartyNewRound.StaticRound3, 'PartyNewRoundStaticRound3');
- ThemeLoadStatic (PartyNewRound.StaticRound4, 'PartyNewRoundStaticRound4');
- ThemeLoadStatic (PartyNewRound.StaticRound5, 'PartyNewRoundStaticRound5');
- ThemeLoadStatic (PartyNewRound.StaticRound6, 'PartyNewRoundStaticRound6');
- ThemeLoadStatic (PartyNewRound.StaticRound7, 'PartyNewRoundStaticRound7');
-
- ThemeLoadText (PartyNewRound.TextScoreTeam1, 'PartyNewRoundTextScoreTeam1');
- ThemeLoadText (PartyNewRound.TextScoreTeam2, 'PartyNewRoundTextScoreTeam2');
- ThemeLoadText (PartyNewRound.TextScoreTeam3, 'PartyNewRoundTextScoreTeam3');
- ThemeLoadText (PartyNewRound.TextNameTeam1, 'PartyNewRoundTextNameTeam1');
- ThemeLoadText (PartyNewRound.TextNameTeam2, 'PartyNewRoundTextNameTeam2');
- ThemeLoadText (PartyNewRound.TextNameTeam3, 'PartyNewRoundTextNameTeam3');
-
- ThemeLoadText (PartyNewRound.TextTeam1Players, 'PartyNewRoundTextTeam1Players');
- ThemeLoadText (PartyNewRound.TextTeam2Players, 'PartyNewRoundTextTeam2Players');
- ThemeLoadText (PartyNewRound.TextTeam3Players, 'PartyNewRoundTextTeam3Players');
-
- ThemeLoadStatic (PartyNewRound.StaticTeam1, 'PartyNewRoundStaticTeam1');
- ThemeLoadStatic (PartyNewRound.StaticTeam2, 'PartyNewRoundStaticTeam2');
- ThemeLoadStatic (PartyNewRound.StaticTeam3, 'PartyNewRoundStaticTeam3');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer1, 'PartyNewRoundStaticNextPlayer1');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer2, 'PartyNewRoundStaticNextPlayer2');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer3, 'PartyNewRoundStaticNextPlayer3');
-
- //Party Score
- ThemeLoadBasic(PartyScore, 'PartyScore');
-
- ThemeLoadText (PartyScore.TextScoreTeam1, 'PartyScoreTextScoreTeam1');
- ThemeLoadText (PartyScore.TextScoreTeam2, 'PartyScoreTextScoreTeam2');
- ThemeLoadText (PartyScore.TextScoreTeam3, 'PartyScoreTextScoreTeam3');
- ThemeLoadText (PartyScore.TextNameTeam1, 'PartyScoreTextNameTeam1');
- ThemeLoadText (PartyScore.TextNameTeam2, 'PartyScoreTextNameTeam2');
- ThemeLoadText (PartyScore.TextNameTeam3, 'PartyScoreTextNameTeam3');
-
- ThemeLoadStatic (PartyScore.StaticTeam1, 'PartyScoreStaticTeam1');
- ThemeLoadStatic (PartyScore.StaticTeam1BG, 'PartyScoreStaticTeam1BG');
- ThemeLoadStatic (PartyScore.StaticTeam1Deco, 'PartyScoreStaticTeam1Deco');
- ThemeLoadStatic (PartyScore.StaticTeam2, 'PartyScoreStaticTeam2');
- ThemeLoadStatic (PartyScore.StaticTeam2BG, 'PartyScoreStaticTeam2BG');
- ThemeLoadStatic (PartyScore.StaticTeam2Deco, 'PartyScoreStaticTeam2Deco');
- ThemeLoadStatic (PartyScore.StaticTeam3, 'PartyScoreStaticTeam3');
- ThemeLoadStatic (PartyScore.StaticTeam3BG, 'PartyScoreStaticTeam3BG');
- ThemeLoadStatic (PartyScore.StaticTeam3Deco, 'PartyScoreStaticTeam3Deco');
-
- //Load Party Score DecoTextures Object
- PartyScore.DecoTextures.ChangeTextures := (ThemeIni.ReadInteger('PartyScoreDecoTextures', 'ChangeTextures', 0) = 1);
- PartyScore.DecoTextures.FirstTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTexture', '');
- PartyScore.DecoTextures.FirstTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTyp', ''), TEXTURE_TYPE_COLORIZED);
- PartyScore.DecoTextures.FirstColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstColor', 'Black');
-
- PartyScore.DecoTextures.SecondTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTexture', '');
- PartyScore.DecoTextures.SecondTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTyp', ''), TEXTURE_TYPE_COLORIZED);
- PartyScore.DecoTextures.SecondColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondColor', 'Black');
-
- PartyScore.DecoTextures.ThirdTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTexture', '');
- PartyScore.DecoTextures.ThirdTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTyp', ''), TEXTURE_TYPE_COLORIZED);
- PartyScore.DecoTextures.ThirdColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdColor', 'Black');
-
- ThemeLoadText (PartyScore.TextWinner, 'PartyScoreTextWinner');
-
- //Party Win
- ThemeLoadBasic(PartyWin, 'PartyWin');
-
- ThemeLoadText (PartyWin.TextScoreTeam1, 'PartyWinTextScoreTeam1');
- ThemeLoadText (PartyWin.TextScoreTeam2, 'PartyWinTextScoreTeam2');
- ThemeLoadText (PartyWin.TextScoreTeam3, 'PartyWinTextScoreTeam3');
- ThemeLoadText (PartyWin.TextNameTeam1, 'PartyWinTextNameTeam1');
- ThemeLoadText (PartyWin.TextNameTeam2, 'PartyWinTextNameTeam2');
- ThemeLoadText (PartyWin.TextNameTeam3, 'PartyWinTextNameTeam3');
-
- ThemeLoadStatic (PartyWin.StaticTeam1, 'PartyWinStaticTeam1');
- ThemeLoadStatic (PartyWin.StaticTeam1BG, 'PartyWinStaticTeam1BG');
- ThemeLoadStatic (PartyWin.StaticTeam1Deco, 'PartyWinStaticTeam1Deco');
- ThemeLoadStatic (PartyWin.StaticTeam2, 'PartyWinStaticTeam2');
- ThemeLoadStatic (PartyWin.StaticTeam2BG, 'PartyWinStaticTeam2BG');
- ThemeLoadStatic (PartyWin.StaticTeam2Deco, 'PartyWinStaticTeam2Deco');
- ThemeLoadStatic (PartyWin.StaticTeam3, 'PartyWinStaticTeam3');
- ThemeLoadStatic (PartyWin.StaticTeam3BG, 'PartyWinStaticTeam3BG');
- ThemeLoadStatic (PartyWin.StaticTeam3Deco, 'PartyWinStaticTeam3Deco');
-
- ThemeLoadText (PartyWin.TextWinner, 'PartyWinTextWinner');
-
- //Party Options
- ThemeLoadBasic(PartyOptions, 'PartyOptions');
- ThemeLoadSelectSlide(PartyOptions.SelectLevel, 'PartyOptionsSelectLevel');
- ThemeLoadSelectSlide(PartyOptions.SelectPlayList, 'PartyOptionsSelectPlayList');
- ThemeLoadSelectSlide(PartyOptions.SelectPlayList2, 'PartyOptionsSelectPlayList2');
- ThemeLoadSelectSlide(PartyOptions.SelectRounds, 'PartyOptionsSelectRounds');
- ThemeLoadSelectSlide(PartyOptions.SelectTeams, 'PartyOptionsSelectTeams');
- ThemeLoadSelectSlide(PartyOptions.SelectPlayers1, 'PartyOptionsSelectPlayers1');
- ThemeLoadSelectSlide(PartyOptions.SelectPlayers2, 'PartyOptionsSelectPlayers2');
- ThemeLoadSelectSlide(PartyOptions.SelectPlayers3, 'PartyOptionsSelectPlayers3');
-
- {ThemeLoadButton (ButtonNext, 'ButtonNext');
- ThemeLoadButton (ButtonPrev, 'ButtonPrev');}
-
- //Party Player
- ThemeLoadBasic(PartyPlayer, 'PartyPlayer');
- ThemeLoadButton(PartyPlayer.Team1Name, 'PartyPlayerTeam1Name');
- ThemeLoadButton(PartyPlayer.Player1Name, 'PartyPlayerPlayer1Name');
- ThemeLoadButton(PartyPlayer.Player2Name, 'PartyPlayerPlayer2Name');
- ThemeLoadButton(PartyPlayer.Player3Name, 'PartyPlayerPlayer3Name');
- ThemeLoadButton(PartyPlayer.Player4Name, 'PartyPlayerPlayer4Name');
-
- ThemeLoadButton(PartyPlayer.Team2Name, 'PartyPlayerTeam2Name');
- ThemeLoadButton(PartyPlayer.Player5Name, 'PartyPlayerPlayer5Name');
- ThemeLoadButton(PartyPlayer.Player6Name, 'PartyPlayerPlayer6Name');
- ThemeLoadButton(PartyPlayer.Player7Name, 'PartyPlayerPlayer7Name');
- ThemeLoadButton(PartyPlayer.Player8Name, 'PartyPlayerPlayer8Name');
-
- ThemeLoadButton(PartyPlayer.Team3Name, 'PartyPlayerTeam3Name');
- ThemeLoadButton(PartyPlayer.Player9Name, 'PartyPlayerPlayer9Name');
- ThemeLoadButton(PartyPlayer.Player10Name, 'PartyPlayerPlayer10Name');
- ThemeLoadButton(PartyPlayer.Player11Name, 'PartyPlayerPlayer11Name');
- ThemeLoadButton(PartyPlayer.Player12Name, 'PartyPlayerPlayer12Name');
-
- {ThemeLoadButton(ButtonNext, 'PartyPlayerButtonNext');
- ThemeLoadButton(ButtonPrev, 'PartyPlayerButtonPrev');}
-
- ThemeLoadBasic(StatMain, 'StatMain');
-
- ThemeLoadButton(StatMain.ButtonScores, 'StatMainButtonScores');
- ThemeLoadButton(StatMain.ButtonSingers, 'StatMainButtonSingers');
- ThemeLoadButton(StatMain.ButtonSongs, 'StatMainButtonSongs');
- ThemeLoadButton(StatMain.ButtonBands, 'StatMainButtonBands');
- ThemeLoadButton(StatMain.ButtonExit, 'StatMainButtonExit');
-
- ThemeLoadText (StatMain.TextOverview, 'StatMainTextOverview');
-
-
- ThemeLoadBasic(StatDetail, 'StatDetail');
-
- ThemeLoadButton(StatDetail.ButtonNext, 'StatDetailButtonNext');
- ThemeLoadButton(StatDetail.ButtonPrev, 'StatDetailButtonPrev');
- ThemeLoadButton(StatDetail.ButtonReverse, 'StatDetailButtonReverse');
- ThemeLoadButton(StatDetail.ButtonExit, 'StatDetailButtonExit');
-
- ThemeLoadText (StatDetail.TextDescription, 'StatDetailTextDescription');
- ThemeLoadText (StatDetail.TextPage, 'StatDetailTextPage');
- ThemeLoadTexts(StatDetail.TextList, 'StatDetailTextList');
-
- //Translate Texts
- StatDetail.Description[0] := Language.Translate('STAT_DESC_SCORES');
- StatDetail.Description[1] := Language.Translate('STAT_DESC_SINGERS');
- StatDetail.Description[2] := Language.Translate('STAT_DESC_SONGS');
- StatDetail.Description[3] := Language.Translate('STAT_DESC_BANDS');
-
- StatDetail.DescriptionR[0] := Language.Translate('STAT_DESC_SCORES_REVERSED');
- StatDetail.DescriptionR[1] := Language.Translate('STAT_DESC_SINGERS_REVERSED');
- StatDetail.DescriptionR[2] := Language.Translate('STAT_DESC_SONGS_REVERSED');
- StatDetail.DescriptionR[3] := Language.Translate('STAT_DESC_BANDS_REVERSED');
-
- StatDetail.FormatStr[0] := Language.Translate('STAT_FORMAT_SCORES');
- StatDetail.FormatStr[1] := Language.Translate('STAT_FORMAT_SINGERS');
- StatDetail.FormatStr[2] := Language.Translate('STAT_FORMAT_SONGS');
- StatDetail.FormatStr[3] := Language.Translate('STAT_FORMAT_BANDS');
-
- StatDetail.PageStr := Language.Translate('STAT_PAGE');
-
- //Playlist Translations
- Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT');
-
- //Level Translations
- //Fill ILevel
- ILevel[0] := Language.Translate('SING_EASY');
- ILevel[1] := Language.Translate('SING_MEDIUM');
- ILevel[2] := Language.Translate('SING_HARD');
- end;
-
- ThemeIni.Free;
- end;
-end;
-
-procedure TTheme.ThemeLoadBasic(Theme: TThemeBasic; Name: string);
-begin
- ThemeLoadBackground(Theme.Background, Name);
- ThemeLoadTexts(Theme.Text, Name + 'Text');
- ThemeLoadStatics(Theme.Static, Name + 'Static');
- ThemeLoadButtonCollections(Theme.ButtonCollection, Name + 'ButtonCollection');
-
- LastThemeBasic := Theme;
-end;
-
-procedure TTheme.ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
-begin
- ThemeBackground.Tex := ThemeIni.ReadString(Name + 'Background', 'Tex', '');
-end;
-
-procedure TTheme.ThemeLoadText(var ThemeText: TThemeText; Name: string);
-var
- C: integer;
-begin
- ThemeText.X := ThemeIni.ReadInteger(Name, 'X', 0);
- ThemeText.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
- ThemeText.W := ThemeIni.ReadInteger(Name, 'W', 0);
-
- ThemeText.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
-
- ThemeText.ColR := ThemeIni.ReadFloat(Name, 'ColR', 0);
- ThemeText.ColG := ThemeIni.ReadFloat(Name, 'ColG', 0);
- ThemeText.ColB := ThemeIni.ReadFloat(Name, 'ColB', 0);
-
- ThemeText.Font := ThemeIni.ReadInteger(Name, 'Font', 0);
- ThemeText.Size := ThemeIni.ReadInteger(Name, 'Size', 0);
- ThemeText.Align := ThemeIni.ReadInteger(Name, 'Align', 0);
-
- ThemeText.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
- ThemeText.Color := ThemeIni.ReadString(Name, 'Color', '');
-
- //Reflection
- ThemeText.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0)) = 1;
- ThemeText.Reflectionspacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
-
- C := ColorExists(ThemeText.Color);
- if C >= 0 then begin
- ThemeText.ColR := Color[C].RGB.R;
- ThemeText.ColG := Color[C].RGB.G;
- ThemeText.ColB := Color[C].RGB.B;
- end;
-end;
-
-procedure TTheme.ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
-var
- T: integer;
-begin
- T := 1;
- while ThemeIni.SectionExists(Name + IntToStr(T)) do begin
- SetLength(ThemeText, T);
- ThemeLoadText(ThemeText[T-1], Name + IntToStr(T));
- Inc(T);
- end;
-end;
-
-procedure TTheme.ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
-var
- C: integer;
-begin
- ThemeStatic.Tex := ThemeIni.ReadString(Name, 'Tex', '');
-
- ThemeStatic.X := ThemeIni.ReadInteger(Name, 'X', 0);
- ThemeStatic.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
- ThemeStatic.Z := ThemeIni.ReadFloat (Name, 'Z', 0);
- ThemeStatic.W := ThemeIni.ReadInteger(Name, 'W', 0);
- ThemeStatic.H := ThemeIni.ReadInteger(Name, 'H', 0);
-
- ThemeStatic.Typ := ParseTextureType(ThemeIni.ReadString(Name, 'Type', ''), TEXTURE_TYPE_PLAIN);
- ThemeStatic.Color := ThemeIni.ReadString(Name, 'Color', '');
-
- C := ColorExists(ThemeStatic.Color);
- if C >= 0 then begin
- ThemeStatic.ColR := Color[C].RGB.R;
- ThemeStatic.ColG := Color[C].RGB.G;
- ThemeStatic.ColB := Color[C].RGB.B;
- end;
-
- ThemeStatic.TexX1 := ThemeIni.ReadFloat(Name, 'TexX1', 0);
- ThemeStatic.TexY1 := ThemeIni.ReadFloat(Name, 'TexY1', 0);
- ThemeStatic.TexX2 := ThemeIni.ReadFloat(Name, 'TexX2', 1);
- ThemeStatic.TexY2 := ThemeIni.ReadFloat(Name, 'TexY2', 1);
-
- //Reflection Mod
- ThemeStatic.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
- ThemeStatic.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
-end;
-
-procedure TTheme.ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
-var
- S: integer;
-begin
- S := 1;
- while ThemeIni.SectionExists(Name + IntToStr(S)) do begin
- SetLength(ThemeStatic, S);
- ThemeLoadStatic(ThemeStatic[S-1], Name + IntToStr(S));
- Inc(S);
- end;
-end;
-
-//Button Collection Mod
-procedure TTheme.ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
-var T: Integer;
-begin
- //Load Collection Style
- ThemeLoadButton(Collection.Style, Name);
-
- //Load Other Attributes
- T := ThemeIni.ReadInteger (Name, 'FirstChild', 0);
- if (T > 0) And (T < 256) then
- Collection.FirstChild := T
- else
- Collection.FirstChild := 0;
-end;
-
-procedure TTheme.ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string);
-var
- I: integer;
-begin
- I := 1;
- while ThemeIni.SectionExists(Name + IntToStr(I)) do begin
- SetLength(Collections, I);
- ThemeLoadButtonCollection(Collections[I-1], Name + IntToStr(I));
- Inc(I);
- end;
-end;
-//End Button Collection Mod
-
-procedure TTheme.ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection);
-var
- C: integer;
- TLen: integer;
- T: integer;
- Collections2: PAThemeButtonCollection;
-begin
- if not ThemeIni.SectionExists(Name) then
- begin
- ThemeButton.Visible := False;
- exit;
- end;
- ThemeButton.Tex := ThemeIni.ReadString(Name, 'Tex', '');
- ThemeButton.X := ThemeIni.ReadInteger (Name, 'X', 0);
- ThemeButton.Y := ThemeIni.ReadInteger (Name, 'Y', 0);
- ThemeButton.Z := ThemeIni.ReadFloat (Name, 'Z', 0);
- ThemeButton.W := ThemeIni.ReadInteger (Name, 'W', 0);
- ThemeButton.H := ThemeIni.ReadInteger (Name, 'H', 0);
- ThemeButton.Typ := ParseTextureType(ThemeIni.ReadString(Name, 'Type', ''), TEXTURE_TYPE_PLAIN);
-
- //Reflection Mod
- ThemeButton.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
- ThemeButton.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
-
- ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
- ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
- ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
- ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
- ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
- ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
- ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
- ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
-
- ThemeButton.Color := ThemeIni.ReadString(Name, 'Color', '');
- C := ColorExists(ThemeButton.Color);
- if C >= 0 then begin
- ThemeButton.ColR := Color[C].RGB.R;
- ThemeButton.ColG := Color[C].RGB.G;
- ThemeButton.ColB := Color[C].RGB.B;
- end;
-
- ThemeButton.DColor := ThemeIni.ReadString(Name, 'DColor', '');
- C := ColorExists(ThemeButton.DColor);
- if C >= 0 then begin
- ThemeButton.DColR := Color[C].RGB.R;
- ThemeButton.DColG := Color[C].RGB.G;
- ThemeButton.DColB := Color[C].RGB.B;
- end;
-
- ThemeButton.Visible := (ThemeIni.ReadInteger(Name, 'Visible', 1) = 1);
-
- //Fade Mod
- ThemeButton.SelectH := ThemeIni.ReadInteger (Name, 'SelectH', ThemeButton.H);
- ThemeButton.SelectW := ThemeIni.ReadInteger (Name, 'SelectW', ThemeButton.W);
-
- ThemeButton.DeSelectReflectionspacing := ThemeIni.ReadFloat(Name, 'DeSelectReflectionSpacing', ThemeButton.Reflectionspacing);
-
- ThemeButton.Fade := (ThemeIni.ReadInteger(Name, 'Fade', 0) = 1);
- ThemeButton.FadeText := (ThemeIni.ReadInteger(Name, 'FadeText', 0) = 1);
-
-
- ThemeButton.FadeTex := ThemeIni.ReadString(Name, 'FadeTex', '');
- ThemeButton.FadeTexPos:= ThemeIni.ReadInteger(Name, 'FadeTexPos', 0);
- if (ThemeButton.FadeTexPos > 4) Or (ThemeButton.FadeTexPos < 0) then
- ThemeButton.FadeTexPos := 0;
-
- //Button Collection Mod
- T := ThemeIni.ReadInteger(Name, 'Parent', 0);
-
- //Set Collections to Last Basic Collections if no valid Value
- if (Collections = nil) then
- Collections2 := @LastThemeBasic.ButtonCollection
- else
- Collections2 := Collections;
- //Test for valid Value
- if (Collections2 <> nil) AND (T > 0) AND (T <= Length(Collections2^)) then
- begin
- Inc(Collections2^[T-1].ChildCount);
- ThemeButton.Parent := T;
- end
- else
- ThemeButton.Parent := 0;
-
- //Read ButtonTexts
- TLen := ThemeIni.ReadInteger(Name, 'Texts', 0);
- SetLength(ThemeButton.Text, TLen);
- for T := 1 to TLen do
- ThemeLoadText(ThemeButton.Text[T-1], Name + 'Text' + IntToStr(T));
-end;
-
-procedure TTheme.ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
-var
- C: integer;
-begin
- ThemeSelectS.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
-
- ThemeSelectS.Tex := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'Tex', '');
- ThemeSelectS.TexSBG := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'TexSBG', '');
-
- ThemeSelectS.X := ThemeIni.ReadInteger(Name, 'X', 0);
- ThemeSelectS.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
- ThemeSelectS.W := ThemeIni.ReadInteger(Name, 'W', 0);
- ThemeSelectS.H := ThemeIni.ReadInteger(Name, 'H', 0);
-
- ThemeSelectS.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
-
- ThemeSelectS.TextSize := ThemeIni.ReadInteger(Name, 'TextSize', 10);
-
- ThemeSelectS.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0);
-
- ThemeSelectS.SBGW := ThemeIni.ReadInteger(Name, 'SBGW', 450);
-
- LoadColor(ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeIni.ReadString(Name, 'Color', ''));
- ThemeSelectS.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
- LoadColor(ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeIni.ReadString(Name, 'DColor', ''));
- ThemeSelectS.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
-
- LoadColor(ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeIni.ReadString(Name, 'TColor', ''));
- ThemeSelectS.TInt := ThemeIni.ReadFloat(Name, 'TInt', 1);
- LoadColor(ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeIni.ReadString(Name, 'TDColor', ''));
- ThemeSelectS.TDInt := ThemeIni.ReadFloat(Name, 'TDInt', 1);
-
- LoadColor(ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeIni.ReadString(Name, 'SBGColor', ''));
- ThemeSelectS.SBGInt := ThemeIni.ReadFloat(Name, 'SBGInt', 1);
- LoadColor(ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeIni.ReadString(Name, 'SBGDColor', ''));
- ThemeSelectS.SBGDInt := ThemeIni.ReadFloat(Name, 'SBGDInt', 1);
-
- LoadColor(ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeIni.ReadString(Name, 'STColor', ''));
- ThemeSelectS.STInt := ThemeIni.ReadFloat(Name, 'STInt', 1);
- LoadColor(ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeIni.ReadString(Name, 'STDColor', ''));
- ThemeSelectS.STDInt := ThemeIni.ReadFloat(Name, 'STDInt', 1);
-end;
-
-procedure TTheme.LoadColors;
-var
- SL: TStringList;
- C: integer;
- S: string;
- Col: integer;
- RGB: TRGB;
-begin
- SL := TStringList.Create;
- ThemeIni.ReadSection('Colors', SL);
-
- // normal colors
- SetLength(Color, SL.Count);
- for C := 0 to SL.Count-1 do begin
- Color[C].Name := SL.Strings[C];
-
- S := ThemeIni.ReadString('Colors', SL.Strings[C], '');
-
- Color[C].RGB.R := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
- Delete(S, 1, Pos(' ', S));
-
- Color[C].RGB.G := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
- Delete(S, 1, Pos(' ', S));
-
- Color[C].RGB.B := StrToInt(S)/255;
- end;
-
- // skin color
- SetLength(Color, SL.Count + 3);
- C := SL.Count;
- Color[C].Name := 'ColorDark';
- Color[C].RGB := GetSystemColor(Skin.Color); //Ini.Color);
-
- C := C+1;
- Color[C].Name := 'ColorLight';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'ColorLightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // players colors
- SetLength(Color, Length(Color)+18);
-
- // P1
- C := C+1;
- Color[C].Name := 'P1Dark';
- Color[C].RGB := GetSystemColor(0); // 0 - blue
-
- C := C+1;
- Color[C].Name := 'P1Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P1Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // P2
- C := C+1;
- Color[C].Name := 'P2Dark';
- Color[C].RGB := GetSystemColor(3); // 3 - red
-
- C := C+1;
- Color[C].Name := 'P2Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P2Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // P3
- C := C+1;
- Color[C].Name := 'P3Dark';
- Color[C].RGB := GetSystemColor(1); // 1 - green
-
- C := C+1;
- Color[C].Name := 'P3Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P3Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // P4
- C := C+1;
- Color[C].Name := 'P4Dark';
- Color[C].RGB := GetSystemColor(4); // 4 - brown
-
- C := C+1;
- Color[C].Name := 'P4Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P4Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // P5
- C := C+1;
- Color[C].Name := 'P5Dark';
- Color[C].RGB := GetSystemColor(5); // 5 - yellow
-
- C := C+1;
- Color[C].Name := 'P5Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P5Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- // P6
- C := C+1;
- Color[C].Name := 'P6Dark';
- Color[C].RGB := GetSystemColor(6); // 6 - violet
-
- C := C+1;
- Color[C].Name := 'P6Light';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
- C := C+1;
- Color[C].Name := 'P6Lightest';
- Color[C].RGB := ColorSqrt(Color[C-1].RGB);
-
-
- SL.Free;
-end;
-
-function ColorExists(Name: string): integer;
-var
- C: integer;
-begin
- Result := -1;
- for C := 0 to High(Color) do
- if Color[C].Name = Name then Result := C;
-end;
-
-procedure LoadColor(var R, G, B: real; ColorName: string);
-var
- C: integer;
-begin
- C := ColorExists(ColorName);
- if C >= 0 then begin
- R := Color[C].RGB.R;
- G := Color[C].RGB.G;
- B := Color[C].RGB.B;
- end;
-end;
-
-function GetSystemColor(Color: integer): TRGB;
-begin
- case Color of
- 0: begin
- // blue
- Result.R := 71/255;
- Result.G := 175/255;
- Result.B := 247/255;
- end;
- 1: begin
- // green
- Result.R := 63/255;
- Result.G := 191/255;
- Result.B := 63/255;
- end;
- 2: begin
- // pink
- Result.R := 255/255;
-{ Result.G := 63/255;
- Result.B := 192/255;}
- Result.G := 175/255;
- Result.B := 247/255;
- end;
- 3: begin
- // red
- Result.R := 247/255;
- Result.G := 71/255;
- Result.B := 71/255;
- end;
- //'Violet', 'Orange', 'Yellow', 'Brown', 'Black'
- //New Theme-Color Patch
- 4: begin
- // violet
- Result.R := 230/255;
- Result.G := 63/255;
- Result.B := 230/255;
- end;
- 5: begin
- // orange
- Result.R := 255/255;
- Result.G := 144/255;
- Result.B := 0;
- end;
- 6: begin
- // yellow
- Result.R := 230/255;
- Result.G := 230/255;
- Result.B := 95/255;
- end;
- 7: begin
- // brown
- Result.R := 192/255;
- Result.G := 127/255;
- Result.B := 31/255;
- end;
- 8: begin
- // black
- Result.R := 0;
- Result.G := 0;
- Result.B := 0;
- end;
- //New Theme-Color Patch End
-
- end;
-end;
-
-function ColorSqrt(RGB: TRGB): TRGB;
-begin
- Result.R := sqrt(RGB.R);
- Result.G := sqrt(RGB.G);
- Result.B := sqrt(RGB.B);
-end;
-
-procedure TTheme.ThemeSave(FileName: string);
-var
- I: integer;
-begin
- {$IFDEF THEMESAVE}
- ThemeIni := TIniFile.Create(FileName);
- {$ELSE}
- ThemeIni := TMemIniFile.Create(FileName);
- {$ENDIF}
-
- ThemeSaveBasic(Loading, 'Loading');
-
- ThemeSaveBasic(Main, 'Main');
- ThemeSaveText(Main.TextDescription, 'MainTextDescription');
- ThemeSaveText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
- ThemeSaveButton(Main.ButtonSolo, 'MainButtonSolo');
- ThemeSaveButton(Main.ButtonEditor, 'MainButtonEditor');
- ThemeSaveButton(Main.ButtonOptions, 'MainButtonOptions');
- ThemeSaveButton(Main.ButtonExit, 'MainButtonExit');
-
- ThemeSaveBasic(Name, 'Name');
- for I := 1 to 6 do
- ThemeSaveButton(Name.ButtonPlayer[I], 'NameButtonPlayer' + IntToStr(I));
-
- ThemeSaveBasic(Level, 'Level');
- ThemeSaveButton(Level.ButtonEasy, 'LevelButtonEasy');
- ThemeSaveButton(Level.ButtonMedium, 'LevelButtonMedium');
- ThemeSaveButton(Level.ButtonHard, 'LevelButtonHard');
-
- ThemeSaveBasic(Song, 'Song');
- ThemeSaveText(Song.TextArtist, 'SongTextArtist');
- ThemeSaveText(Song.TextTitle, 'SongTextTitle');
- ThemeSaveText(Song.TextNumber, 'SongTextNumber');
-
- //Show CAt in Top Left Mod
- ThemeSaveText(Song.TextCat, 'SongTextCat');
- ThemeSaveStatic(Song.StaticCat, 'SongStaticCat');
-
- ThemeSaveBasic(Sing, 'Sing');
-
- //TimeBar mod
- ThemeSaveStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
- ThemeSaveText(Sing.TextTimeText, 'SingTimeText');
- //eoa TimeBar mod
-
- ThemeSaveStatic(Sing.StaticP1, 'SingP1Static');
- ThemeSaveText(Sing.TextP1, 'SingP1Text');
- ThemeSaveStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
- ThemeSaveText(Sing.TextP1Score, 'SingP1TextScore');
-
- //moveable singbar mod
- ThemeSaveStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
- ThemeSaveStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
- ThemeSaveStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
- ThemeSaveStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
- ThemeSaveStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
- ThemeSaveStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
- //eoa moveable singbar
-
- //Added for ps3 skin
- //This one is shown in 2/4P mode
- ThemeSaveStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
- ThemeSaveText(Sing.TextP1TwoP, 'SingP1TwoPText');
- ThemeSaveStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
- ThemeSaveText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
-
- //This one is shown in 3/6P mode
- ThemeSaveStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
- ThemeSaveText(Sing.TextP1ThreeP, 'SingP1ThreePText');
- ThemeSaveStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
- ThemeSaveText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
- //eoa
-
- ThemeSaveStatic(Sing.StaticP2R, 'SingP2RStatic');
- ThemeSaveText(Sing.TextP2R, 'SingP2RText');
- ThemeSaveStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
- ThemeSaveText(Sing.TextP2RScore, 'SingP2RTextScore');
-
- ThemeSaveStatic(Sing.StaticP2M, 'SingP2MStatic');
- ThemeSaveText(Sing.TextP2M, 'SingP2MText');
- ThemeSaveStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
- ThemeSaveText(Sing.TextP2MScore, 'SingP2MTextScore');
-
- ThemeSaveStatic(Sing.StaticP3R, 'SingP3RStatic');
- ThemeSaveText(Sing.TextP3R, 'SingP3RText');
- ThemeSaveStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
- ThemeSaveText(Sing.TextP3RScore, 'SingP3RTextScore');
-
- ThemeSaveBasic(Score, 'Score');
- ThemeSaveText(Score.TextArtist, 'ScoreTextArtist');
- ThemeSaveText(Score.TextTitle, 'ScoreTextTitle');
-
- for I := 1 to 6 do begin
- ThemeSaveStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
-
- ThemeSaveText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
- ThemeSaveText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
- ThemeSaveText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
- ThemeSaveText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
- ThemeSaveText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
- ThemeSaveText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
- ThemeSaveText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
- ThemeSaveText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
- ThemeSaveText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
- ThemeSaveText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
-
- ThemeSaveStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
- ThemeSaveStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
- ThemeSaveStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
- ThemeSaveStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
- end;
-
- ThemeSaveBasic(Top5, 'Top5');
- ThemeSaveText(Top5.TextLevel, 'Top5TextLevel');
- ThemeSaveText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
- ThemeSaveStatics(Top5.StaticNumber, 'Top5StaticNumber');
- ThemeSaveTexts(Top5.TextNumber, 'Top5TextNumber');
- ThemeSaveTexts(Top5.TextName, 'Top5TextName');
- ThemeSaveTexts(Top5.TextScore, 'Top5TextScore');
-
-
- ThemeIni.Free;
-end;
-
-procedure TTheme.ThemeSaveBasic(Theme: TThemeBasic; Name: string);
-begin
- ThemeIni.WriteInteger(Name, 'Texts', Length(Theme.Text));
-
- ThemeSaveBackground(Theme.Background, Name + 'Background');
- ThemeSaveStatics(Theme.Static, Name + 'Static');
- ThemeSaveTexts(Theme.Text, Name + 'Text');
-end;
-
-procedure TTheme.ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
-begin
- if ThemeBackground.Tex <> '' then
- ThemeIni.WriteString(Name, 'Tex', ThemeBackground.Tex)
- else begin
- ThemeIni.EraseSection(Name);
- end;
-end;
-
-procedure TTheme.ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
-begin
- ThemeIni.WriteInteger(Name, 'X', ThemeStatic.X);
- ThemeIni.WriteInteger(Name, 'Y', ThemeStatic.Y);
- ThemeIni.WriteInteger(Name, 'W', ThemeStatic.W);
- ThemeIni.WriteInteger(Name, 'H', ThemeStatic.H);
-
- ThemeIni.WriteString(Name, 'Tex', ThemeStatic.Tex);
- ThemeIni.WriteString(Name, 'Type', TextureTypeToStr(ThemeStatic.Typ));
- ThemeIni.WriteString(Name, 'Color', ThemeStatic.Color);
-
- ThemeIni.WriteFloat(Name, 'TexX1', ThemeStatic.TexX1);
- ThemeIni.WriteFloat(Name, 'TexY1', ThemeStatic.TexY1);
- ThemeIni.WriteFloat(Name, 'TexX2', ThemeStatic.TexX2);
- ThemeIni.WriteFloat(Name, 'TexY2', ThemeStatic.TexY2);
-end;
-
-procedure TTheme.ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
-var
- S: integer;
-begin
- for S := 0 to Length(ThemeStatic)-1 do
- ThemeSaveStatic(ThemeStatic[S], Name + {'Static' +} IntToStr(S+1));
-
- ThemeIni.EraseSection(Name + {'Static' + }IntToStr(S+1));
-end;
-
-procedure TTheme.ThemeSaveText(ThemeText: TThemeText; Name: string);
-begin
- ThemeIni.WriteInteger(Name, 'X', ThemeText.X);
- ThemeIni.WriteInteger(Name, 'Y', ThemeText.Y);
-
- ThemeIni.WriteInteger(Name, 'Font', ThemeText.Font);
- ThemeIni.WriteInteger(Name, 'Size', ThemeText.Size);
- ThemeIni.WriteInteger(Name, 'Align', ThemeText.Align);
-
- ThemeIni.WriteString(Name, 'Text', ThemeText.Text);
- ThemeIni.WriteString(Name, 'Color', ThemeText.Color);
-
- ThemeIni.WriteBool(Name, 'Reflection', ThemeText.Reflection);
- ThemeIni.WriteFloat(Name, 'ReflectionSpacing', ThemeText.ReflectionSpacing);
-end;
-
-procedure TTheme.ThemeSaveTexts(ThemeText: AThemeText; Name: string);
-var
- T: integer;
-begin
- for T := 0 to Length(ThemeText)-1 do
- ThemeSaveText(ThemeText[T], Name + {'Text' + }IntToStr(T+1));
-
- ThemeIni.EraseSection(Name + {'Text' + }IntToStr(T+1));
-end;
-
-procedure TTheme.ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
-var
- T: integer;
-begin
- ThemeIni.WriteString(Name, 'Tex', ThemeButton.Tex);
- ThemeIni.WriteInteger(Name, 'X', ThemeButton.X);
- ThemeIni.WriteInteger(Name, 'Y', ThemeButton.Y);
- ThemeIni.WriteInteger(Name, 'W', ThemeButton.W);
- ThemeIni.WriteInteger(Name, 'H', ThemeButton.H);
- ThemeIni.WriteString(Name, 'Type', TextureTypeToStr(ThemeButton.Typ));
- ThemeIni.WriteInteger(Name, 'Texts', Length(ThemeButton.Text));
-
- ThemeIni.WriteString(Name, 'Color', ThemeButton.Color);
-
-{ ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
- ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
- ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
- ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
- ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
- ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
- ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
- ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);}
-
-{ C := ColorExists(ThemeIni.ReadString(Name, 'Color', ''));
- if C >= 0 then begin
- ThemeButton.ColR := Color[C].RGB.R;
- ThemeButton.ColG := Color[C].RGB.G;
- ThemeButton.ColB := Color[C].RGB.B;
- end;
-
- C := ColorExists(ThemeIni.ReadString(Name, 'DColor', ''));
- if C >= 0 then begin
- ThemeButton.DColR := Color[C].RGB.R;
- ThemeButton.DColG := Color[C].RGB.G;
- ThemeButton.DColB := Color[C].RGB.B;
- end;}
-
- for T := 0 to High(ThemeButton.Text) do
- ThemeSaveText(ThemeButton.Text[T], Name + 'Text' + IntToStr(T+1));
-end;
-
-procedure TTheme.create_theme_objects();
-begin
- freeandnil( Loading );
- Loading := TThemeLoading.Create;
-
- freeandnil( Main );
- Main := TThemeMain.Create;
-
- freeandnil( Name );
- Name := TThemeName.Create;
-
- freeandnil( Level );
- Level := TThemeLevel.Create;
-
- freeandnil( Song );
- Song := TThemeSong.Create;
-
- freeandnil( Sing );
- Sing := TThemeSing.Create;
-
- freeandnil( Score );
- Score := TThemeScore.Create;
-
- freeandnil( Top5 );
- Top5 := TThemeTop5.Create;
-
- freeandnil( Options );
- Options := TThemeOptions.Create;
-
- freeandnil( OptionsGame );
- OptionsGame := TThemeOptionsGame.Create;
-
- freeandnil( OptionsGraphics );
- OptionsGraphics := TThemeOptionsGraphics.Create;
-
- freeandnil( OptionsSound );
- OptionsSound := TThemeOptionsSound.Create;
-
- freeandnil( OptionsLyrics );
- OptionsLyrics := TThemeOptionsLyrics.Create;
-
- freeandnil( OptionsThemes );
- OptionsThemes := TThemeOptionsThemes.Create;
-
- freeandnil( OptionsRecord );
- OptionsRecord := TThemeOptionsRecord.Create;
-
- freeandnil( OptionsAdvanced );
- OptionsAdvanced := TThemeOptionsAdvanced.Create;
-
-
- freeandnil( ErrorPopup );
- ErrorPopup := TThemeError.Create;
-
- freeandnil( CheckPopup );
- CheckPopup := TThemeCheck.Create;
-
-
- freeandnil( SongMenu );
- SongMenu := TThemeSongMenu.Create;
-
- freeandnil( SongJumpto );
- SongJumpto := TThemeSongJumpto.Create;
-
- //Party Screens
- freeandnil( PartyNewRound );
- PartyNewRound := TThemePartyNewRound.Create;
-
- freeandnil( PartyWin );
- PartyWin := TThemePartyWin.Create;
-
- freeandnil( PartyScore );
- PartyScore := TThemePartyScore.Create;
-
- freeandnil( PartyOptions );
- PartyOptions := TThemePartyOptions.Create;
-
- freeandnil( PartyPlayer );
- PartyPlayer := TThemePartyPlayer.Create;
-
-
- //Stats Screens:
- freeandnil( StatMain );
- StatMain := TThemeStatMain.Create;
-
- freeandnil( StatDetail );
- StatDetail := TThemeStatDetail.Create;
-
- end;
-
-end.
diff --git a/Game/Code/Classes/UTime.pas b/Game/Code/Classes/UTime.pas
deleted file mode 100644
index f8ae91c4..00000000
--- a/Game/Code/Classes/UTime.pas
+++ /dev/null
@@ -1,185 +0,0 @@
-unit UTime;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-type
- TTime = class
- public
- constructor Create;
- function GetTime(): real;
- end;
-
- TRelativeTimer = class
- private
- AbsoluteTime: int64; // system-clock reference time for calculation of CurrentTime
- RelativeTimeOffset: real;
- Paused: boolean;
- TriggerMode: boolean;
- public
- constructor Create(TriggerMode: boolean = false);
- procedure Pause();
- procedure Resume();
- function GetTime(): real;
- function GetAndResetTime(): real;
- procedure SetTime(Time: real; Trigger: boolean = true);
- procedure Reset();
- end;
-
-procedure CountSkipTimeSet;
-procedure CountSkipTime;
-procedure CountMidTime;
-
-var
- USTime : TTime;
- VideoBGTimer: TRelativeTimer;
-
- TimeNew : int64;
- TimeOld : int64;
- TimeSkip : real;
- TimeMid : real;
- TimeMidTemp : int64;
-
-implementation
-
-uses
- sdl,
- ucommon;
-
-const
- cSDLCorrectionRatio = 1000;
-
-(*
-BEST Option now ( after discussion with whiteshark ) seems to be to use SDL
-timer functions...
-
-SDL_delay
-SDL_GetTicks
-http://www.gamedev.net/community/forums/topic.asp?topic_id=466145&whichpage=1%EE%8D%B7
-*)
-
-
-procedure CountSkipTimeSet;
-begin
- TimeNew := SDL_GetTicks();
-end;
-
-procedure CountSkipTime;
-begin
- TimeOld := TimeNew;
- TimeNew := SDL_GetTicks();
- TimeSkip := (TimeNew-TimeOld) / cSDLCorrectionRatio;
-end;
-
-procedure CountMidTime;
-begin
- TimeMidTemp := SDL_GetTicks();
- TimeMid := (TimeMidTemp - TimeNew) / cSDLCorrectionRatio;
-end;
-
-{**
- * TTime
- **}
-
-constructor TTime.Create;
-begin
- inherited;
- CountSkipTimeSet;
-end;
-
-function TTime.GetTime: real;
-begin
- Result := SDL_GetTicks() / cSDLCorrectionRatio;
-end;
-
-{**
- * TRelativeTimer
- **}
-
-(*
- * Creates a new timer.
- * If TriggerMode is false (default), the timer
- * will immediately begin with counting.
- * If TriggerMode is true, it will wait until Get/SetTime() or Pause() is called
- * for the first time.
- *)
-constructor TRelativeTimer.Create(TriggerMode: boolean);
-begin
- inherited Create();
- Self.TriggerMode := TriggerMode;
- Reset();
- Paused := false;
-end;
-
-procedure TRelativeTimer.Pause();
-begin
- RelativeTimeOffset := GetTime();
- Paused := true;
-end;
-
-procedure TRelativeTimer.Resume();
-begin
- AbsoluteTime := SDL_GetTicks();
- Paused := false;
-end;
-
-(*
- * Returns the counter of the timer.
- * If in TriggerMode it will return 0 and start the counter on the first call.
- *)
-function TRelativeTimer.GetTime: real;
-begin
- // initialize absolute time on first call in triggered mode
- if (TriggerMode and (AbsoluteTime = 0)) then
- begin
- AbsoluteTime := SDL_GetTicks();
- Result := RelativeTimeOffset;
- Exit;
- end;
-
- if Paused then
- Result := RelativeTimeOffset
- else
- Result := RelativeTimeOffset + (SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
-end;
-
-(*
- * Returns the counter of the timer and resets the counter to 0 afterwards.
- * Note: In TriggerMode the counter will not be stopped as with Reset().
- *)
-function TRelativeTimer.GetAndResetTime(): real;
-begin
- Result := GetTime();
- SetTime(0);
-end;
-
-(*
- * Sets the timer to the given time. This will trigger in TriggerMode if
- * Trigger is set to true. Otherwise the counter's state will not change.
- *)
-procedure TRelativeTimer.SetTime(Time: real; Trigger: boolean);
-begin
- RelativeTimeOffset := Time;
- if ((not TriggerMode) or Trigger) then
- AbsoluteTime := SDL_GetTicks();
-end;
-
-(*
- * Resets the counter of the timer to 0.
- * If in TriggerMode the timer will not start counting until it is triggered again.
- *)
-procedure TRelativeTimer.Reset();
-begin
- RelativeTimeOffset := 0;
- if (TriggerMode) then
- AbsoluteTime := 0
- else
- AbsoluteTime := SDL_GetTicks();
-end;
-
-end.
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas
deleted file mode 100644
index 0ab1d350..00000000
--- a/Game/Code/Classes/UVideo.pas
+++ /dev/null
@@ -1,828 +0,0 @@
-{##############################################################################
- # FFmpeg support for UltraStar deluxe #
- # #
- # Created by b1indy #
- # based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) #
- # with modifications by Jay Binks #
- # #
- # http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg09949.html #
- # http://www.nabble.com/file/p11795857/mpegpas01.zip #
- # #
- ##############################################################################}
-
-unit UVideo;
-
-// uncomment if you want to see the debug stuff
-{.$define DebugDisplay}
-{.$define DebugFrames}
-{.$define VideoBenchmark}
-{.$define Info}
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-// use BGR-format for accelerated colorspace conversion with swscale
-{$IFDEF UseSWScale}
- {$DEFINE PIXEL_FMT_BGR}
-{$ENDIF}
-
-implementation
-
-uses
- SDL,
- textgl,
- avcodec,
- avformat,
- avutil,
- avio,
- rational,
- {$IFDEF UseSWScale}
- swscale,
- {$ENDIF}
- UMediaCore_FFmpeg,
- math,
- gl,
- glext,
- SysUtils,
- UCommon,
- UConfig,
- ULog,
- UMusic,
- UGraphicClasses,
- UGraphic;
-
-const
-{$IFDEF PIXEL_FMT_BGR}
- PIXEL_FMT_OPENGL = GL_BGR;
- PIXEL_FMT_FFMPEG = PIX_FMT_BGR24;
-{$ELSE}
- PIXEL_FMT_OPENGL = GL_RGB;
- PIXEL_FMT_FFMPEG = PIX_FMT_RGB24;
-{$ENDIF}
-
-type
- TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback )
- private
- fVideoOpened,
- fVideoPaused: Boolean;
-
- VideoStream: PAVStream;
- VideoStreamIndex : Integer;
- VideoFormatContext: PAVFormatContext;
- VideoCodecContext: PAVCodecContext;
- VideoCodec: PAVCodec;
-
- AVFrame: PAVFrame;
- AVFrameRGB: PAVFrame;
- FrameBuffer: PByte;
-
- {$IFDEF UseSWScale}
- SoftwareScaleContext: PSwsContext;
- {$ENDIF}
-
- fVideoTex: GLuint;
- TexWidth, TexHeight: Cardinal;
-
- VideoAspect: Real;
- VideoTimeBase, VideoTime: Extended;
- fLoopTime: Extended;
-
- EOF: boolean;
- Loop: boolean;
-
- Initialized: boolean;
-
- procedure Reset();
- function DecodeFrame(var AVPacket: TAVPacket; out pts: double): boolean;
- procedure SynchronizeVideo(Frame: PAVFrame; var pts: double);
- public
- function GetName: String;
-
- function Init(): boolean;
- function Finalize: boolean;
-
- function Open(const aFileName : string): boolean; // true if succeed
- procedure Close;
-
- procedure Play;
- procedure Pause;
- procedure Stop;
-
- procedure SetPosition(Time: real);
- function GetPosition: real;
-
- procedure GetFrame(Time: Extended);
- procedure DrawGL(Screen: integer);
- end;
-
-var
- FFmpegCore: TMediaCore_FFmpeg;
-
-
-// These are called whenever we allocate a frame buffer.
-// We use this to store the global_pts in a frame at the time it is allocated.
-function PtsGetBuffer(CodecCtx: PAVCodecContext; Frame: PAVFrame): integer; cdecl;
-var
- pts: Pint64;
- VideoPktPts: Pint64;
-begin
- Result := avcodec_default_get_buffer(CodecCtx, Frame);
- VideoPktPts := CodecCtx^.opaque;
- if (VideoPktPts <> nil) then
- begin
- // Note: we must copy the pts instead of passing a pointer, because the packet
- // (and with it the pts) might change before a frame is returned by av_decode_video.
- pts := av_malloc(sizeof(int64));
- pts^ := VideoPktPts^;
- Frame^.opaque := pts;
- end;
-end;
-
-procedure PtsReleaseBuffer(CodecCtx: PAVCodecContext; Frame: PAVFrame); cdecl;
-begin
- if (Frame <> nil) then
- av_freep(@Frame^.opaque);
- avcodec_default_release_buffer(CodecCtx, Frame);
-end;
-
-
-{*------------------------------------------------------------------------------
- * TVideoPlayback_ffmpeg
- *------------------------------------------------------------------------------}
-
-function TVideoPlayback_FFmpeg.GetName: String;
-begin
- result := 'FFmpeg_Video';
-end;
-
-function TVideoPlayback_FFmpeg.Init(): boolean;
-begin
- Result := true;
-
- if (Initialized) then
- Exit;
- Initialized := true;
-
- FFmpegCore := TMediaCore_FFmpeg.GetInstance();
-
- Reset();
- av_register_all();
- glGenTextures(1, PGLuint(@fVideoTex));
-end;
-
-function TVideoPlayback_FFmpeg.Finalize(): boolean;
-begin
- Close();
- glDeleteTextures(1, PGLuint(@fVideoTex));
- Result := true;
-end;
-
-procedure TVideoPlayback_FFmpeg.Reset();
-begin
- // close previously opened video
- Close();
-
- fVideoOpened := False;
- fVideoPaused := False;
- VideoTimeBase := 0;
- VideoTime := 0;
- VideoStream := nil;
- VideoStreamIndex := -1;
-
- EOF := false;
-
- // TODO: do we really want this by default?
- Loop := true;
- fLoopTime := 0;
-end;
-
-function TVideoPlayback_FFmpeg.Open(const aFileName : string): boolean; // true if succeed
-var
- errnum: Integer;
- AudioStreamIndex: integer;
-begin
- Result := false;
-
- Reset();
-
- errnum := av_open_input_file(VideoFormatContext, PChar(aFileName), nil, 0, nil);
- if (errnum <> 0) then
- begin
- Log.LogError('Failed to open file "'+aFileName+'" ('+FFmpegCore.GetErrorString(errnum)+')');
- Exit;
- end;
-
- // update video info
- if (av_find_stream_info(VideoFormatContext) < 0) then
- begin
- Log.LogError('No stream info found', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
- Log.LogInfo('VideoStreamIndex : ' + inttostr(VideoStreamIndex), 'TVideoPlayback_ffmpeg.Open');
-
- // find video stream
- FFmpegCore.FindStreamIDs(VideoFormatContext, VideoStreamIndex, AudioStreamIndex);
- if (VideoStreamIndex < 0) then
- begin
- Log.LogError('No video stream found', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
-
- VideoStream := VideoFormatContext^.streams[VideoStreamIndex];
- VideoCodecContext := VideoStream^.codec;
-
- VideoCodec := avcodec_find_decoder(VideoCodecContext^.codec_id);
- if (VideoCodec = nil) then
- begin
- Log.LogError('No matching codec found', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
-
- // set debug options
- VideoCodecContext^.debug_mv := 0;
- VideoCodecContext^.debug := 0;
-
- // detect bug-workarounds automatically
- VideoCodecContext^.workaround_bugs := FF_BUG_AUTODETECT;
- // error resilience strategy (careful/compliant/agressive/very_aggressive)
- //VideoCodecContext^.error_resilience := FF_ER_CAREFUL; //FF_ER_COMPLIANT;
- // allow non spec compliant speedup tricks.
- //VideoCodecContext^.flags2 := VideoCodecContext^.flags2 or CODEC_FLAG2_FAST;
-
- // Note: avcodec_open() and avcodec_close() are not thread-safe and will
- // fail if called concurrently by different threads.
- FFmpegCore.LockAVCodec();
- try
- errnum := avcodec_open(VideoCodecContext, VideoCodec);
- finally
- FFmpegCore.UnlockAVCodec();
- end;
- if (errnum < 0) then
- begin
- Log.LogError('No matching codec found', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
-
- // register custom callbacks for pts-determination
- VideoCodecContext^.get_buffer := PtsGetBuffer;
- VideoCodecContext^.release_buffer := PtsReleaseBuffer;
-
- {$ifdef DebugDisplay}
- DebugWriteln('Found a matching Codec: '+ VideoCodecContext^.Codec.Name + sLineBreak +
- sLineBreak +
- ' Width = '+inttostr(VideoCodecContext^.width) +
- ', Height='+inttostr(VideoCodecContext^.height) + sLineBreak +
- ' Aspect : '+inttostr(VideoCodecContext^.sample_aspect_ratio.num) + '/' +
- inttostr(VideoCodecContext^.sample_aspect_ratio.den) + sLineBreak +
- ' Framerate : '+inttostr(VideoCodecContext^.time_base.num) + '/' +
- inttostr(VideoCodecContext^.time_base.den));
- {$endif}
-
- // allocate space for decoded frame and rgb frame
- AVFrame := avcodec_alloc_frame();
- AVFrameRGB := avcodec_alloc_frame();
- FrameBuffer := av_malloc(avpicture_get_size(PIXEL_FMT_FFMPEG,
- VideoCodecContext^.width, VideoCodecContext^.height));
-
- if ((AVFrame = nil) or (AVFrameRGB = nil) or (FrameBuffer = nil)) then
- begin
- Log.LogError('Failed to allocate buffers', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
-
- // TODO: pad data for OpenGL to GL_UNPACK_ALIGNMENT
- // (otherwise video will be distorted if width/height is not a multiple of the alignment)
- errnum := avpicture_fill(PAVPicture(AVFrameRGB), FrameBuffer, PIXEL_FMT_FFMPEG,
- VideoCodecContext^.width, VideoCodecContext^.height);
- if (errnum < 0) then
- begin
- Log.LogError('avpicture_fill failed: ' + FFmpegCore.GetErrorString(errnum), 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
-
- // calculate some information for video display
- VideoAspect := av_q2d(VideoCodecContext^.sample_aspect_ratio);
- if (VideoAspect = 0) then
- VideoAspect := VideoCodecContext^.width /
- VideoCodecContext^.height
- else
- VideoAspect := VideoAspect * VideoCodecContext^.width /
- VideoCodecContext^.height;
-
- VideoTimeBase := 1/av_q2d(VideoStream^.r_frame_rate);
-
- // hack to get reasonable timebase (for divx and others)
- if (VideoTimeBase < 0.02) then // 0.02 <-> 50 fps
- begin
- VideoTimeBase := av_q2d(VideoStream^.r_frame_rate);
- while (VideoTimeBase > 50) do
- VideoTimeBase := VideoTimeBase/10;
- VideoTimeBase := 1/VideoTimeBase;
- end;
-
- Log.LogInfo('VideoTimeBase: ' + floattostr(VideoTimeBase), 'TVideoPlayback_ffmpeg.Open');
- Log.LogInfo('Framerate: '+inttostr(floor(1/VideoTimeBase))+'fps', 'TVideoPlayback_ffmpeg.Open');
-
- {$IFDEF UseSWScale}
- // if available get a SWScale-context -> faster than the deprecated img_convert().
- // SWScale has accelerated support for PIX_FMT_RGB32/PIX_FMT_BGR24/PIX_FMT_BGR565/PIX_FMT_BGR555.
- // Note: PIX_FMT_RGB32 is a BGR- and not an RGB-format (maybe a bug)!!!
- // The BGR565-formats (GL_UNSIGNED_SHORT_5_6_5) is way too slow because of its
- // bad OpenGL support. The BGR formats have MMX(2) implementations but no speed-up
- // could be observed in comparison to the RGB versions.
- SoftwareScaleContext := sws_getContext(
- VideoCodecContext^.width, VideoCodecContext^.height,
- integer(VideoCodecContext^.pix_fmt),
- VideoCodecContext^.width, VideoCodecContext^.height,
- integer(PIXEL_FMT_FFMPEG),
- SWS_FAST_BILINEAR, nil, nil, nil);
- if (SoftwareScaleContext = nil) then
- begin
- Log.LogError('Failed to get swscale context', 'TVideoPlayback_ffmpeg.Open');
- Close();
- Exit;
- end;
- {$ENDIF}
-
- TexWidth := Round(Power(2, Ceil(Log2(VideoCodecContext^.width))));
- TexHeight := Round(Power(2, Ceil(Log2(VideoCodecContext^.height))));
-
- // we retrieve a texture just once with glTexImage2D and update it with glTexSubImage2D later.
- // Benefits: glTexSubImage2D is faster and supports non-power-of-two widths/height.
- glBindTexture(GL_TEXTURE_2D, fVideoTex);
- glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexImage2D(GL_TEXTURE_2D, 0, 3, TexWidth, TexHeight, 0,
- PIXEL_FMT_OPENGL, GL_UNSIGNED_BYTE, nil);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-
- fVideoOpened := True;
-
- Result := true;
-end;
-
-procedure TVideoPlayback_FFmpeg.Close;
-begin
- if (FrameBuffer <> nil) then
- av_free(FrameBuffer);
- if (AVFrameRGB <> nil) then
- av_free(AVFrameRGB);
- if (AVFrame <> nil) then
- av_free(AVFrame);
-
- AVFrame := nil;
- AVFrameRGB := nil;
- FrameBuffer := nil;
-
- if (VideoCodecContext <> nil) then
- begin
- // avcodec_close() is not thread-safe
- FFmpegCore.LockAVCodec();
- try
- avcodec_close(VideoCodecContext);
- finally
- FFmpegCore.UnlockAVCodec();
- end;
- end;
-
- if (VideoFormatContext <> nil) then
- av_close_input_file(VideoFormatContext);
-
- VideoCodecContext := nil;
- VideoFormatContext := nil;
-
- fVideoOpened := False;
-end;
-
-procedure TVideoPlayback_FFmpeg.SynchronizeVideo(Frame: PAVFrame; var pts: double);
-var
- FrameDelay: double;
-begin
- if (pts <> 0) then
- begin
- // if we have pts, set video clock to it
- VideoTime := pts;
- end else
- begin
- // if we aren't given a pts, set it to the clock
- pts := VideoTime;
- end;
- // update the video clock
- FrameDelay := av_q2d(VideoCodecContext^.time_base);
- // if we are repeating a frame, adjust clock accordingly
- FrameDelay := FrameDelay + Frame^.repeat_pict * (FrameDelay * 0.5);
- VideoTime := VideoTime + FrameDelay;
-end;
-
-function TVideoPlayback_FFmpeg.DecodeFrame(var AVPacket: TAVPacket; out pts: double): boolean;
-var
- FrameFinished: Integer;
- VideoPktPts: int64;
- pbIOCtx: PByteIOContext;
- errnum: integer;
-begin
- Result := false;
- FrameFinished := 0;
-
- if EOF then
- Exit;
-
- // read packets until we have a finished frame (or there are no more packets)
- while (FrameFinished = 0) do
- begin
- errnum := av_read_frame(VideoFormatContext, AVPacket);
- if (errnum < 0) then
- begin
- // failed to read a frame, check reason
-
- {$IF (LIBAVFORMAT_VERSION_MAJOR >= 52)}
- pbIOCtx := VideoFormatContext^.pb;
- {$ELSE}
- pbIOCtx := @VideoFormatContext^.pb;
- {$IFEND}
-
- // check for end-of-file (eof is not an error)
- if (url_feof(pbIOCtx) <> 0) then
- begin
- EOF := true;
- Exit;
- end;
-
- // check for errors
- if (url_ferror(pbIOCtx) <> 0) then
- Exit;
-
- // url_feof() does not detect an EOF for some mov-files (e.g. deluxe.mov)
- // so we have to do it this way.
- if ((VideoFormatContext^.file_size <> 0) and
- (pbIOCtx^.pos >= VideoFormatContext^.file_size)) then
- begin
- EOF := true;
- Exit;
- end;
-
- // no error -> wait for user input
- SDL_Delay(100);
- continue;
- end;
-
- // if we got a packet from the video stream, then decode it
- if (AVPacket.stream_index = VideoStreamIndex) then
- begin
- // save pts to be stored in pFrame in first call of PtsGetBuffer()
- VideoPktPts := AVPacket.pts;
- VideoCodecContext^.opaque := @VideoPktPts;
-
- // decode packet
- avcodec_decode_video(VideoCodecContext, AVFrame,
- frameFinished, AVPacket.data, AVPacket.size);
-
- // reset opaque data
- VideoCodecContext^.opaque := nil;
-
- // update pts
- if (AVPacket.dts <> AV_NOPTS_VALUE) then
- begin
- pts := AVPacket.dts;
- end
- else if ((AVFrame^.opaque <> nil) and
- (Pint64(AVFrame^.opaque)^ <> AV_NOPTS_VALUE)) then
- begin
- pts := Pint64(AVFrame^.opaque)^;
- end
- else
- begin
- pts := 0;
- end;
- pts := pts * av_q2d(VideoStream^.time_base);
-
- // synchronize on each complete frame
- if (frameFinished <> 0) then
- SynchronizeVideo(AVFrame, pts);
- end;
-
- // free the packet from av_read_frame
- av_free_packet( @AVPacket );
- end;
-
- Result := true;
-end;
-
-procedure TVideoPlayback_FFmpeg.GetFrame(Time: Extended);
-var
- AVPacket: TAVPacket;
- errnum: Integer;
- myTime: Extended;
- TimeDifference: Extended;
- DropFrameCount: Integer;
- pts: double;
- i: Integer;
-const
- FRAME_DROPCOUNT = 3;
-begin
- if not fVideoOpened then
- Exit;
-
- if fVideoPaused then
- Exit;
-
- // current time, relative to last loop (if any)
- myTime := Time - fLoopTime;
- // time since the last frame was returned
- TimeDifference := myTime - VideoTime;
-
- {$IFDEF DebugDisplay}
- DebugWriteln('Time: '+inttostr(floor(Time*1000)) + sLineBreak +
- 'VideoTime: '+inttostr(floor(VideoTime*1000)) + sLineBreak +
- 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
- 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
- {$endif}
-
- // check if a new frame is needed
- if (VideoTime <> 0) and (TimeDifference < VideoTimeBase) then
- begin
- {$ifdef DebugFrames}
- // frame delay debug display
- GoldenRec.Spawn(200,15,1,16,0,-1,ColoredStar,$00ff00);
- {$endif}
-
- {$IFDEF DebugDisplay}
- DebugWriteln('not getting new frame' + sLineBreak +
- 'Time: '+inttostr(floor(Time*1000)) + sLineBreak +
- 'VideoTime: '+inttostr(floor(VideoTime*1000)) + sLineBreak +
- 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
- 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
- {$endif}
-
- // we do not need a new frame now
- Exit;
- end;
-
- // update video-time to the next frame
- VideoTime := VideoTime + VideoTimeBase;
- TimeDifference := myTime - VideoTime;
-
- // check if we have to skip frames
- if (TimeDifference >= FRAME_DROPCOUNT*VideoTimeBase) then
- begin
- {$IFDEF DebugFrames}
- //frame drop debug display
- GoldenRec.Spawn(200,55,1,16,0,-1,ColoredStar,$ff0000);
- {$ENDIF}
- {$IFDEF DebugDisplay}
- DebugWriteln('skipping frames' + sLineBreak +
- 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
- 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
- {$endif}
-
- // update video-time
- DropFrameCount := Trunc(TimeDifference / VideoTimeBase);
- VideoTime := VideoTime + DropFrameCount*VideoTimeBase;
-
- // skip half of the frames, this is much smoother than to skip all at once
- for i := 1 to DropFrameCount (*div 2*) do
- DecodeFrame(AVPacket, pts);
- end;
-
- {$IFDEF VideoBenchmark}
- Log.BenchmarkStart(15);
- {$ENDIF}
-
- if (not DecodeFrame(AVPacket, pts)) then
- begin
- if Loop then
- begin
- // Record the time we looped. This is used to keep the loops in time. otherwise they speed
- SetPosition(0);
- fLoopTime := Time;
- end;
- Exit;
- end;
-
- // TODO: support for pan&scan
- //if (AVFrame.pan_scan <> nil) then
- //begin
- // Writeln(Format('PanScan: %d/%d', [AVFrame.pan_scan.width, AVFrame.pan_scan.height]));
- //end;
-
- // otherwise we convert the pixeldata from YUV to RGB
- {$IFDEF UseSWScale}
- errnum := sws_scale(SoftwareScaleContext, @(AVFrame.data), @(AVFrame.linesize),
- 0, VideoCodecContext^.Height,
- @(AVFrameRGB.data), @(AVFrameRGB.linesize));
- {$ELSE}
- errnum := img_convert(PAVPicture(AVFrameRGB), PIXEL_FMT_FFMPEG,
- PAVPicture(AVFrame), VideoCodecContext^.pix_fmt,
- VideoCodecContext^.width, VideoCodecContext^.height);
- {$ENDIF}
-
- if (errnum < 0) then
- begin
- Log.LogError('Image conversion failed', 'TVideoPlayback_ffmpeg.GetFrame');
- Exit;
- end;
-
- {$IFDEF VideoBenchmark}
- Log.BenchmarkEnd(15);
- Log.BenchmarkStart(16);
- {$ENDIF}
-
- // TODO: data is not padded, so we will need to tell OpenGL.
- // Or should we add padding with avpicture_fill? (check which one is faster)
- //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- glBindTexture(GL_TEXTURE_2D, fVideoTex);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
- VideoCodecContext^.width, VideoCodecContext^.height,
- PIXEL_FMT_OPENGL, GL_UNSIGNED_BYTE, AVFrameRGB^.data[0]);
-
- {$ifdef DebugFrames}
- //frame decode debug display
- GoldenRec.Spawn(200, 35, 1, 16, 0, -1, ColoredStar, $ffff00);
- {$endif}
-
- {$IFDEF VideoBenchmark}
- Log.BenchmarkEnd(16);
- Log.LogBenchmark('FFmpeg', 15);
- Log.LogBenchmark('Texture', 16);
- {$ENDIF}
-end;
-
-procedure TVideoPlayback_FFmpeg.DrawGL(Screen: integer);
-var
- TexVideoRightPos, TexVideoLowerPos: Single;
- ScreenLeftPos, ScreenRightPos: Single;
- ScreenUpperPos, ScreenLowerPos: Single;
- ScaledVideoWidth, ScaledVideoHeight: Single;
- ScreenMidPosX, ScreenMidPosY: Single;
- ScreenAspect: Single;
-begin
- // have a nice black background to draw on (even if there were errors opening the vid)
- if (Screen = 1) then
- begin
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end;
-
- // exit if there's nothing to draw
- if (not fVideoOpened) then
- Exit;
-
- {$IFDEF VideoBenchmark}
- Log.BenchmarkStart(15);
- {$ENDIF}
-
- // TODO: add a SetAspectCorrectionMode() function so we can switch
- // aspect correction. The screens video backgrounds look very ugly with aspect
- // correction because of the white bars at the top and bottom.
-
- ScreenAspect := ScreenW / ScreenH;
- ScaledVideoWidth := RenderW;
- ScaledVideoHeight := RenderH * ScreenAspect/VideoAspect;
-
- // Note: Scaling the width does not look good because the video might contain
- // black borders at the top already
- //ScaledVideoHeight := RenderH;
- //ScaledVideoWidth := RenderW * VideoAspect/ScreenAspect;
-
- // center the video
- ScreenMidPosX := RenderW/2;
- ScreenMidPosY := RenderH/2;
- ScreenLeftPos := ScreenMidPosX - ScaledVideoWidth/2;
- ScreenRightPos := ScreenMidPosX + ScaledVideoWidth/2;
- ScreenUpperPos := ScreenMidPosY - ScaledVideoHeight/2;
- ScreenLowerPos := ScreenMidPosY + ScaledVideoHeight/2;
- // the video-texture contains empty borders because its width and height must be
- // a power of 2. So we have to determine the texture coords of the video.
- TexVideoRightPos := VideoCodecContext^.width / TexWidth;
- TexVideoLowerPos := VideoCodecContext^.height / TexHeight;
-
- // we could use blending for brightness control, but do we need this?
- glDisable(GL_BLEND);
-
- // TODO: disable other stuff like lightning, etc.
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, fVideoTex);
- glColor3f(1, 1, 1);
- glBegin(GL_QUADS);
- // upper-left coord
- glTexCoord2f(0, 0);
- glVertex2f(ScreenLeftPos, ScreenUpperPos);
- // lower-left coord
- glTexCoord2f(0, TexVideoLowerPos);
- glVertex2f(ScreenLeftPos, ScreenLowerPos);
- // lower-right coord
- glTexCoord2f(TexVideoRightPos, TexVideoLowerPos);
- glVertex2f(ScreenRightPos, ScreenLowerPos);
- // upper-right coord
- glTexCoord2f(TexVideoRightPos, 0);
- glVertex2f(ScreenRightPos, ScreenUpperPos);
- glEnd;
- glDisable(GL_TEXTURE_2D);
-
- {$IFDEF VideoBenchmark}
- Log.BenchmarkEnd(15);
- Log.LogBenchmark('DrawGL', 15);
- {$ENDIF}
-
- {$IFDEF Info}
- if (fVideoSkipTime+VideoTime+VideoTimeBase < 0) then
- begin
- glColor4f(0.7, 1, 0.3, 1);
- SetFontStyle (1);
- SetFontItalic(False);
- SetFontSize(9);
- SetFontPos (300, 0);
- glPrint('Delay due to negative VideoGap');
- glColor4f(1, 1, 1, 1);
- end;
- {$ENDIF}
-
- {$IFDEF DebugFrames}
- glColor4f(0, 0, 0, 0.2);
- glbegin(GL_QUADS);
- glVertex2f(0, 0);
- glVertex2f(0, 70);
- glVertex2f(250, 70);
- glVertex2f(250, 0);
- glEnd;
-
- glColor4f(1, 1, 1, 1);
- SetFontStyle (1);
- SetFontItalic(False);
- SetFontSize(9);
- SetFontPos (5, 0);
- glPrint('delaying frame');
- SetFontPos (5, 20);
- glPrint('fetching frame');
- SetFontPos (5, 40);
- glPrint('dropping frame');
- {$ENDIF}
-end;
-
-procedure TVideoPlayback_FFmpeg.Play;
-begin
-end;
-
-procedure TVideoPlayback_FFmpeg.Pause;
-begin
- fVideoPaused := not fVideoPaused;
-end;
-
-procedure TVideoPlayback_FFmpeg.Stop;
-begin
-end;
-
-procedure TVideoPlayback_FFmpeg.SetPosition(Time: real);
-var
- SeekFlags: integer;
-begin
- if not fVideoOpened then
- Exit;
-
- if (Time < 0) then
- Time := 0;
-
- // TODO: handle loop-times
- //Time := Time mod VideoDuration;
-
- // backward seeking might fail without AVSEEK_FLAG_BACKWARD
- SeekFlags := AVSEEK_FLAG_ANY;
- if (Time < VideoTime) then
- SeekFlags := SeekFlags or AVSEEK_FLAG_BACKWARD;
-
- VideoTime := Time;
- EOF := false;
-
- if (av_seek_frame(VideoFormatContext, VideoStreamIndex, Floor(Time/VideoTimeBase), SeekFlags) < 0) then
- begin
- Log.LogError('av_seek_frame() failed', 'TVideoPlayback_ffmpeg.SetPosition');
- Exit;
- end;
-
- avcodec_flush_buffers(VideoCodecContext);
-end;
-
-function TVideoPlayback_FFmpeg.GetPosition: real;
-begin
- // TODO: return video-position in seconds
- Result := VideoTime;
-end;
-
-initialization
- MediaManager.Add(TVideoPlayback_FFmpeg.Create);
-
-end.
diff --git a/Game/Code/Classes/UVisualizer.pas b/Game/Code/Classes/UVisualizer.pas
deleted file mode 100644
index e2125201..00000000
--- a/Game/Code/Classes/UVisualizer.pas
+++ /dev/null
@@ -1,442 +0,0 @@
-unit UVisualizer;
-
-(* TODO:
- * - fix video/visualizer switching
- * - use GL_EXT_framebuffer_object for rendering to a separate framebuffer,
- * this will prevent plugins from messing up our render-context
- * (-> no stack corruption anymore, no need for Save/RestoreOpenGLState()).
- * - create a generic (C-compatible) interface for visualization plugins
- * - create a visualization plugin manager
- * - write a plugin for projectM in C/C++ (so we need no wrapper anymore)
- *)
-
-{* Note:
- * It would be easier to create a seperate Render-Context (RC) for projectM
- * and switch to it when necessary. This can be achieved by pbuffers
- * (slow and platform specific) or the OpenGL FramebufferObject (FBO) extension
- * (fast and plattform-independent but not supported by older graphic-cards/drivers).
- *
- * See http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
- *
- * To support as many cards as possible we will stick to the current dirty
- * solution for now even if it is a pain to save/restore projectM's state due
- * to bugs etc.
- *
- * This also restricts us to projectM. As other plug-ins might have different
- * needs and bugs concerning the OpenGL state, USDX's state would probably be
- * corrupted after the plug-in finshed drawing.
- *}
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SDL,
- UGraphicClasses,
- textgl,
- math,
- gl,
- SysUtils,
- UIni,
- projectM,
- UMusic;
-
-implementation
-
-uses
- UGraphic,
- UMain,
- UConfig,
- ULog;
-
-{$IF PROJECTM_VERSION < 1000000} // < 1.0
-// Initialization data used on projectM 0.9x creation.
-// Since projectM 1.0 this data is passed via the config-file.
-const
- meshX = 32;
- meshY = 24;
- fps = 30;
- textureSize = 512;
-{$IFEND}
-
-type
- TVideoPlayback_ProjectM = class( TInterfacedObject, IVideoPlayback, IVideoVisualization )
- private
- pm: TProjectM;
- ProjectMPath : string;
- Initialized: boolean;
-
- VisualizerStarted: boolean;
- VisualizerPaused: boolean;
-
- VisualTex: GLuint;
- PCMData: TPCMData;
- RndPCMcount: integer;
-
- projMatrix: array[0..3, 0..3] of GLdouble;
- texMatrix: array[0..3, 0..3] of GLdouble;
-
- procedure VisualizerStart;
- procedure VisualizerStop;
-
- procedure VisualizerTogglePause;
-
- function GetRandomPCMData(var data: TPCMData): Cardinal;
-
- procedure SaveOpenGLState();
- procedure RestoreOpenGLState();
-
- public
- function GetName: String;
-
- function Init(): boolean;
- function Finalize(): boolean;
-
- function Open(const aFileName : string): boolean; // true if succeed
- procedure Close;
-
- procedure Play;
- procedure Pause;
- procedure Stop;
-
- procedure SetPosition(Time: real);
- function GetPosition: real;
-
- procedure GetFrame(Time: Extended);
- procedure DrawGL(Screen: integer);
- end;
-
-
-function TVideoPlayback_ProjectM.GetName: String;
-begin
- Result := 'ProjectM';
-end;
-
-function TVideoPlayback_ProjectM.Init(): boolean;
-begin
- Result := true;
-
- if (Initialized) then
- Exit;
- Initialized := true;
-
- RndPCMcount := 0;
-
- ProjectMPath := ProjectM_DataDir + PathDelim;
-
- VisualizerStarted := False;
- VisualizerPaused := False;
-
- {$IFDEF UseTexture}
- glGenTextures(1, PglUint(@VisualTex));
- glBindTexture(GL_TEXTURE_2D, VisualTex);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- {$ENDIF}
-end;
-
-function TVideoPlayback_ProjectM.Finalize(): boolean;
-begin
- VisualizerStop();
- {$IFDEF UseTexture}
- glDeleteTextures(1, PglUint(@VisualTex));
- {$ENDIF}
- Result := true;
-end;
-
-function TVideoPlayback_ProjectM.Open(const aFileName : string): boolean; // true if succeed
-begin
- Result := false;
-end;
-
-procedure TVideoPlayback_ProjectM.Close;
-begin
- VisualizerStop();
-end;
-
-procedure TVideoPlayback_ProjectM.Play;
-begin
- VisualizerStart();
-end;
-
-procedure TVideoPlayback_ProjectM.Pause;
-begin
- VisualizerTogglePause();
-end;
-
-procedure TVideoPlayback_ProjectM.Stop;
-begin
- VisualizerStop();
-end;
-
-procedure TVideoPlayback_ProjectM.SetPosition(Time: real);
-begin
- if assigned(pm) then
- pm.RandomPreset();
-end;
-
-function TVideoPlayback_ProjectM.GetPosition: real;
-begin
- Result := 0;
-end;
-
-{**
- * Saves the current OpenGL state.
- * This is necessary to prevent projectM from corrupting USDX's current
- * OpenGL state.
- *
- * The following steps are performed:
- * - All attributes are pushed to the attribute-stack
- * - Projection-/Texture-matrices are saved
- * - Modelview-matrix is pushed to the Modelview-stack
- * - the OpenGL error-state (glGetError) is cleared
- *}
-procedure TVideoPlayback_ProjectM.SaveOpenGLState();
-begin
- // save all OpenGL state-machine attributes
- glPushAttrib(GL_ALL_ATTRIB_BITS);
-
- // Note: we do not use glPushMatrix() for the GL_PROJECTION and GL_TEXTURE stacks.
- // OpenGL specifies the depth of those stacks to be at least 2 but projectM
- // already uses 2 stack-entries so overflows might be possible on older hardware.
- // In contrast to this the GL_MODELVIEW stack-size is at least 32, so we can
- // use glPushMatrix() for this stack.
-
- // save projection-matrix
- glMatrixMode(GL_PROJECTION);
- glGetDoublev(GL_PROJECTION_MATRIX, @projMatrix);
- {$IF PROJECTM_VERSION = 1000000} // 1.0, 1.01
- // bugfix: projection-matrix is popped without being pushed first
- glPushMatrix();
- {$IFEND}
-
- // save texture-matrix
- glMatrixMode(GL_TEXTURE);
- glGetDoublev(GL_TEXTURE_MATRIX, @texMatrix);
-
- // save modelview-matrix
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- {$IF PROJECTM_VERSION = 1000000} // 1.0, 1.01
- // bugfix: modelview-matrix is popped without being pushed first
- glPushMatrix();
- {$IFEND}
-
- // reset OpenGL error-state
- glGetError();
-end;
-
-{**
- * Restores the OpenGL state saved by SaveOpenGLState()
- * and resets the error-state.
- *}
-procedure TVideoPlayback_ProjectM.RestoreOpenGLState();
-begin
- // reset OpenGL error-state
- glGetError();
-
- // restore projection-matrix
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixd(@projMatrix);
-
- // restore texture-matrix
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixd(@texMatrix);
-
- // restore modelview-matrix
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- // restore all OpenGL state-machine attributes
- glPopAttrib();
-end;
-
-procedure TVideoPlayback_ProjectM.VisualizerStart;
-begin
- if VisualizerStarted then
- Exit;
-
- // the OpenGL state must be saved before
- SaveOpenGLState();
- try
-
- try
- {$IF PROJECTM_VERSION >= 1000000} // >= 1.0
- pm := TProjectM.Create(ProjectMPath + 'config.inp');
- {$ELSE}
- pm := TProjectM.Create(
- meshX, meshY, fps, textureSize, ScreenW, ScreenH,
- ProjectMPath + 'presets', ProjectMPath + 'fonts');
- {$IFEND}
- except on E: Exception do
- begin
- // Create() might fail if the config-file is not found
- Log.LogError('TProjectM.Create: ' + E.Message, 'TVideoPlayback_ProjectM.VisualizerStart');
- Exit;
- end;
- end;
-
- // initialize OpenGL
- pm.ResetGL(ScreenW, ScreenH);
- // skip projectM default-preset
- pm.RandomPreset();
- // projectM >= 1.0 uses the OpenGL FramebufferObject (FBO) extension.
- // Unfortunately it does NOT reset the framebuffer-context after
- // TProjectM.Create. Either glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) for
- // a manual reset or TProjectM.RenderFrame() must be called.
- // We use the latter so we do not need to load the FBO extension in USDX.
- pm.RenderFrame();
-
- VisualizerStarted := True;
- finally
- RestoreOpenGLState();
- end;
-end;
-
-procedure TVideoPlayback_ProjectM.VisualizerStop;
-begin
- if VisualizerStarted then
- begin
- VisualizerStarted := False;
- FreeAndNil(pm);
- end;
-end;
-
-procedure TVideoPlayback_ProjectM.VisualizerTogglePause;
-begin
- VisualizerPaused := not VisualizerPaused;
-end;
-
-procedure TVideoPlayback_ProjectM.GetFrame(Time: Extended);
-var
- nSamples: cardinal;
- stackDepth: Integer;
-begin
- if not VisualizerStarted then
- Exit;
-
- if VisualizerPaused then
- Exit;
-
- // get audio data
- nSamples := AudioPlayback.GetPCMData(PcmData);
-
- // generate some data if non is available
- if (nSamples = 0) then
- nSamples := GetRandomPCMData(PcmData);
-
- // send audio-data to projectM
- if (nSamples > 0) then
- pm.AddPCM16Data(PSmallInt(@PcmData), nSamples);
-
- // store OpenGL state (might be messed up otherwise)
- SaveOpenGLState();
- try
- // setup projectM's OpenGL state
- pm.ResetGL(ScreenW, ScreenH);
-
- // let projectM render a frame
- pm.RenderFrame();
-
- {$IFDEF UseTexture}
- glBindTexture(GL_TEXTURE_2D, VisualTex);
- glFlush();
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, VisualWidth, VisualHeight, 0);
- {$ENDIF}
- finally
- // restore USDX OpenGL state
- RestoreOpenGLState();
- end;
-
- // discard projectM's depth buffer information (avoid overlay)
- glClear(GL_DEPTH_BUFFER_BIT);
-end;
-
-{**
- * Draws the current frame to screen.
- * TODO: this is not used yet. Data is directly drawn on GetFrame().
- *}
-procedure TVideoPlayback_ProjectM.DrawGL(Screen: integer);
-begin
- {$IFDEF UseTexture}
- // have a nice black background to draw on
- if (Screen = 1) then
- begin
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end;
-
- // exit if there's nothing to draw
- if not VisualizerStarted then
- Exit;
-
- // setup display
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluOrtho2D(0, 1, 0, 1);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glBindTexture(GL_TEXTURE_2D, VisualTex);
- glColor4f(1, 1, 1, 1);
-
- // draw projectM frame
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(0, 0);
- glTexCoord2f(1, 0); glVertex2f(1, 0);
- glTexCoord2f(1, 1); glVertex2f(1, 1);
- glTexCoord2f(0, 1); glVertex2f(0, 1);
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // restore state
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- {$ENDIF}
-end;
-
-{**
- * Produces random "sound"-data in case no audio-data is available.
- * Otherwise the visualization will look rather boring.
- *}
-function TVideoPlayback_ProjectM.GetRandomPCMData(var data: TPCMData): Cardinal;
-var
- i: integer;
-begin
- // Produce some fake PCM data
- if (RndPCMcount mod 500 = 0) then
- begin
- FillChar(data, SizeOf(TPCMData), 0);
- end
- else
- begin
- for i := 0 to 511 do
- begin
- data[i][0] := Random(High(Word)+1);
- data[i][1] := Random(High(Word)+1);
- end;
- end;
- Inc(RndPCMcount);
- Result := 512;
-end;
-
-
-initialization
- MediaManager.Add(TVideoPlayback_ProjectM.Create);
-
-end.
diff --git a/Game/Code/Classes/UXMLSong.pas b/Game/Code/Classes/UXMLSong.pas
deleted file mode 100644
index 1a1fe6bc..00000000
--- a/Game/Code/Classes/UXMLSong.pas
+++ /dev/null
@@ -1,573 +0,0 @@
-unit UXMLSong;
-
-interface
-uses Classes;
-
-type
- TNote = record
- Start: Cardinal;
- Duration: Cardinal;
- Tone: Integer;
- NoteTyp: Byte;
- Lyric: String;
- end;
- ANote = Array of TNote;
-
- TSentence = record
- Singer: Byte;
- Duration: Cardinal;
- Notes: ANote;
- end;
- ASentence = Array of TSentence;
-
- TSongInfo = Record
- ID: Cardinal;
- DualChannel: Boolean;
- Header: Record
- Artist: String;
- Title: String;
- Gap: Cardinal;
- BPM: Real;
- Resolution: Byte;
- Edition: String;
- Genre: String;
- Year: String;
- Language: String;
- end;
- CountSentences: Cardinal;
- Sentences: ASentence;
- end;
-
- TParser = class
- private
- SSFile: TStringList;
-
- ParserState: Byte;
- CurPosinSong: Cardinal; //Cur Beat Pos in the Song
- CurDuettSinger: Byte; //Who sings this Part?
- BindLyrics: Boolean; //Should the Lyrics be bind to the last Word (no Space)
- FirstNote: Boolean; //Is this the First Note found? For Gap calculating
-
- Function ParseLine(Line: String): Boolean;
- public
- SongInfo: TSongInfo;
- ErrorMessage: String;
- Edition: String;
- SingstarVersion: String;
-
- Settings: Record
- DashReplacement: Char;
- end;
-
- Constructor Create;
-
- Function ParseConfigforEdition(const Filename: String): String;
-
- Function ParseSongHeader(const Filename: String): Boolean; //Parse Song Header only
- Function ParseSong (const Filename: String): Boolean; //Parse whole Song
- end;
-
-const
- PS_None = 0;
- PS_Melody = 1;
- PS_Sentence = 2;
-
- NT_Normal = 1;
- NT_Freestyle = 0;
- NT_Golden = 2;
-
- DS_Player1 = 1;
- DS_Player2 = 2;
- DS_Both = 3;
-
-implementation
-uses SysUtils, StrUtils;
-
-Constructor TParser.Create;
-begin
- inherited Create;
- ErrorMessage := '';
-
- DecimalSeparator := '.';
-end;
-
-Function TParser.ParseSong (const Filename: String): Boolean;
-var I: Integer;
-begin
- Result := False;
- if FileExists(Filename) then
- begin
- SSFile := TStringList.Create;
-
- try
- ErrorMessage := 'Can''t open melody.xml file';
- SSFile.LoadFromFile(Filename);
- ErrorMessage := '';
- Result := True;
- I := 0;
-
- SongInfo.CountSentences := 0;
- CurDuettSinger := DS_Both; //Both is Singstar Standard
- CurPosinSong := 0; //Start at Pos 0
- BindLyrics := True; //Dont start with Space
- FirstNote := True; //First Note found should be the First Note ;)
-
- SongInfo.Header.Language := '';
- SongInfo.Header.Edition := Edition;
- SongInfo.DualChannel := False;
-
- ParserState := PS_None;
-
- SetLength(SongInfo.Sentences, 0);
-
- While Result And (I < SSFile.Count) do
- begin
- Result := ParseLine(SSFile.Strings[I]);
-
- Inc(I);
- end;
-
- finally
- SSFile.Free;
- end;
- end;
-end;
-
-Function TParser.ParseSongHeader (const Filename: String): Boolean;
-var I: Integer;
-begin
- Result := False;
- if FileExists(Filename) then
- begin
- SSFile := TStringList.Create;
- SSFile.Clear;
-
- try
- SSFile.LoadFromFile(Filename);
-
- If (SSFile.Count > 0) then
- begin
- Result := True;
- I := 0;
-
- SongInfo.CountSentences := 0;
- CurDuettSinger := DS_Both; //Both is Singstar Standard
- CurPosinSong := 0; //Start at Pos 0
- BindLyrics := True; //Dont start with Space
- FirstNote := True; //First Note found should be the First Note ;)
-
- SongInfo.ID := 0;
- SongInfo.Header.Language := '';
- SongInfo.Header.Edition := Edition;
- SongInfo.DualChannel := False;
- ParserState := PS_None;
-
- While (SongInfo.ID < 4) AND Result And (I < SSFile.Count) do
- begin
- Result := ParseLine(SSFile.Strings[I]);
-
- Inc(I);
- end;
- end
- else
- ErrorMessage := 'Can''t open melody.xml file';
-
- finally
- SSFile.Free;
- end;
- end
- else
- ErrorMessage := 'Can''t find melody.xml file';
-end;
-
-Function TParser.ParseLine(Line: String): Boolean;
-var
- Tag: String;
- Values: String;
- AValues: Array of Record
- Name: String;
- Value: String;
- end;
- I, J, K: Integer;
- Duration, Tone: Integer;
- Lyric: String;
- NoteType: Byte;
-
- Procedure MakeValuesArray;
- var Len, Pos, State, StateChange: Integer;
- begin
- Len := -1;
- SetLength(AValues, Len + 1);
-
- Pos := 1;
- State := 0;
- While (Pos <= Length(Values)) AND (Pos <> 0) do
- begin
- Case State of
-
- 0: begin //Search for ValueName
- If (Values[Pos] <> ' ') AND (Values[Pos] <> '=') then
- begin
- //Found Something
- State := 1; //State search for '='
- StateChange := Pos; //Save Pos of Change
- Pos := PosEx('=', Values, Pos + 1);
- end
- else Inc(Pos); //When nothing found then go to next char
- end;
-
- 1: begin //Search for Equal Mark
- //Add New Value
- Inc(Len);
- SetLength(AValues, Len + 1);
-
- AValues[Len].Name := UpperCase(Copy(Values, StateChange, Pos - StateChange));
-
-
- State := 2; //Now Search for starting '"'
- StateChange := Pos; //Save Pos of Change
- Pos := PosEx('"', Values, Pos + 1);
- end;
-
- 2: begin //Search for starting '"' or ' ' <- End if there was no "
- If (Values[Pos] = '"') then
- begin //Found starting '"'
- State := 3; //Now Search for ending '"'
- StateChange := Pos; //Save Pos of Change
- Pos := PosEx('"', Values, Pos + 1);
- end
- else If (Values[Pos] = ' ') then //Found ending Space
- begin
- //Save Value to Array
- AValues[Len].Value := Copy(Values, StateChange + 1, Pos - StateChange - 1);
-
- //Search for next Valuename
- State := 0;
- StateChange := Pos;
- Inc(Pos);
- end;
- end;
-
- 3: begin //Search for ending '"'
- //Save Value to Array
- AValues[Len].Value := Copy(Values, StateChange + 1, Pos - StateChange - 1);
-
- //Search for next Valuename
- State := 0;
- StateChange := Pos;
- Inc(Pos);
- end;
- end;
-
- If (State >= 2) then
- begin //Save Last Value
- AValues[Len].Value := Copy(Values, StateChange + 1, Length(Values) - StateChange);
- end;
- end;
- end;
-begin
- Result := True;
-
- Line := Trim(Line);
- If (Length(Line) > 0) then
- begin
- I := Pos('<', Line);
- J := PosEx(' ', Line, I+1);
- K := PosEx('>', Line, I+1);
-
- If (J = 0) then J := K
- Else If (K < J) AND (K <> 0) then J := K; //Use nearest Tagname End indicator
- Tag := UpperCase(copy(Line, I + 1, J - I - 1));
- Values := copy(Line, J + 1, K - J - 1);
-
- Case ParserState of
- PS_None: begin//Search for Melody Tag
- If (Tag = 'MELODY') then
- begin
- Inc(SongInfo.ID); //Inc SongID when header Information is added
- MakeValuesArray;
- For I := 0 to High(AValues) do
- begin
- If (AValues[I].Name = 'TEMPO') then
- begin
- SongInfo.Header.BPM := StrtoFloatDef(AValues[I].Value, 0);
- If (SongInfo.Header.BPM <= 0) then
- begin
- Result := False;
- ErrorMessage := 'Can''t read BPM from Song';
- end;
- end
-
- Else If (AValues[I].Name = 'RESOLUTION') then
- begin
- AValues[I].Value := Uppercase(AValues[I].Value);
- //Ultrastar Resolution is "how often a Beat is split / 4"
- If (AValues[I].Value = 'HEMIDEMISEMIQUAVER') then
- SongInfo.Header.Resolution := 64 div 4
- Else If (AValues[I].Value = 'DEMISEMIQUAVER') then
- SongInfo.Header.Resolution := 32 div 4
- Else If (AValues[I].Value = 'SEMIQUAVER') then
- SongInfo.Header.Resolution := 16 div 4
- Else If (AValues[I].Value = 'QUAVER') then
- SongInfo.Header.Resolution := 8 div 4
- Else If (AValues[I].Value = 'CROTCHET') then
- SongInfo.Header.Resolution := 4 div 4
- Else
- begin //Can't understand teh Resolution :/
- Result := False;
- ErrorMessage := 'Can''t read Resolution from Song';
- end;
- end
-
- Else If (AValues[I].Name = 'GENRE') then
- begin
- SongInfo.Header.Genre := AValues[I].Value;
- end
-
- Else If (AValues[I].Name = 'YEAR') then
- begin
- SongInfo.Header.Year := AValues[I].Value;
- end
-
- Else If (AValues[I].Name = 'VERSION') then
- begin
- SingstarVersion := AValues[I].Value;
- end;
- end;
-
- ParserState := PS_Melody; //In Melody Tag
- end;
- end;
-
-
- PS_Melody: begin //Search for Sentence, Artist/Title Info or eo Melody
- If (Tag = 'SENTENCE') then
- begin
- ParserState := PS_Sentence; //Parse in a Sentence Tag now
-
- //Increase SentenceCount
- Inc(SongInfo.CountSentences);
-
- BindLyrics := True; //Don't let Txts Begin w/ Space
-
- //Search for Duett Singer Info
- MakeValuesArray;
- For I := 0 to High(AValues) do
- If (AValues[I].Name = 'SINGER') then
- begin
- AValues[I].Value := Uppercase(AValues[I].Value);
- If (AValues[I].Value = 'SOLO 1') then
- CurDuettSinger := DS_Player1
- Else If (AValues[I].Value = 'SOLO 2') then
- CurDuettSinger := DS_Player2
- Else
- CurDuettSinger := DS_Both; //In case of "Group" or anything that is not identified use Both
- end;
- end
-
- Else If (Tag = '!--') then
- begin //Comment, this may be Artist or Title Info
- I := Pos(':', Values); //Search for Delimiter
-
- If (I <> 0) then //If Found check for Title or Artist
- begin
- //Copy Title or Artist Tag to Tag String
- Tag := Uppercase(Trim(Copy(Values, 1, I - 1)));
-
- If (Tag = 'ARTIST') then
- begin
- SongInfo.Header.Artist := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
- Inc(SongInfo.ID); //Inc SongID when header Information is added
- end
- Else If (Tag = 'TITLE') then
- begin
- SongInfo.Header.Title := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
- Inc(SongInfo.ID); //Inc SongID when header Information is added
- end;
- end;
- end
-
- //Parsing for weird "Die toten Hosen" Tags
- Else If (Tag = '!--ARTIST:') OR (Tag = '!--ARTIST') then
- begin //Comment, with Artist Info
- I := Pos(':', Values); //Search for Delimiter
-
- Inc(SongInfo.ID); //Inc SongID when header Information is added
-
- SongInfo.Header.Artist := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
- end
-
- Else If (Tag = '!--TITLE:') OR (Tag = '!--TITLE') then
- begin //Comment, with Artist Info
- I := Pos(':', Values); //Search for Delimiter
-
- Inc(SongInfo.ID); //Inc SongID when header Information is added
-
- SongInfo.Header.Title := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
- end
-
- Else If (Tag = '/MELODY') then
- begin
- ParserState := PS_None;
- Exit; //Stop Parsing, Melody iTag ended
- end
- end;
-
-
- PS_Sentence: begin //Search for Notes or eo Sentence
- If (Tag = 'NOTE') then
- begin //Found Note
- //Get Values
- MakeValuesArray;
-
- NoteType := NT_Normal;
- For I := 0 to High(AValues) do
- begin
- If (AValues[I].Name = 'DURATION') then
- begin
- Duration := StrtoIntDef(AValues[I].Value, -1);
- If (Duration < 0) then
- begin
- Result := False;
- ErrorMessage := 'Can''t read duration from Note in Line: "' + Line + '"';
- Exit;
- end;
- end
- Else If (AValues[I].Name = 'MIDINOTE') then
- begin
- Tone := StrtoIntDef(AValues[I].Value, 0);
- end
- Else If (AValues[I].Name = 'BONUS') AND (Uppercase(AValues[I].Value) = 'YES') then
- begin
- NoteType := NT_Golden;
- end
- Else If (AValues[I].Name = 'FREESTYLE') AND (Uppercase(AValues[I].Value) = 'YES') then
- begin
- NoteType := NT_Freestyle;
- end
- Else If (AValues[I].Name = 'LYRIC') then
- begin
- Lyric := AValues[I].Value;
-
- If (Length(Lyric) > 0) then
- begin
- If (Lyric = '-') then
- Lyric[1] := Settings.DashReplacement;
-
- If (not BindLyrics) then
- Lyric := ' ' + Lyric;
-
-
- If (Length(Lyric) > 2) AND (Lyric[Length(Lyric)-1] = ' ') AND (Lyric[Length(Lyric)] = '-') then
- begin //Between this and the next Lyric should be no space
- BindLyrics := True;
- SetLength(Lyric, Length(Lyric) - 2);
- end
- else
- BindLyrics := False; //There should be a Space
- end;
- end;
- end;
-
- //Add Note
- I := SongInfo.CountSentences - 1;
-
- If (Length(Lyric) > 0) then
- begin //Real note, no rest
- //First Note of Sentence
- If (Length(SongInfo.Sentences) < SongInfo.CountSentences) then
- begin
- SetLength(SongInfo.Sentences, SongInfo.CountSentences);
- SetLength(SongInfo.Sentences[I].Notes, 0);
- end;
-
- //First Note of Song -> Generate Gap
- If (FirstNote) then
- begin
- //Calculate Gap
- If (SongInfo.Header.Resolution <> 0) AND (SongInfo.Header.BPM <> 0) then
- SongInfo.Header.Gap := Round(CurPosinSong / (SongInfo.Header.BPM*SongInfo.Header.Resolution) * 60000)
- Else
- begin
- Result := False;
- ErrorMessage := 'Can''t calculate Gap, no Resolution or BPM present.';
- Exit;
- end;
-
- CurPosinSong := 0; //Start at 0, because Gap goes until here
- Inc(SongInfo.ID); //Add Header Value therefore Inc
- FirstNote := False;
- end;
-
- J := Length(SongInfo.Sentences[I].Notes);
- SetLength(SongInfo.Sentences[I].Notes, J + 1);
- SongInfo.Sentences[I].Notes[J].Start := CurPosinSong;
- SongInfo.Sentences[I].Notes[J].Duration := Duration;
- SongInfo.Sentences[I].Notes[J].Tone := Tone;
- SongInfo.Sentences[I].Notes[J].NoteTyp := NoteType;
- SongInfo.Sentences[I].Notes[J].Lyric := Lyric;
-
- //Inc Pos in Song
- Inc(CurPosInSong, Duration);
- end
- else
- begin
- //just change pos in Song
- Inc(CurPosInSong, Duration);
- end;
-
-
- end
- Else If (Tag = '/SENTENCE') then
- begin //End of Sentence Tag
- ParserState := PS_Melody;
-
- //Delete Sentence if no Note is Added
- If (Length(SongInfo.Sentences) <> SongInfo.CountSentences) then
- begin
- SongInfo.CountSentences := Length(SongInfo.Sentences);
- end;
- end;
- end;
- end;
-
- end
- else //Empty Line -> parsed succesful ;)
- Result := true;
-end;
-
-Function TParser.ParseConfigforEdition(const Filename: String): String;
-var
- txt: TStringlist;
- I: Integer;
- J, K: Integer;
- S: String;
-begin
- Result := '';
- txt := TStringlist.Create;
- try
- txt.LoadFromFile(Filename);
-
- For I := 0 to txt.Count-1 do
- begin
- S := Trim(txt.Strings[I]);
- J := Pos('', S);
-
- If (J <> 0) then
- begin
- Inc(J, 14);
- K := Pos('', S);
- If (K nil then write array of TUS_PluginInfo to address at lparam) else (Get PluginInfo of Plugin with Index(wParam) to Address at lParam)
- function GetPluginState(wParam: TwParam; lParam: TlParam): integer; //If wParam = -1 then (If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TUS_PluginInfo to address at lparam) else (Return PluginInfo of Plugin with Index(wParam))
-
- end;
-
- {*********************
- TtehPlugins
- Class Represents the Plugins in Module Chain.
- It Calls the Plugins Procs and Funcs
- *********************}
- TtehPlugins = class (TCoreModule)
- private
- PluginLoader: PPluginLoader;
- public
- //TCoreModule methods to inherit
- constructor Create; override;
-
- procedure Info(const pInfo: PModuleInfo); override;
- function Load: Boolean; override;
- function Init: Boolean; override;
- procedure DeInit; override;
- end;
-
-const
- {$IFDEF MSWINDOWS}
- PluginFileExtension = '.dll';
- {$ENDIF}
- {$IFDEF LINUX}
- PluginFileExtension = '.so';
- {$ENDIF}
- {$IFDEF DARWIN}
- PluginFileExtension = '.dylib';
- {$ENDIF}
-
-implementation
-
-uses
- UCore,
- UPluginInterface,
-{$IFDEF MSWINDOWS}
- windows,
-{$ELSE}
- dynlibs,
-{$ENDIF}
- UMain,
- SysUtils;
-
-{*********************
- TPluginLoader
- Implentation
-*********************}
-
-//-------------
-// function that gives some Infos about the Module to the Core
-//-------------
-procedure TPluginLoader.Info(const pInfo: PModuleInfo);
-begin
- pInfo^.Name := 'TPluginLoader';
- pInfo^.Version := MakeVersion(1,0,0,chr(0));
- pInfo^.Description := 'Searches for Plugins, loads and unloads them';
-end;
-
-//-------------
-// Just the Constructor
-//-------------
-constructor TPluginLoader.Create;
-begin
- inherited;
-
- //Init PluginInterface
- //Using Methods from UPluginInterface
- PluginInterface.CreateHookableEvent := CreateHookableEvent;
- PluginInterface.DestroyHookableEvent := DestroyHookableEvent;
- PluginInterface.NotivyEventHooks := NotivyEventHooks;
- PluginInterface.HookEvent := HookEvent;
- PluginInterface.UnHookEvent := UnHookEvent;
- PluginInterface.EventExists := EventExists;
-
- PluginInterface.CreateService := @CreateService;
- PluginInterface.DestroyService := DestroyService;
- PluginInterface.CallService := CallService;
- PluginInterface.ServiceExists := ServiceExists;
-
- //UnSet Private Var
- LoadingProcessFinished := False;
-end;
-
-//-------------
-//Is Called on Loading.
-//In this Method only Events and Services should be created
-//to offer them to other Modules or Plugins during the Init process
-//If False is Returned this will cause a Forced Exit
-//-------------
-function TPluginLoader.Load: Boolean;
-begin
- Result := True;
-
- try
- //Start Searching for Plugins
- BrowseDir(PluginPath);
- except
- Result := False;
- Core.ReportError(integer(PChar('Error Browsing and Loading.')), PChar('TPluginLoader'));
- end;
-end;
-
-//-------------
-//Is Called on Init Process
-//In this Method you can Hook some Events and Create + Init
-//your Classes, Variables etc.
-//If False is Returned this will cause a Forced Exit
-//-------------
-function TPluginLoader.Init: Boolean;
-begin
- //Just set Prvate Var to true.
- LoadingProcessFinished := True;
- Result := True;
-end;
-
-//-------------
-//Is Called if this Module has been Inited and there is a Exit.
-//Deinit is in backwards Initing Order
-//-------------
-procedure TPluginLoader.DeInit;
-var
- I: integer;
-begin
- //Force DeInit
- //If some Plugins aren't DeInited for some Reason o0
- for I := 0 to High(Plugins) do
- begin
- if (Plugins[I].State < 4) then
- FreePlugin(I);
- end;
-
- //Nothing to do here. Core will remove the Hooks
-end;
-
-//-------------
-//Is Called if this Module will be unloaded and has been created
-//Should be used to Free Memory
-//-------------
-Destructor TPluginLoader.Destroy;
-begin
- //Just save some Memory if it wasn't done now..
- SetLength(Plugins, 0);
- inherited;
-end;
-
-//--------------
-// Browses the Path at _Path_ for Plugins
-//--------------
-procedure TPluginLoader.BrowseDir(Path: String);
-var
- SR: TSearchRec;
-begin
- //Search for other Dirs to Browse
- if FindFirst(Path + '*', faDirectory, SR) = 0 then begin
- repeat
- if (SR.Name <> '.') and (SR.Name <> '..') then
- BrowseDir(Path + Sr.Name + PathDelim);
- until FindNext(SR) <> 0;
- end;
- FindClose(SR);
-
- //Search for Plugins at Path
- if FindFirst(Path + '*' + PluginFileExtension, 0, SR) = 0 then
- begin
- repeat
- AddPlugin(Path + SR.Name);
- until FindNext(SR) <> 0;
- end;
- FindClose(SR);
-end;
-
-//--------------
-// If Plugin Exists: Index of Plugin, else -1
-//--------------
-function TPluginLoader.PluginExists(Name: String): integer;
-var
- I: integer;
-begin
- Result := -1;
-
- if (Length(Name) <= 32 { =>Length(TUS_PluginInfo.Name)}) then
- begin
- for I := 0 to High(Plugins) do
- if (Plugins[I].Info.Name = Name) then
- begin //Found the Plugin
- Result := I;
- Break;
- end;
- end;
-end;
-
-//--------------
-// Adds Plugin to the Array
-//--------------
-procedure TPluginLoader.AddPlugin(Filename: String);
-var
- hLib: THandle;
- PInfo: Proc_PluginInfo;
- Info: TUS_PluginInfo;
- PluginID: integer;
-begin
- if (FileExists(Filename)) then
- begin //Load Libary
- hLib := LoadLibrary(PChar(Filename));
- if (hLib <> 0) then
- begin //Try to get Address of the Info Proc
- PInfo := GetProcAddress (hLib, PChar('USPlugin_Info'));
- if (@PInfo <> nil) then
- begin
- Info.cbSize := SizeOf(TUS_PluginInfo);
-
- try //Call Info Proc
- PInfo(@Info);
- except
- Info.Name := '';
- Core.ReportError(integer(PChar('Error getting Plugin Info: ' + Filename)), PChar('TPluginLoader'));
- end;
-
- //Is Name set ?
- if (Trim(Info.Name) <> '') then
- begin
- PluginID := PluginExists(Info.Name);
-
- if (PluginID > 0) and (Plugins[PluginID].State >=4) then
- PluginID := -1;
-
- if (PluginID = -1) then
- begin
- //Add new item to array
- PluginID := Length(Plugins);
- SetLength(Plugins, PluginID + 1);
-
- //Fill with Info:
- Plugins[PluginID].Info := Info;
- Plugins[PluginID].State := 0;
- Plugins[PluginID].Path := Filename;
- Plugins[PluginID].NeedsDeInit := False;
- Plugins[PluginID].hLib := hLib;
-
- //Try to get Procs
- Plugins[PluginID].Procs.Load := GetProcAddress (hLib, PChar('USPlugin_Load'));
- Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
- Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
-
- if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
- begin
- Plugins[PluginID].State := 255;
- FreeLibrary(hLib);
- Core.ReportError(integer(PChar('Can''t get Plugin Procs from Libary: "' + Info.Name + '" ' + Filename)), PChar('TPluginLoader'));
- end;
-
- //Emulate loading process if this Plugin is loaded to late
- if (LoadingProcessFinished) then
- begin
- CallLoad(PluginID);
- CallInit(PluginID);
- end;
- end
- else if (LoadingProcessFinished = False) then
- begin
- if (Plugins[PluginID].Info.Version < Info.Version) then
- begin //Found newer Version of this Plugin
- Core.ReportDebug(integer(PChar('Found a newer Version of Plugin: ' + String(Info.Name))), PChar('TPluginLoader'));
-
- //Unload Old Plugin
- UnloadPlugin(PluginID, nil);
-
- //Fill with new Info
- Plugins[PluginID].Info := Info;
- Plugins[PluginID].State := 0;
- Plugins[PluginID].Path := Filename;
- Plugins[PluginID].NeedsDeInit := False;
- Plugins[PluginID].hLib := hLib;
-
- //Try to get Procs
- Plugins[PluginID].Procs.Load := GetProcAddress (hLib, PChar('USPlugin_Load'));
- Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
- Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
-
- if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
- begin
- FreeLibrary(hLib);
- Plugins[PluginID].State := 255;
- Core.ReportError(integer(PChar('Can''t get Plugin Procs from Libary: "' + Info.Name + '" ' + Filename)), PChar('TPluginLoader'));
- end;
- end
- else
- begin //Newer Version already loaded
- FreeLibrary(hLib);
- end;
- end
- else
- begin
- FreeLibrary(hLib);
- Core.ReportError(integer(PChar('Plugin with this Name already exists: ' + String(Info.Name))), PChar('TPluginLoader'));
- end;
- end
- else
- begin
- FreeLibrary(hLib);
- Core.ReportError(integer(PChar('No name reported: ' + Filename)), PChar('TPluginLoader'));
- end;
- end
- else
- begin
- FreeLibrary(hLib);
- Core.ReportError(integer(PChar('Can''t find Info procedure: ' + Filename)), PChar('TPluginLoader'));
- end;
- end
- else
- Core.ReportError(integer(PChar('Can''t load Plugin Libary: ' + Filename)), PChar('TPluginLoader'));
- end;
-end;
-
-//--------------
-// Calls Load Func of Plugin with the given Index
-//--------------
-function TPluginLoader.CallLoad(Index: Cardinal): integer;
-begin
- Result := -2;
- if(Index < Length(Plugins)) then
- begin
- if (@Plugins[Index].Procs.Load <> nil) and (Plugins[Index].State = 0) then
- begin
- try
- Result := Plugins[Index].Procs.Load(@PluginInterface);
- except
- Result := -3;
- End;
-
- if (Result = 0) then
- Plugins[Index].State := 1
- else
- begin
- FreePlugin(Index);
- Plugins[Index].State := 255;
- Core.ReportError(integer(PChar('Error calling Load function from Plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
- end;
- end;
- end;
-end;
-
-//--------------
-// Calls Init Func of Plugin with the given Index
-//--------------
-function TPluginLoader.CallInit(Index: Cardinal): integer;
-begin
- Result := -2;
- if(Index < Length(Plugins)) then
- begin
- if (@Plugins[Index].Procs.Init <> nil) and (Plugins[Index].State = 1) then
- begin
- try
- Result := Plugins[Index].Procs.Init(@PluginInterface);
- except
- Result := -3;
- End;
-
- if (Result = 0) then
- begin
- Plugins[Index].State := 2;
- Plugins[Index].NeedsDeInit := True;
- end
- else
- begin
- FreePlugin(Index);
- Plugins[Index].State := 255;
- Core.ReportError(integer(PChar('Error calling Init function from Plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
- end;
- end;
- end;
-end;
-
-//--------------
-// Calls DeInit Proc of Plugin with the given Index
-//--------------
-procedure TPluginLoader.CallDeInit(Index: Cardinal);
-begin
- if(Index < Length(Plugins)) then
- begin
- if (Plugins[Index].State < 4) then
- begin
- if (@Plugins[Index].Procs.DeInit <> nil) and (Plugins[Index].NeedsDeInit) then
- try
- Plugins[Index].Procs.DeInit(@PluginInterface);
- except
-
- End;
-
- //Don't forget to remove Services and Subscriptions by this Plugin
- Core.Hooks.DelbyOwner(-1 - Index);
-
- FreePlugin(Index);
- end;
- end;
-end;
-
-//--------------
-// Frees all Plugin Sources (Procs and Handles) - Helper for Deiniting Functions
-//--------------
-procedure TPluginLoader.FreePlugin(Index: Cardinal);
-begin
- Plugins[Index].State := 4;
- Plugins[Index].Procs.Load := nil;
- Plugins[Index].Procs.Init := nil;
- Plugins[Index].Procs.DeInit := nil;
-
- if (Plugins[Index].hLib <> 0) then
- FreeLibrary(Plugins[Index].hLib);
-end;
-
-
-
-//--------------
-// wParam PChar(PluginName/PluginPath) | wParam (if lParam = nil) ID of the Plugin
-//--------------
-function TPluginLoader.LoadPlugin(wParam: TwParam; lParam: TlParam): integer;
-var
- Index: integer;
- sFile: String;
-begin
- Result := -1;
- sFile := '';
- //lParam is ID
- if (lParam = nil) then
- begin
- Index := wParam;
- end
- else
- begin //lParam is PChar
- try
- sFile := String(PChar(lParam));
- Index := PluginExists(sFile);
- if (Index < 0) And FileExists(sFile) then
- begin //Is Filename
- AddPlugin(sFile);
- Result := Plugins[High(Plugins)].State;
- end;
- except
- Index := -2;
- end;
- end;
-
-
- if (Index >= 0) and (Index < Length(Plugins)) then
- begin
- AddPlugin(Plugins[Index].Path);
- Result := Plugins[Index].State;
- end;
-end;
-
-//--------------
-// wParam PChar(PluginName/PluginPath) | wParam (if lParam = nil) ID of the Plugin
-//--------------
-function TPluginLoader.UnloadPlugin(wParam: TwParam; lParam: TlParam): integer;
-var
- Index: integer;
- sName: String;
-begin
- Result := -1;
- //lParam is ID
- if (lParam = nil) then
- begin
- Index := wParam;
- end
- else
- begin //wParam is PChar
- try
- sName := String(PChar(lParam));
- Index := PluginExists(sName);
- except
- Index := -2;
- end;
- end;
-
-
- if (Index >= 0) and (Index < Length(Plugins)) then
- CallDeInit(Index)
-end;
-
-//--------------
-// if wParam = -1 then (if lParam = nil then get length of Moduleinfo Array. if lparam <> nil then write array of TUS_PluginInfo to address at lparam) else (Get PluginInfo of Plugin with Index(wParam) to Address at lParam)
-//--------------
-function TPluginLoader.GetPluginInfo(wParam: TwParam; lParam: TlParam): integer;
-var I: integer;
-begin
- Result := 0;
- if (wParam > 0) then
- begin //Get Info of 1 Plugin
- if (lParam <> nil) and (wParam < Length(Plugins)) then
- begin
- try
- Result := 1;
- PUS_PluginInfo(lParam)^ := Plugins[wParam].Info;
- except
-
- End;
- end;
- end
- else if (lParam = nil) then
- begin //Get Length of Plugin (Info) Array
- Result := Length(Plugins);
- end
- else //Write PluginInfo Array to Address in lParam
- begin
- try
- for I := 0 to high(Plugins) do
- PAUS_PluginInfo(lParam)^[I] := Plugins[I].Info;
- Result := Length(Plugins);
- except
- Core.ReportError(integer(PChar('Could not write PluginInfo Array')), PChar('TPluginLoader'));
- End;
- end;
-
-end;
-
-//--------------
-// if wParam = -1 then (if lParam = nil then get length of Plugin State Array. if lparam <> nil then write array of Byte to address at lparam) else (Return State of Plugin with Index(wParam))
-//--------------
-function TPluginLoader.GetPluginState(wParam: TwParam; lParam: TlParam): integer;
-var I: integer;
-begin
- Result := -1;
- if (wParam > 0) then
- begin //Get State of 1 Plugin
- if (wParam < Length(Plugins)) then
- begin
- Result := Plugins[wParam].State;
- end;
- end
- else if (lParam = nil) then
- begin //Get Length of Plugin (Info) Array
- Result := Length(Plugins);
- end
- else //Write PluginInfo Array to Address in lParam
- begin
- try
- for I := 0 to high(Plugins) do
- Byte(Pointer(integer(lParam) + I)^) := Plugins[I].State;
- Result := Length(Plugins);
- except
- Core.ReportError(integer(PChar('Could not write PluginState Array')), PChar('TPluginLoader'));
- End;
- end;
-end;
-
-
-{*********************
- TtehPlugins
- Implentation
-*********************}
-
-//-------------
-// function that gives some Infos about the Module to the Core
-//-------------
-procedure TtehPlugins.Info(const pInfo: PModuleInfo);
-begin
- pInfo^.Name := 'TtehPlugins';
- pInfo^.Version := MakeVersion(1,0,0,chr(0));
- pInfo^.Description := 'Module executing the Plugins!';
-end;
-
-//-------------
-// Just the Constructor
-//-------------
-constructor TtehPlugins.Create;
-begin
- inherited;
- PluginLoader := nil;
-end;
-
-//-------------
-//Is Called on Loading.
-//In this Method only Events and Services should be created
-//to offer them to other Modules or Plugins during the Init process
-//If False is Returned this will cause a Forced Exit
-//-------------
-function TtehPlugins.Load: Boolean;
-var
- i: integer; //Counter
- CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
-begin
- //Get Pointer to PluginLoader
- PluginLoader := PPluginLoader(Core.GetModulebyName('TPluginLoader'));
- if (PluginLoader = nil) then
- begin
- Result := false;
- Core.ReportError(integer(PChar('Could not get Pointer to PluginLoader')), PChar('TtehPlugins'));
- end
- else
- begin
- Result := true;
-
- //Backup CurExecuted
- CurExecutedBackup := Core.CurExecuted;
-
- //Start Loading the Plugins
- for i := 0 to High(PluginLoader.Plugins) do
- begin
- Core.CurExecuted := -1 - i;
-
- try
- //Unload Plugin if not correctly Executed
- if (PluginLoader.CallLoad(i) <> 0) then
- begin
- PluginLoader.CallDeInit(i);
- PluginLoader.Plugins[i].State := 254; //Plugin asks for unload
- Core.ReportDebug(integer(PChar('Plugin Selfabort during loading process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
- end
- else
- begin
- Core.ReportDebug(integer(PChar('Plugin loaded succesful: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
- end;
- except
- //Plugin could not be loaded.
- // => Show Error Message, then ShutDown Plugin
- on E: Exception do
- begin
- PluginLoader.CallDeInit(i);
- PluginLoader.Plugins[i].State := 255; //Plugin causes Error
- Core.ReportError(integer(PChar('Plugin causes Error during loading process: ' + PluginLoader.Plugins[i].Info.Name + ', ErrorMsg: "' + E.Message + '"')), PChar('TtehPlugins'));
- end;
- end;
- end;
-
- //Reset CurExecuted
- Core.CurExecuted := CurExecutedBackup;
- end;
-end;
-
-//-------------
-//Is Called on Init Process
-//In this Method you can Hook some Events and Create + Init
-//your Classes, Variables etc.
-//If False is Returned this will cause a Forced Exit
-//-------------
-function TtehPlugins.Init: Boolean;
-var
- i: integer; //Counter
- CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
-begin
- Result := true;
-
- //Backup CurExecuted
- CurExecutedBackup := Core.CurExecuted;
-
- //Start Loading the Plugins
- for i := 0 to High(PluginLoader.Plugins) do
- try
- Core.CurExecuted := -1 - i;
-
- //Unload Plugin if not correctly Executed
- if (PluginLoader.CallInit(i) <> 0) then
- begin
- PluginLoader.CallDeInit(i);
- PluginLoader.Plugins[i].State := 254; //Plugin asks for unload
- Core.ReportDebug(integer(PChar('Plugin Selfabort during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
- end
- else
- Core.ReportDebug(integer(PChar('Plugin inited succesful: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
- except
- //Plugin could not be loaded.
- // => Show Error Message, then ShutDown Plugin
- PluginLoader.CallDeInit(i);
- PluginLoader.Plugins[i].State := 255; //Plugin causes Error
- Core.ReportError(integer(PChar('Plugin causes Error during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
- end;
-
- //Reset CurExecuted
- Core.CurExecuted := CurExecutedBackup;
-end;
-
-//-------------
-//Is Called if this Module has been Inited and there is a Exit.
-//Deinit is in backwards Initing Order
-//-------------
-procedure TtehPlugins.DeInit;
-var
- i: integer; //Counter
- CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
-begin
- //Backup CurExecuted
- CurExecutedBackup := Core.CurExecuted;
-
- //Start Loop
-
- for i := 0 to High(PluginLoader.Plugins) do
- begin
- try
- //DeInit Plugin
- PluginLoader.CallDeInit(i);
- except
- end;
- end;
-
- //Reset CurExecuted
- Core.CurExecuted := CurExecutedBackup;
-end;
-
-end.
diff --git a/Game/Code/MacOSX/English.lproj/InfoPlist.strings b/Game/Code/MacOSX/English.lproj/InfoPlist.strings
deleted file mode 100755
index ce30d99a..00000000
Binary files a/Game/Code/MacOSX/English.lproj/InfoPlist.strings and /dev/null differ
diff --git a/Game/Code/MacOSX/English.lproj/SDLMain.nib/classes.nib b/Game/Code/MacOSX/English.lproj/SDLMain.nib/classes.nib
deleted file mode 100644
index 799eaadd..00000000
--- a/Game/Code/MacOSX/English.lproj/SDLMain.nib/classes.nib
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- IBClasses = (
- {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
- {
- ACTIONS = {
- help = id;
- newGame = id;
- openGame = id;
- prefsMenu = id;
- saveGame = id;
- saveGameAs = id;
- };
- CLASS = SDLMain;
- LANGUAGE = ObjC;
- SUPERCLASS = NSObject;
- }
- );
- IBVersion = 1;
-}
\ No newline at end of file
diff --git a/Game/Code/MacOSX/English.lproj/SDLMain.nib/info.nib b/Game/Code/MacOSX/English.lproj/SDLMain.nib/info.nib
deleted file mode 100644
index 1d6fb7e0..00000000
--- a/Game/Code/MacOSX/English.lproj/SDLMain.nib/info.nib
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
- IBDocumentLocation
- 62 117 356 240 0 0 1152 848
- IBEditorPositions
-
- 29
- 62 362 195 44 0 0 1152 848
-
- IBFramework Version
- 291.0
- IBOpenObjects
-
- 29
-
- IBSystem Version
- 6L60
-
-
diff --git a/Game/Code/MacOSX/English.lproj/SDLMain.nib/objects.nib b/Game/Code/MacOSX/English.lproj/SDLMain.nib/objects.nib
deleted file mode 100644
index 63780152..00000000
Binary files a/Game/Code/MacOSX/English.lproj/SDLMain.nib/objects.nib and /dev/null differ
diff --git a/Game/Code/MacOSX/Info.plist b/Game/Code/MacOSX/Info.plist
deleted file mode 100644
index a62966cf..00000000
--- a/Game/Code/MacOSX/Info.plist
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleDisplayName
- UltraStarDeluxe
- CFBundleExecutable
- ultrastardx
- CFBundleGetInfoString
- UltraStarDeluxe, a SingStar clone
- CFBundleIconFile
- ustar-icon_v01.icns
- CFBundleIdentifier
- org.ultrastardeluxe.ultrastardeluxe
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- UltraStarDeluxe
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- USDX
- CFBundleVersion
- 1.0
- LSExecutableArchitectures
- i386
- NSAppleScriptEnabled
-
- NSHumanReadableCopyright
- LGPL
- NSMainNibFile
- SDLMain
- NSPrincipalClass
- NSApplication
-
-
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1 b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
deleted file mode 100644
index 578575c4..00000000
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
+++ /dev/null
@@ -1,1408 +0,0 @@
-
-
-
-
- ActivePerspectiveName
- Project
- AllowedModules
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXSmartGroupTreeModule
- Name
- Groups and Files Outline View
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXNavigatorGroup
- Name
- Editor
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCTaskListModule
- Name
- Task List
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCDetailModule
- Name
- File and Smart Group Detail Viewer
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXBuildResultsModule
- Name
- Detailed Build Results Viewer
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXProjectFindModule
- Name
- Project Batch Find Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXRunSessionModule
- Name
- Run Log
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXBookmarksModule
- Name
- Bookmarks Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXClassBrowserModule
- Name
- Class Browser
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXCVSModule
- Name
- Source Code Control Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXDebugBreakpointsModule
- Name
- Debug Breakpoints Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCDockableInspector
- Name
- Inspector
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXOpenQuicklyModule
- Name
- Open Quickly Tool
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXDebugSessionModule
- Name
- Debugger
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXDebugCLIModule
- Name
- Debug Console
-
-
- Description
- DefaultDescriptionKey
- DockingSystemVisible
-
- Extension
- mode1
- FavBarConfig
-
- PBXProjectModuleGUID
- 2CDD4B6F0CB935C700549FAC
- XCBarModuleItemNames
-
- XCBarModuleItems
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- com.apple.perspectives.project.mode1
- MajorVersion
- 31
- MinorVersion
- 1
- Name
- Default
- Notifications
-
- OpenEditors
-
-
- Content
-
- PBXProjectModuleGUID
- 2CAE5FE50CE3B914009D9EF2
- PBXProjectModuleLabel
- USongs.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CAE5FE60CE3B914009D9EF2
- PBXProjectModuleLabel
- USongs.pas
- _historyCapacity
- 0
- bookmark
- 2CF1EFD70CE77D5600B5167D
- history
-
- 2C0B367E0CE3D50000158AB2
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {797, 748}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 15 212 797 789 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2CC28B200CE3C14E00D16793
- PBXProjectModuleLabel
- UPlatformWindows.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CC28B210CE3C14E00D16793
- PBXProjectModuleLabel
- UPlatformWindows.pas
- _historyCapacity
- 0
- bookmark
- 2CF1EFD80CE77D5600B5167D
- history
-
- 2C0B367F0CE3D50000158AB2
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {776, 859}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 15 123 776 900 0 0 1680 1028
-
-
-
- PerspectiveWidths
-
- -1
- -1
-
- Perspectives
-
-
- ChosenToolbarItems
-
- active-target-popup
- active-buildstyle-popup
- action
- NSToolbarFlexibleSpaceItem
- buildOrClean
- build-and-runOrDebug
- com.apple.ide.PBXToolbarStopButton
- get-info
- toggle-editor
- NSToolbarFlexibleSpaceItem
- com.apple.pbx.toolbar.searchfield
-
- ControllerClassBaseName
-
- IconName
- WindowOfProjectWithEditor
- Identifier
- perspective.project
- IsVertical
-
- Layout
-
-
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
- 1C08E77C0454961000C914BD
- 1C37FABC05509CD000000102
- 1C37FABC05539CD112110102
- E2644B35053B69B200211256
- 1C37FABC04509CD000100104
- 1CC0EA4004350EF90044410B
- 1CC0EA4004350EF90041110B
-
- PBXProjectModuleGUID
- 1CE0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- yes
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 266
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- DDC6850D09F5717A004E4BFF
- DD7C45450A6E72DE003FA52B
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 17
- 15
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 0}, {266, 694}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
-
- XCSharingToken
- com.apple.Xcode.GFSharingToken
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {283, 712}}
- GroupTreeTableConfiguration
-
- MainColumn
- 266
-
- RubberWindowFrame
- 858 143 817 753 0 0 1680 1028
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 283pt
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CE0B20306471E060097A5F4
- PBXProjectModuleLabel
-
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 1CE0B20406471E060097A5F4
- PBXProjectModuleLabel
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {529, 0}}
- RubberWindowFrame
- 858 143 817 753 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 0pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CE0B20506471E060097A5F4
- PBXProjectModuleLabel
- Detail
-
- GeometryConfiguration
-
- Frame
- {{0, 5}, {529, 707}}
- RubberWindowFrame
- 858 143 817 753 0 0 1680 1028
-
- Module
- XCDetailModule
- Proportion
- 707pt
-
-
- Proportion
- 529pt
-
-
- Name
- Project
- ServiceClasses
-
- XCModuleDock
- PBXSmartGroupTreeModule
- XCModuleDock
- PBXNavigatorGroup
- XCDetailModule
-
- TableOfContents
-
- 2CF1EFD10CE77D5600B5167D
- 1CE0B1FE06471DED0097A5F4
- 2CF1EFD20CE77D5600B5167D
- 1CE0B20306471E060097A5F4
- 1CE0B20506471E060097A5F4
-
- ToolbarConfiguration
- xcode.toolbar.config.default
-
-
- ControllerClassBaseName
-
- IconName
- WindowOfProject
- Identifier
- perspective.morph
- IsVertical
- 0
- Layout
-
-
- BecomeActive
- 1
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
- 1C08E77C0454961000C914BD
- 1C37FABC05509CD000000102
- 1C37FABC05539CD112110102
- E2644B35053B69B200211256
- 1C37FABC04509CD000100104
- 1CC0EA4004350EF90044410B
- 1CC0EA4004350EF90041110B
-
- PBXProjectModuleGUID
- 11E0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- yes
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 186
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- 29B97314FDCFA39411CA2CEA
- 1C37FABC05509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 0}, {186, 337}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
- 1
- XCSharingToken
- com.apple.Xcode.GFSharingToken
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {203, 355}}
- GroupTreeTableConfiguration
-
- MainColumn
- 186
-
- RubberWindowFrame
- 373 269 690 397 0 0 1440 878
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 100%
-
-
- Name
- Morph
- PreferredWidth
- 300
- ServiceClasses
-
- XCModuleDock
- PBXSmartGroupTreeModule
-
- TableOfContents
-
- 11E0B1FE06471DED0097A5F4
-
- ToolbarConfiguration
- xcode.toolbar.config.default.short
-
-
- PerspectivesBarVisible
-
- ShelfIsVisible
-
- SourceDescription
- file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'
- StatusbarIsVisible
-
- TimeStamp
- 0.0
- ToolbarDisplayMode
- 1
- ToolbarIsVisible
-
- ToolbarSizeMode
- 1
- Type
- Perspectives
- UpdateMessage
- The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?
- WindowJustification
- 5
- WindowOrderList
-
- 2CC28B200CE3C14E00D16793
- 2CAE5FE50CE3B914009D9EF2
- 1C0AD2B3069F1EA900FABCE6
- /Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj
-
- WindowString
- 858 143 817 753 0 0 1680 1028
- WindowTools
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.build
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD0528F0623707200166675
- PBXProjectModuleLabel
-
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {1346, 566}}
- RubberWindowFrame
- 106 169 1346 848 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 566pt
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- XCMainBuildResultsModuleGUID
- PBXProjectModuleLabel
- Build
- XCBuildResultsTrigger_Collapse
- 1021
- XCBuildResultsTrigger_Open
- 1011
-
- GeometryConfiguration
-
- Frame
- {{0, 571}, {1346, 236}}
- RubberWindowFrame
- 106 169 1346 848 0 0 1680 1028
-
- Module
- PBXBuildResultsModule
- Proportion
- 236pt
-
-
- Proportion
- 807pt
-
-
- Name
- Build Results
- ServiceClasses
-
- PBXBuildResultsModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 2CDD4B730CB935C700549FAC
- 2C0B36810CE3D50000158AB2
- 1CD0528F0623707200166675
- XCMainBuildResultsModuleGUID
-
- ToolbarConfiguration
- xcode.toolbar.config.build
- WindowString
- 106 169 1346 848 0 0 1680 1028
- WindowToolGUID
- 2CDD4B730CB935C700549FAC
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.debugger
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- Debugger
-
- HorizontalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {333, 414}}
- {{333, 0}, {631, 414}}
-
-
- VerticalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {964, 414}}
- {{0, 414}, {964, 374}}
-
-
-
- LauncherConfigVersion
- 8
- PBXProjectModuleGUID
- 1C162984064C10D400B95A72
- PBXProjectModuleLabel
- Debug - GLUTExamples (Underwater)
-
- GeometryConfiguration
-
- DebugConsoleDrawerSize
- {100, 120}
- DebugConsoleVisible
- None
- DebugConsoleWindowFrame
- {{200, 200}, {500, 300}}
- DebugSTDIOWindowFrame
- {{200, 200}, {500, 300}}
- Frame
- {{0, 0}, {964, 788}}
- RubberWindowFrame
- 227 162 964 829 0 0 1680 1028
-
- Module
- PBXDebugSessionModule
- Proportion
- 788pt
-
-
- Proportion
- 788pt
-
-
- Name
- Debugger
- ServiceClasses
-
- PBXDebugSessionModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1CD10A99069EF8BA00B06720
- 2C89371D0CE3926A005D8A87
- 1C162984064C10D400B95A72
- 2C89371E0CE3926A005D8A87
- 2C89371F0CE3926A005D8A87
- 2C8937200CE3926A005D8A87
- 2C8937210CE3926A005D8A87
- 2C8937220CE3926A005D8A87
- 2C8937230CE3926A005D8A87
-
- ToolbarConfiguration
- xcode.toolbar.config.debug
- WindowString
- 227 162 964 829 0 0 1680 1028
- WindowToolGUID
- 1CD10A99069EF8BA00B06720
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.find
- IsVertical
-
- Layout
-
-
- Dock
-
-
- Dock
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CDD528C0622207200134675
- PBXProjectModuleLabel
- UCommon.pas
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {790, 502}}
- RubberWindowFrame
- 821 68 790 888 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 790pt
-
-
- Proportion
- 502pt
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD0528E0623707200166675
- PBXProjectModuleLabel
- Project Find
-
- GeometryConfiguration
-
- Frame
- {{0, 507}, {790, 340}}
- RubberWindowFrame
- 821 68 790 888 0 0 1680 1028
-
- Module
- PBXProjectFindModule
- Proportion
- 340pt
-
-
- Proportion
- 847pt
-
-
- Name
- Project Find
- ServiceClasses
-
- PBXProjectFindModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C530D57069F1CE1000CFCEE
- 2C5C69C90CE3B3AF00545A7B
- 2C5C69CA0CE3B3AF00545A7B
- 1CDD528C0622207200134675
- 1CD0528E0623707200166675
-
- WindowString
- 821 68 790 888 0 0 1680 1028
- WindowToolGUID
- 1C530D57069F1CE1000CFCEE
- WindowToolIsVisible
-
-
-
- Identifier
- MENUSEPARATOR
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.debuggerConsole
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1C78EAAC065D492600B07095
- PBXProjectModuleLabel
- Debugger Console
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {1245, 708}}
- RubberWindowFrame
- 410 84 1245 749 0 0 1680 1028
-
- Module
- PBXDebugCLIModule
- Proportion
- 708pt
-
-
- Proportion
- 708pt
-
-
- Name
- Debugger Console
- ServiceClasses
-
- PBXDebugCLIModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 2CDD4BFC0CB948FC00549FAC
- 2C8937D00CE3A1FF005D8A87
- 1C78EAAC065D492600B07095
-
- WindowString
- 410 84 1245 749 0 0 1680 1028
- WindowToolGUID
- 2CDD4BFC0CB948FC00549FAC
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.run
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- LauncherConfigVersion
- 3
- PBXProjectModuleGUID
- 1CD0528B0623707200166675
- PBXProjectModuleLabel
- Run
- Runner
-
- HorizontalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {493, 167}}
- {{0, 176}, {493, 267}}
-
-
- VerticalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {405, 443}}
- {{414, 0}, {514, 443}}
-
-
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {1092, 660}}
- RubberWindowFrame
- 266 221 1092 701 0 0 1680 1028
-
- Module
- PBXRunSessionModule
- Proportion
- 660pt
-
-
- Proportion
- 660pt
-
-
- Name
- Run Log
- ServiceClasses
-
- PBXRunSessionModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C0AD2B3069F1EA900FABCE6
- 2CF1EFD50CE77D5600B5167D
- 1CD0528B0623707200166675
- 2CF1EFD60CE77D5600B5167D
-
- ToolbarConfiguration
- xcode.toolbar.config.run
- WindowString
- 266 221 1092 701 0 0 1680 1028
- WindowToolGUID
- 1C0AD2B3069F1EA900FABCE6
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.scm
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1C78EAB2065D492600B07095
- PBXProjectModuleLabel
-
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {452, 0}}
- RubberWindowFrame
- 194 589 452 308 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 0pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD052920623707200166675
- PBXProjectModuleLabel
- SCM Results
-
- GeometryConfiguration
-
- Frame
- {{0, 5}, {452, 262}}
- RubberWindowFrame
- 194 589 452 308 0 0 1680 1028
-
- Module
- PBXCVSModule
- Proportion
- 262pt
-
-
- Proportion
- 267pt
-
-
- Name
- SCM
- ServiceClasses
-
- PBXCVSModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 2CBF1CB30CC566690030C462
- 2CBF1CB40CC566690030C462
- 1C78EAB2065D492600B07095
- 1CD052920623707200166675
-
- ToolbarConfiguration
- xcode.toolbar.config.scm
- WindowString
- 194 589 452 308 0 0 1680 1028
- WindowToolGUID
- 2CBF1CB30CC566690030C462
- WindowToolIsVisible
-
-
-
- Identifier
- windowTool.breakpoints
- IsVertical
- 0
- Layout
-
-
- Dock
-
-
- BecomeActive
- 1
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C77FABC04509CD000000102
-
- PBXProjectModuleGUID
- 1CE0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- no
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 168
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- 1C77FABC04509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 0}, {168, 350}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
- 0
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {185, 368}}
- GroupTreeTableConfiguration
-
- MainColumn
- 168
-
- RubberWindowFrame
- 315 424 744 409 0 0 1440 878
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 185pt
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CA1AED706398EBD00589147
- PBXProjectModuleLabel
- Detail
-
- GeometryConfiguration
-
- Frame
- {{190, 0}, {554, 368}}
- RubberWindowFrame
- 315 424 744 409 0 0 1440 878
-
- Module
- XCDetailModule
- Proportion
- 554pt
-
-
- Proportion
- 368pt
-
-
- MajorVersion
- 2
- MinorVersion
- 0
- Name
- Breakpoints
- ServiceClasses
-
- PBXSmartGroupTreeModule
- XCDetailModule
-
- StatusbarIsVisible
- 1
- TableOfContents
-
- 1CDDB66807F98D9800BB5817
- 1CDDB66907F98D9800BB5817
- 1CE0B1FE06471DED0097A5F4
- 1CA1AED706398EBD00589147
-
- ToolbarConfiguration
- xcode.toolbar.config.breakpoints
- WindowString
- 315 424 744 409 0 0 1440 878
- WindowToolGUID
- 1CDDB66807F98D9800BB5817
- WindowToolIsVisible
- 1
-
-
- Identifier
- windowTool.debugAnimator
- Layout
-
-
- Dock
-
-
- Module
- PBXNavigatorGroup
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Debug Visualizer
- ServiceClasses
-
- PBXNavigatorGroup
-
- StatusbarIsVisible
- 1
- ToolbarConfiguration
- xcode.toolbar.config.debugAnimator
- WindowString
- 100 100 700 500 0 0 1280 1002
-
-
- Identifier
- windowTool.bookmarks
- Layout
-
-
- Dock
-
-
- Module
- PBXBookmarksModule
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Bookmarks
- ServiceClasses
-
- PBXBookmarksModule
-
- StatusbarIsVisible
- 0
- WindowString
- 538 42 401 187 0 0 1280 1002
-
-
- Identifier
- windowTool.classBrowser
- Layout
-
-
- Dock
-
-
- BecomeActive
- 1
- ContentConfiguration
-
- OptionsSetName
- Hierarchy, all classes
- PBXProjectModuleGUID
- 1CA6456E063B45B4001379D8
- PBXProjectModuleLabel
- Class Browser - NSObject
-
- GeometryConfiguration
-
- ClassesFrame
- {{0, 0}, {374, 96}}
- ClassesTreeTableConfiguration
-
- PBXClassNameColumnIdentifier
- 208
- PBXClassBookColumnIdentifier
- 22
-
- Frame
- {{0, 0}, {630, 331}}
- MembersFrame
- {{0, 105}, {374, 395}}
- MembersTreeTableConfiguration
-
- PBXMemberTypeIconColumnIdentifier
- 22
- PBXMemberNameColumnIdentifier
- 216
- PBXMemberTypeColumnIdentifier
- 97
- PBXMemberBookColumnIdentifier
- 22
-
- PBXModuleWindowStatusBarHidden2
- 1
- RubberWindowFrame
- 385 179 630 352 0 0 1440 878
-
- Module
- PBXClassBrowserModule
- Proportion
- 332pt
-
-
- Proportion
- 332pt
-
-
- Name
- Class Browser
- ServiceClasses
-
- PBXClassBrowserModule
-
- StatusbarIsVisible
- 0
- TableOfContents
-
- 1C0AD2AF069F1E9B00FABCE6
- 1C0AD2B0069F1E9B00FABCE6
- 1CA6456E063B45B4001379D8
-
- ToolbarConfiguration
- xcode.toolbar.config.classbrowser
- WindowString
- 385 179 630 352 0 0 1440 878
- WindowToolGUID
- 1C0AD2AF069F1E9B00FABCE6
- WindowToolIsVisible
- 0
-
-
-
-
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
deleted file mode 100644
index 3a15da1d..00000000
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
+++ /dev/null
@@ -1,1740 +0,0 @@
-
-
-
-
- ActivePerspectiveName
- Project
- AllowedModules
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXSmartGroupTreeModule
- Name
- Groups and Files Outline View
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXNavigatorGroup
- Name
- Editor
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCTaskListModule
- Name
- Task List
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCDetailModule
- Name
- File and Smart Group Detail Viewer
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXBuildResultsModule
- Name
- Detailed Build Results Viewer
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXProjectFindModule
- Name
- Project Batch Find Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCProjectFormatConflictsModule
- Name
- Project Format Conflicts List
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXBookmarksModule
- Name
- Bookmarks Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXClassBrowserModule
- Name
- Class Browser
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXCVSModule
- Name
- Source Code Control Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXDebugBreakpointsModule
- Name
- Debug Breakpoints Tool
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCDockableInspector
- Name
- Inspector
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- PBXOpenQuicklyModule
- Name
- Open Quickly Tool
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXDebugSessionModule
- Name
- Debugger
-
-
- BundleLoadPath
-
- MaxInstances
- 1
- Module
- PBXDebugCLIModule
- Name
- Debug Console
-
-
- BundleLoadPath
-
- MaxInstances
- n
- Module
- XCSnapshotModule
- Name
- Snapshots Tool
-
-
- Description
- DefaultDescriptionKey
- DockingSystemVisible
-
- Extension
- mode1v3
- FavBarConfig
-
- PBXProjectModuleGUID
- 2C349F430CF222D900A55A81
- XCBarModuleItemNames
-
- XCBarModuleItems
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- com.apple.perspectives.project.mode1v3
- MajorVersion
- 33
- MinorVersion
- 0
- Name
- Default
- Notifications
-
- OpenEditors
-
-
- Content
-
- PBXProjectModuleGUID
- 2CA608820D9998CC00EBC4A7
- PBXProjectModuleLabel
- UAudioPlayback_Bass.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CA608830D9998CC00EBC4A7
- PBXProjectModuleLabel
- UAudioPlayback_Bass.pas
- _historyCapacity
- 0
- bookmark
- 2CA6088F0D99999100EBC4A7
- history
-
- 2CA608790D99987900EBC4A7
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {993, 838}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 38 123 993 879 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2CA608850D9998CC00EBC4A7
- PBXProjectModuleLabel
- UAudioCore_Bass.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CA608860D9998CC00EBC4A7
- PBXProjectModuleLabel
- UAudioCore_Bass.pas
- _historyCapacity
- 0
- bookmark
- 2CA608900D99999100EBC4A7
- history
-
- 2CA608780D99987200EBC4A7
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {993, 838}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 15 144 993 879 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2C019A0B0D998D4A00974970
- PBXProjectModuleLabel
- UMain.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2C019A0C0D998D4A00974970
- PBXProjectModuleLabel
- UMain.pas
- _historyCapacity
- 0
- bookmark
- 2CA608910D99999100EBC4A7
- history
-
- 2CA607DD0D998F0B00EBC4A7
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {1052, 646}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 30 341 1052 687 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2C0199490D9981C000974970
- PBXProjectModuleLabel
- UCommon.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2C01994A0D9981C000974970
- PBXProjectModuleLabel
- UCommon.pas
- _historyCapacity
- 0
- bookmark
- 2CA608920D99999100EBC4A7
- history
-
- 2CA607DF0D998F0B00EBC4A7
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {754, 847}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 38 134 754 888 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2C0199430D9981C000974970
- PBXProjectModuleLabel
- UScreenMain.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2C0199440D9981C000974970
- PBXProjectModuleLabel
- UScreenMain.pas
- _historyCapacity
- 0
- bookmark
- 2CA608930D99999100EBC4A7
- history
-
- 2C019A190D998D4A00974970
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {754, 847}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 38 135 754 888 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2C0199930D9984F900974970
- PBXProjectModuleLabel
- UltraStarDX.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2C0199940D9984F900974970
- PBXProjectModuleLabel
- UltraStarDX.pas
- _historyCapacity
- 0
- bookmark
- 2CA608940D99999100EBC4A7
- history
-
- 2C019A1A0D998D4A00974970
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {987, 762}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 311 168 987 803 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2C01994C0D9981C000974970
- PBXProjectModuleLabel
- OpenGL12.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2C01994D0D9981C000974970
- PBXProjectModuleLabel
- OpenGL12.pas
- _historyCapacity
- 0
- bookmark
- 2CA608950D99999100EBC4A7
- history
-
- 2C019A1B0D998D4A00974970
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {1070, 868}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 1 119 1070 909 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2CE603EA0D71601400DB0D88
- PBXProjectModuleLabel
- UTexture.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CE603EB0D71601400DB0D88
- PBXProjectModuleLabel
- UTexture.pas
- _historyCapacity
- 0
- bookmark
- 2CA608960D99999100EBC4A7
- history
-
- 2C019A1C0D998D4A00974970
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {776, 858}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 15 124 776 899 0 0 1680 1028
-
-
-
- Content
-
- PBXProjectModuleGUID
- 2CE603EE0D71601400DB0D88
- PBXProjectModuleLabel
- UPlatformMacOSX.pas
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 2CE603EF0D71601400DB0D88
- PBXProjectModuleLabel
- UPlatformMacOSX.pas
- _historyCapacity
- 0
- bookmark
- 2CA608970D99999100EBC4A7
- history
-
- 2C019A1D0D998D4A00974970
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- Geometry
-
- Frame
- {{0, 20}, {776, 859}}
- PBXModuleWindowStatusBarHidden2
-
- RubberWindowFrame
- 79 126 776 900 0 0 1680 1028
-
-
-
- PerspectiveWidths
-
- -1
- -1
-
- Perspectives
-
-
- ChosenToolbarItems
-
- active-target-popup
- active-buildstyle-popup
- action
- NSToolbarFlexibleSpaceItem
- buildOrClean
- build-and-goOrGo
- com.apple.ide.PBXToolbarStopButton
- get-info
- toggle-editor
- NSToolbarFlexibleSpaceItem
- com.apple.pbx.toolbar.searchfield
-
- ControllerClassBaseName
-
- IconName
- WindowOfProjectWithEditor
- Identifier
- perspective.project
- IsVertical
-
- Layout
-
-
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
- 1C08E77C0454961000C914BD
- 1C37FABC05509CD000000102
- 1C37FABC05539CD112110102
- E2644B35053B69B200211256
- 1C37FABC04509CD000100104
- 1CC0EA4004350EF90044410B
- 1CC0EA4004350EF90041110B
-
- PBXProjectModuleGUID
- 1CE0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- yes
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 266
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- DDC6850D09F5717A004E4BFF
- 2C4D9D980CC9EE0B0031092D
- DD7C45450A6E72DE003FA52B
- 2CF5510C0CDA28F000627463
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 23
- 15
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 105}, {266, 694}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
-
- XCSharingToken
- com.apple.Xcode.GFSharingToken
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {283, 712}}
- GroupTreeTableConfiguration
-
- MainColumn
- 266
-
- RubberWindowFrame
- 799 242 817 753 0 0 1680 1028
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 283pt
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CE0B20306471E060097A5F4
- PBXProjectModuleLabel
-
- PBXSplitModuleInNavigatorKey
-
- Split0
-
- PBXProjectModuleGUID
- 1CE0B20406471E060097A5F4
- PBXProjectModuleLabel
-
-
- SplitCount
- 1
-
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {529, 0}}
- RubberWindowFrame
- 799 242 817 753 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 0pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CE0B20506471E060097A5F4
- PBXProjectModuleLabel
- Detail
-
- GeometryConfiguration
-
- Frame
- {{0, 5}, {529, 707}}
- RubberWindowFrame
- 799 242 817 753 0 0 1680 1028
-
- Module
- XCDetailModule
- Proportion
- 707pt
-
-
- Proportion
- 529pt
-
-
- Name
- Project
- ServiceClasses
-
- XCModuleDock
- PBXSmartGroupTreeModule
- XCModuleDock
- PBXNavigatorGroup
- XCDetailModule
-
- TableOfContents
-
- 2CA607D80D998F0B00EBC4A7
- 1CE0B1FE06471DED0097A5F4
- 2CA607D90D998F0B00EBC4A7
- 1CE0B20306471E060097A5F4
- 1CE0B20506471E060097A5F4
-
- ToolbarConfiguration
- xcode.toolbar.config.defaultV3
-
-
- ControllerClassBaseName
-
- IconName
- WindowOfProject
- Identifier
- perspective.morph
- IsVertical
-
- Layout
-
-
- BecomeActive
- 1
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C37FBAC04509CD000000102
- 1C37FAAC04509CD000000102
- 1C08E77C0454961000C914BD
- 1C37FABC05509CD000000102
- 1C37FABC05539CD112110102
- E2644B35053B69B200211256
- 1C37FABC04509CD000100104
- 1CC0EA4004350EF90044410B
- 1CC0EA4004350EF90041110B
-
- PBXProjectModuleGUID
- 11E0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- yes
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 186
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- 29B97314FDCFA39411CA2CEA
- 1C37FABC05509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 0}, {186, 337}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
- 1
- XCSharingToken
- com.apple.Xcode.GFSharingToken
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {203, 355}}
- GroupTreeTableConfiguration
-
- MainColumn
- 186
-
- RubberWindowFrame
- 373 269 690 397 0 0 1440 878
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 100%
-
-
- Name
- Morph
- PreferredWidth
- 300
- ServiceClasses
-
- XCModuleDock
- PBXSmartGroupTreeModule
-
- TableOfContents
-
- 11E0B1FE06471DED0097A5F4
-
- ToolbarConfiguration
- xcode.toolbar.config.default.shortV3
-
-
- PerspectivesBarVisible
-
- ShelfIsVisible
-
- StatusbarIsVisible
-
- TimeStamp
- 0.0
- ToolbarDisplayMode
- 1
- ToolbarIsVisible
-
- ToolbarSizeMode
- 1
- Type
- Perspectives
- UpdateMessage
- The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?
- WindowJustification
- 5
- WindowOrderList
-
- 2CA6081C0D9991E800EBC4A7
- 2CA6081D0D9991E800EBC4A7
- 1C530D57069F1CE1000CFCEE
- 1C78EAAD065D492600B07095
- 1CD10A99069EF8BA00B06720
- 2C65660B0CF2236C0041F7DC
- 2CE603EE0D71601400DB0D88
- 2CE603EA0D71601400DB0D88
- 2C01994C0D9981C000974970
- 2C0199930D9984F900974970
- 2C0199430D9981C000974970
- 2C0199490D9981C000974970
- 2C019A0B0D998D4A00974970
- 2CA608850D9998CC00EBC4A7
- /Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj
- 2CA608820D9998CC00EBC4A7
-
- WindowString
- 799 242 817 753 0 0 1680 1028
- WindowToolsV3
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.build
- IsVertical
-
- Layout
-
-
- Dock
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD0528F0623707200166675
- PBXProjectModuleLabel
- UAudioInput_Bass.pas
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {942, 546}}
- RubberWindowFrame
- 105 189 942 828 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 546pt
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- XCMainBuildResultsModuleGUID
- PBXProjectModuleLabel
- Build
- XCBuildResultsTrigger_Collapse
- 1021
- XCBuildResultsTrigger_Open
- 1011
-
- GeometryConfiguration
-
- Frame
- {{0, 551}, {942, 236}}
- RubberWindowFrame
- 105 189 942 828 0 0 1680 1028
-
- Module
- PBXBuildResultsModule
- Proportion
- 236pt
-
-
- Proportion
- 787pt
-
-
- Name
- Build Results
- ServiceClasses
-
- PBXBuildResultsModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 2C65660B0CF2236C0041F7DC
- 2CA607E60D998F0B00EBC4A7
- 1CD0528F0623707200166675
- XCMainBuildResultsModuleGUID
-
- ToolbarConfiguration
- xcode.toolbar.config.buildV3
- WindowString
- 105 189 942 828 0 0 1680 1028
- WindowToolGUID
- 2C65660B0CF2236C0041F7DC
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.debugger
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- Debugger
-
- HorizontalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {312, 440}}
- {{312, 0}, {591, 440}}
-
-
- VerticalSplitView
-
- _collapsingFrameDimension
- 0.0
- _indexOfCollapsedView
- 0
- _percentageOfCollapsedView
- 0.0
- isCollapsed
- yes
- sizes
-
- {{0, 0}, {903, 440}}
- {{0, 440}, {903, 385}}
-
-
-
- LauncherConfigVersion
- 8
- PBXProjectModuleGUID
- 1C162984064C10D400B95A72
- PBXProjectModuleLabel
- Debug - GLUTExamples (Underwater)
-
- GeometryConfiguration
-
- DebugConsoleVisible
- None
- DebugConsoleWindowFrame
- {{200, 200}, {500, 300}}
- DebugSTDIOWindowFrame
- {{200, 200}, {500, 300}}
- Frame
- {{0, 0}, {903, 825}}
- PBXDebugSessionStackFrameViewKey
-
- DebugVariablesTableConfiguration
-
- Name
- 120
- Value
- 85
- Summary
- 361
-
- Frame
- {{312, 0}, {591, 440}}
- RubberWindowFrame
- 13 162 903 866 0 0 1680 1028
-
- RubberWindowFrame
- 13 162 903 866 0 0 1680 1028
-
- Module
- PBXDebugSessionModule
- Proportion
- 825pt
-
-
- Proportion
- 825pt
-
-
- Name
- Debugger
- ServiceClasses
-
- PBXDebugSessionModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1CD10A99069EF8BA00B06720
- 2CA607E70D998F0B00EBC4A7
- 1C162984064C10D400B95A72
- 2CA607E80D998F0B00EBC4A7
- 2CA607E90D998F0B00EBC4A7
- 2CA607EA0D998F0B00EBC4A7
- 2CA607EB0D998F0B00EBC4A7
- 2CA607EC0D998F0B00EBC4A7
-
- ToolbarConfiguration
- xcode.toolbar.config.debugV3
- WindowString
- 13 162 903 866 0 0 1680 1028
- WindowToolGUID
- 1CD10A99069EF8BA00B06720
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.find
- IsVertical
-
- Layout
-
-
- Dock
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CDD528C0622207200134675
- PBXProjectModuleLabel
- <No Editor>
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {790, 502}}
- RubberWindowFrame
- 821 68 790 888 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 790pt
-
-
- Proportion
- 502pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD0528E0623707200166675
- PBXProjectModuleLabel
- Project Find
-
- GeometryConfiguration
-
- Frame
- {{0, 507}, {790, 340}}
- RubberWindowFrame
- 821 68 790 888 0 0 1680 1028
-
- Module
- PBXProjectFindModule
- Proportion
- 340pt
-
-
- Proportion
- 847pt
-
-
- Name
- Project Find
- ServiceClasses
-
- PBXProjectFindModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C530D57069F1CE1000CFCEE
- 2CA607ED0D998F0B00EBC4A7
- 2CA607EE0D998F0B00EBC4A7
- 1CDD528C0622207200134675
- 1CD0528E0623707200166675
-
- WindowString
- 821 68 790 888 0 0 1680 1028
- WindowToolGUID
- 1C530D57069F1CE1000CFCEE
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- MENUSEPARATOR
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.debuggerConsole
- IsVertical
-
- Layout
-
-
- Dock
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1C78EAAC065D492600B07095
- PBXProjectModuleLabel
- Debugger Console
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {779, 729}}
- RubberWindowFrame
- 886 204 779 770 0 0 1680 1028
-
- Module
- PBXDebugCLIModule
- Proportion
- 729pt
-
-
- Proportion
- 729pt
-
-
- Name
- Debugger Console
- ServiceClasses
-
- PBXDebugCLIModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C78EAAD065D492600B07095
- 2CA607EF0D998F0B00EBC4A7
- 1C78EAAC065D492600B07095
-
- ToolbarConfiguration
- xcode.toolbar.config.consoleV3
- WindowString
- 886 204 779 770 0 0 1680 1028
- WindowToolGUID
- 1C78EAAD065D492600B07095
- WindowToolIsVisible
-
-
-
- Identifier
- windowTool.snapshots
- Layout
-
-
- Dock
-
-
- Module
- XCSnapshotModule
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Snapshots
- ServiceClasses
-
- XCSnapshotModule
-
- StatusbarIsVisible
- Yes
- ToolbarConfiguration
- xcode.toolbar.config.snapshots
- WindowString
- 315 824 300 550 0 0 1440 878
- WindowToolIsVisible
- Yes
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.scm
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1C78EAB2065D492600B07095
- PBXProjectModuleLabel
-
- StatusBarVisibility
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {452, 0}}
- RubberWindowFrame
- 194 589 452 308 0 0 1680 1028
-
- Module
- PBXNavigatorGroup
- Proportion
- 0pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CD052920623707200166675
- PBXProjectModuleLabel
- SCM Results
-
- GeometryConfiguration
-
- Frame
- {{0, 5}, {452, 262}}
- RubberWindowFrame
- 194 589 452 308 0 0 1680 1028
-
- Module
- PBXCVSModule
- Proportion
- 262pt
-
-
- Proportion
- 267pt
-
-
- Name
- SCM
- ServiceClasses
-
- PBXCVSModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C78EAB4065D492600B07095
- 1C78EAB5065D492600B07095
- 1C78EAB2065D492600B07095
- 1CD052920623707200166675
-
- ToolbarConfiguration
- xcode.toolbar.config.scm
- WindowString
- 194 589 452 308 0 0 1680 1028
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.breakpoints
- IsVertical
-
- Layout
-
-
- Dock
-
-
- ContentConfiguration
-
- PBXBottomSmartGroupGIDs
-
- 1C77FABC04509CD000000102
-
- PBXProjectModuleGUID
- 1CE0B1FE06471DED0097A5F4
- PBXProjectModuleLabel
- Files
- PBXProjectStructureProvided
- no
- PBXSmartGroupTreeModuleColumnData
-
- PBXSmartGroupTreeModuleColumnWidthsKey
-
- 168
-
- PBXSmartGroupTreeModuleColumnsKey_v4
-
- MainColumn
-
-
- PBXSmartGroupTreeModuleOutlineStateKey_v7
-
- PBXSmartGroupTreeModuleOutlineStateExpansionKey
-
- 1C77FABC04509CD000000102
-
- PBXSmartGroupTreeModuleOutlineStateSelectionKey
-
-
- 0
-
-
- PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
- {{0, 0}, {168, 350}}
-
- PBXTopSmartGroupGIDs
-
- XCIncludePerspectivesSwitch
-
-
- GeometryConfiguration
-
- Frame
- {{0, 0}, {185, 368}}
- GroupTreeTableConfiguration
-
- MainColumn
- 168
-
- RubberWindowFrame
- 424 558 744 409 0 0 1680 1028
-
- Module
- PBXSmartGroupTreeModule
- Proportion
- 185pt
-
-
- BecomeActive
-
- ContentConfiguration
-
- PBXProjectModuleGUID
- 1CA1AED706398EBD00589147
- PBXProjectModuleLabel
- Detail
-
- GeometryConfiguration
-
- Frame
- {{190, 0}, {554, 368}}
- RubberWindowFrame
- 424 558 744 409 0 0 1680 1028
-
- Module
- XCDetailModule
- Proportion
- 554pt
-
-
- Proportion
- 368pt
-
-
- MajorVersion
- 3
- MinorVersion
- 0
- Name
- Breakpoints
- ServiceClasses
-
- PBXSmartGroupTreeModule
- XCDetailModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 2CA2CD2C0CF61AD5008733A1
- 2CA2CD2D0CF61AD5008733A1
- 1CE0B1FE06471DED0097A5F4
- 1CA1AED706398EBD00589147
-
- ToolbarConfiguration
- xcode.toolbar.config.breakpointsV3
- WindowString
- 424 558 744 409 0 0 1680 1028
- WindowToolGUID
- 2CA2CD2C0CF61AD5008733A1
- WindowToolIsVisible
-
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.debugAnimator
- Layout
-
-
- Dock
-
-
- Module
- PBXNavigatorGroup
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Debug Visualizer
- ServiceClasses
-
- PBXNavigatorGroup
-
- StatusbarIsVisible
-
- ToolbarConfiguration
- xcode.toolbar.config.debugAnimatorV3
- WindowString
- 100 100 700 500 0 0 1280 1002
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.bookmarks
- Layout
-
-
- Dock
-
-
- Module
- PBXBookmarksModule
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Bookmarks
- ServiceClasses
-
- PBXBookmarksModule
-
- StatusbarIsVisible
-
- WindowString
- 538 42 401 187 0 0 1280 1002
-
-
- Identifier
- windowTool.projectFormatConflicts
- Layout
-
-
- Dock
-
-
- Module
- XCProjectFormatConflictsModule
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Project Format Conflicts
- ServiceClasses
-
- XCProjectFormatConflictsModule
-
- StatusbarIsVisible
-
- WindowContentMinSize
- 450 300
- WindowString
- 50 850 472 307 0 0 1440 877
-
-
- FirstTimeWindowDisplayed
-
- Identifier
- windowTool.classBrowser
- Layout
-
-
- Dock
-
-
- BecomeActive
- 1
- ContentConfiguration
-
- OptionsSetName
- Hierarchy, all classes
- PBXProjectModuleGUID
- 1CA6456E063B45B4001379D8
- PBXProjectModuleLabel
- Class Browser - NSObject
-
- GeometryConfiguration
-
- ClassesFrame
- {{0, 0}, {374, 96}}
- ClassesTreeTableConfiguration
-
- PBXClassNameColumnIdentifier
- 208
- PBXClassBookColumnIdentifier
- 22
-
- Frame
- {{0, 0}, {630, 331}}
- MembersFrame
- {{0, 105}, {374, 395}}
- MembersTreeTableConfiguration
-
- PBXMemberTypeIconColumnIdentifier
- 22
- PBXMemberNameColumnIdentifier
- 216
- PBXMemberTypeColumnIdentifier
- 97
- PBXMemberBookColumnIdentifier
- 22
-
- PBXModuleWindowStatusBarHidden2
- 1
- RubberWindowFrame
- 385 179 630 352 0 0 1440 878
-
- Module
- PBXClassBrowserModule
- Proportion
- 332pt
-
-
- Proportion
- 332pt
-
-
- Name
- Class Browser
- ServiceClasses
-
- PBXClassBrowserModule
-
- StatusbarIsVisible
-
- TableOfContents
-
- 1C0AD2AF069F1E9B00FABCE6
- 1C0AD2B0069F1E9B00FABCE6
- 1CA6456E063B45B4001379D8
-
- ToolbarConfiguration
- xcode.toolbar.config.classbrowser
- WindowString
- 385 179 630 352 0 0 1440 878
- WindowToolGUID
- 1C0AD2AF069F1E9B00FABCE6
- WindowToolIsVisible
-
-
-
- Identifier
- windowTool.refactoring
- IncludeInToolsMenu
-
- Layout
-
-
- Dock
-
-
- BecomeActive
-
- GeometryConfiguration
-
- Frame
- {0, 0}, {500, 335}
- RubberWindowFrame
- {0, 0}, {500, 335}
-
- Module
- XCRefactoringModule
- Proportion
- 100%
-
-
- Proportion
- 100%
-
-
- Name
- Refactoring
- ServiceClasses
-
- XCRefactoringModule
-
- WindowString
- 200 200 500 356 0 0 1920 1200
-
-
-
-
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
deleted file mode 100644
index e054f93e..00000000
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
+++ /dev/null
@@ -1,1414 +0,0 @@
-// !$*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}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{0, 1115}";
- sepNavWindowFrame = "{{15, 465}, {750, 558}}";
- };
- };
- 2C4D9C620CC9EC8C0031092D /* TextGL.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 7532}}";
- sepNavSelRange = "{10589, 66}";
- sepNavVisRange = "{10222, 893}";
- sepNavVisRect = "{{0, 5908}, {758, 716}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {923, 2128}}";
- sepNavSelRange = "{1154, 0}";
- sepNavVisRect = "{{0, 354}, {923, 342}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 4130}}";
- sepNavSelRange = "{79, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{84, 115}, {797, 845}}";
- };
- };
- 2C4D9C670CC9EC8C0031092D /* UCommon.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {695, 4060}}";
- sepNavSelRange = "{584, 24}";
- sepNavVisRange = "{249, 1447}";
- sepNavVisRect = "{{0, 508}, {715, 815}}";
- sepNavWindowFrame = "{{38, 78}, {754, 944}}";
- };
- };
- 2C4D9C680CC9EC8C0031092D /* UCore.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1202, 7294}}";
- sepNavSelRange = "{12520, 0}";
- sepNavVisRect = "{{0, 844}, {758, 716}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {577, 1708}}";
- sepNavSelRange = "{262, 0}";
- sepNavVisRect = "{{0, 0}, {577, 612}}";
- sepNavWindowFrame = "{{38, 261}, {616, 741}}";
- };
- };
- 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 3668}}";
- sepNavSelRange = "{49, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{130, 73}, {797, 845}}";
- };
- };
- 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {4058, 5082}}";
- sepNavSelRange = "{1600, 0}";
- sepNavVisRect = "{{0, 1250}, {923, 342}}";
- sepNavWindowFrame = "{{153, 52}, {797, 845}}";
- };
- };
- 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1424, 3542}}";
- sepNavSelRange = "{4330, 0}";
- sepNavVisRange = "{3445, 1320}";
- sepNavVisRect = "{{0, 456}, {758, 716}}";
- sepNavWindowFrame = "{{15, 178}, {797, 845}}";
- };
- };
- 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {836, 19516}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{6577, 1474}";
- sepNavVisRect = "{{0, 4065}, {1277, 312}}";
- sepNavWindowFrame = "{{61, 122}, {794, 859}}";
- };
- };
- 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {815, 2086}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{2303, 2169}";
- sepNavVisRect = "{{0, 4494}, {923, 342}}";
- sepNavWindowFrame = "{{84, 77}, {874, 883}}";
- };
- };
- 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {729, 10626}}";
- sepNavSelRange = "{16099, 0}";
- sepNavVisRange = "{13982, 870}";
- sepNavVisRect = "{{0, 3790}, {749, 470}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1052, 9450}}";
- sepNavSelRange = "{5863, 11}";
- sepNavVisRect = "{{0, 2572}, {749, 470}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9C710CC9EC8C0031092D /* UHooks.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1277, 5964}}";
- sepNavSelRange = "{11810, 0}";
- sepNavVisRect = "{{0, 5652}, {1277, 312}}";
- sepNavWindowFrame = "{{84, 115}, {797, 845}}";
- };
- };
- 2C4D9C720CC9EC8C0031092D /* UIni.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 11214}}";
- sepNavSelRange = "{5601, 15}";
- sepNavVisRange = "{5183, 839}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {896, 3962}}";
- sepNavSelRange = "{46, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{130, 73}, {797, 845}}";
- };
- };
- 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {738, 3388}}";
- sepNavSelRange = "{28, 58}";
- sepNavVisRange = "{0, 1050}";
- sepNavVisRect = "{{0, 914}, {923, 342}}";
- sepNavWindowFrame = "{{153, 52}, {797, 845}}";
- };
- };
- 2C4D9C760CC9EC8C0031092D /* ULCD.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {577, 4270}}";
- sepNavSelRange = "{25, 0}";
- sepNavVisRect = "{{0, 0}, {577, 612}}";
- sepNavWindowFrame = "{{176, 135}, {616, 741}}";
- };
- };
- 2C4D9C770CC9EC8C0031092D /* ULight.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 2282}}";
- sepNavSelRange = "{1017, 0}";
- sepNavVisRect = "{{0, 425}, {758, 716}}";
- sepNavWindowFrame = "{{15, 178}, {797, 845}}";
- };
- };
- 2C4D9C780CC9EC8C0031092D /* ULog.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 4102}}";
- sepNavSelRange = "{6569, 0}";
- sepNavVisRange = "{6421, 474}";
- sepNavVisRect = "{{0, 147}, {758, 716}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1070, 5950}}";
- sepNavSelRange = "{34, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{84, 115}, {797, 845}}";
- };
- };
- 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 10626}}";
- sepNavSelRange = "{6965, 12}";
- sepNavVisRange = "{6549, 702}";
- sepNavVisRect = "{{0, 4395}, {758, 716}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1026, 16268}}";
- sepNavSelRange = "{31433, 0}";
- sepNavVisRange = "{32193, 1839}";
- sepNavVisRect = "{{0, 0}, {1013, 614}}";
- sepNavWindowFrame = "{{30, 285}, {1052, 743}}";
- };
- };
- 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {738, 3864}}";
- sepNavSelRange = "{960, 0}";
- sepNavVisRange = "{4488, 788}";
- sepNavVisRect = "{{0, 1071}, {749, 470}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
- sepNavSelRange = "{31, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{130, 73}, {797, 845}}";
- };
- };
- 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {749, 4494}}";
- sepNavSelRange = "{4994, 0}";
- sepNavVisRect = "{{0, 4024}, {749, 470}}";
- sepNavWindowFrame = "{{153, 52}, {797, 845}}";
- };
- };
- 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {854, 8988}}";
- sepNavSelRange = "{17977, 0}";
- sepNavVisRange = "{16881, 1096}";
- sepNavVisRect = "{{0, 3141}, {1305, 534}}";
- sepNavWindowFrame = "{{15, 178}, {797, 845}}";
- };
- };
- 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {824, 6496}}";
- sepNavSelRange = "{51, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 2198}}";
- sepNavSelRange = "{247, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{84, 115}, {797, 845}}";
- };
- };
- 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1718, 11116}}";
- sepNavSelRange = "{317, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9C840CC9EC8C0031092D /* URecord.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {738, 8372}}";
- sepNavSelRange = "{10657, 20}";
- sepNavVisRange = "{10176, 1198}";
- sepNavVisRect = "{{0, 4312}, {758, 716}}";
- sepNavWindowFrame = "{{130, 73}, {797, 845}}";
- };
- };
- 2C4D9C850CC9EC8C0031092D /* UServices.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1916, 4494}}";
- sepNavSelRange = "{9160, 4}";
- sepNavVisRect = "{{0, 4182}, {1277, 312}}";
- sepNavWindowFrame = "{{153, 52}, {797, 845}}";
- };
- };
- 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
- sepNavSelRange = "{52, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{15, 178}, {797, 845}}";
- };
- };
- 2C4D9C870CC9EC8C0031092D /* USingScores.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {950, 13818}}";
- sepNavSelRange = "{15011, 16}";
- sepNavVisRect = "{{0, 5904}, {749, 470}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9C880CC9EC8C0031092D /* USkins.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 2450}}";
- sepNavSelRange = "{2805, 0}";
- sepNavVisRange = "{2928, 803}";
- sepNavVisRect = "{{0, 550}, {923, 342}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9C890CC9EC8C0031092D /* USongs.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {920, 13636}}";
- sepNavSelRange = "{6946, 0}";
- sepNavVisRange = "{6429, 995}";
- sepNavVisRect = "{{0, 4157}, {758, 716}}";
- sepNavWindowFrame = "{{15, 156}, {797, 845}}";
- };
- };
- 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1010, 854}}";
- sepNavSelRange = "{54, 0}";
- sepNavVisRect = "{{0, 138}, {758, 716}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {858, 16688}}";
- sepNavSelRange = "{10496, 0}";
- sepNavVisRange = "{9368, 1825}";
- sepNavVisRect = "{{0, 3420}, {737, 826}}";
- sepNavWindowFrame = "{{15, 68}, {776, 955}}";
- };
- };
- 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 32242}}";
- sepNavSelRange = "{59317, 12}";
- sepNavVisRange = "{61073, 1036}";
- sepNavVisRect = "{{0, 19678}, {923, 342}}";
- sepNavWindowFrame = "{{28, 161}, {797, 845}}";
- };
- };
- 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 1400}}";
- sepNavSelRange = "{42, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{153, 52}, {797, 845}}";
- };
- };
- 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {914, 9016}}";
- sepNavSelRange = "{12966, 0}";
- sepNavVisRange = "{12857, 955}";
- sepNavVisRect = "{{0, 5722}, {749, 470}}";
- sepNavWindowFrame = "{{15, 178}, {797, 845}}";
- };
- };
- 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {974, 24374}}";
- sepNavSelRange = "{1377, 0}";
- sepNavVisRect = "{{0, 0}, {577, 612}}";
- sepNavWindowFrame = "{{245, 72}, {616, 741}}";
- };
- };
- 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1718, 10416}}";
- sepNavSelRange = "{1255, 0}";
- sepNavVisRect = "{{0, 373}, {577, 612}}";
- sepNavWindowFrame = "{{15, 282}, {616, 741}}";
- };
- };
- 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 6944}}";
- sepNavSelRange = "{5028, 51}";
- sepNavVisRange = "{4044, 1359}";
- sepNavVisRect = "{{0, 4834}, {758, 716}}";
- sepNavWindowFrame = "{{38, 157}, {797, 845}}";
- };
- };
- 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {738, 1470}}";
- sepNavSelRange = "{2779, 0}";
- sepNavVisRange = "{937, 1764}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1284, 22162}}";
- sepNavSelRange = "{51782, 0}";
- sepNavVisRange = "{51126, 1038}";
- sepNavVisRect = "{{0, 3972}, {749, 470}}";
- sepNavWindowFrame = "{{38, 82}, {898, 920}}";
- };
- };
- 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {934, 7546}}";
- sepNavSelRange = "{10421, 15}";
- sepNavVisRange = "{9357, 1695}";
- sepNavVisRect = "{{0, 1104}, {577, 612}}";
- sepNavWindowFrame = "{{44, 71}, {993, 935}}";
- };
- };
- 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 1008}}";
- sepNavSelRange = "{63, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{61, 136}, {797, 845}}";
- };
- };
- 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
- sepNavSelRange = "{55, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{84, 115}, {797, 845}}";
- };
- };
- 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {577, 2828}}";
- sepNavSelRange = "{53, 0}";
- sepNavVisRect = "{{0, 0}, {577, 612}}";
- sepNavWindowFrame = "{{130, 177}, {616, 741}}";
- };
- };
- 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 4928}}";
- sepNavSelRange = "{58, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
- sepNavWindowFrame = "{{107, 94}, {797, 845}}";
- };
- };
- 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 1204}}";
- sepNavSelRange = "{400, 0}";
- sepNavVisRange = "{184, 530}";
- sepNavVisRect = "{{0, 0}, {577, 612}}";
- sepNavWindowFrame = "{{107, 198}, {616, 741}}";
- };
- };
- 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {962, 5222}}";
- sepNavSelRange = "{2165, 0}";
- sepNavVisRect = "{{0, 707}, {758, 716}}";
- sepNavWindowFrame = "{{130, 73}, {797, 845}}";
- };
- };
- 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1268, 4788}}";
- sepNavSelRange = "{15613, 0}";
- sepNavVisRect = "{{0, 1736}, {1013, 614}}";
- sepNavWindowFrame = "{{15, 280}, {1052, 743}}";
- };
- };
- 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1268, 6552}}";
- sepNavSelRange = "{8844, 12}";
- sepNavVisRect = "{{0, 2054}, {749, 470}}";
- };
- };
- 2C4D9E040CC9EF840031092D /* OpenGL12.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1608, 64064}}";
- sepNavSelRange = "{213678, 0}";
- sepNavVisRange = "{207797, 6669}";
- sepNavVisRect = "{{0, 64932}, {1031, 840}}";
- sepNavWindowFrame = "{{1, 63}, {1070, 965}}";
- };
- };
- 2C4D9E090CC9EF840031092D /* Windows.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {577, 2352}}";
- sepNavSelRange = "{2345, 0}";
- sepNavVisRect = "{{0, 1278}, {577, 612}}";
- sepNavWindowFrame = "{{176, 135}, {616, 741}}";
- };
- };
- 2C4D9E440CC9F0ED0031092D /* switches.inc */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {624, 1918}}";
- sepNavSelRange = "{1326, 0}";
- sepNavVisRange = "{657, 1095}";
- sepNavVisRect = "{{0, 7}, {577, 612}}";
- sepNavWindowFrame = "{{15, 282}, {616, 741}}";
- };
- };
- 2C5663EE0D35645700D4FF53 /* portaudio.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 16842}}";
- sepNavSelRange = "{2289, 0}";
- sepNavVisRange = "{7295, 1046}";
- };
- };
- 2C56642B0D35683200D4FF53 /* SDLMain.m */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 5404}}";
- sepNavSelRange = "{247, 16}";
- sepNavVisRange = "{0, 1181}";
- };
- };
- 2C8937290CE393FB005D8A87 /* UPlatform.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {717, 1120}}";
- sepNavSelRange = "{830, 0}";
- sepNavVisRange = "{241, 1433}";
- sepNavVisRect = "{{0, 0}, {737, 826}}";
- sepNavWindowFrame = "{{200, 71}, {776, 955}}";
- };
- };
- 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {744, 1890}}";
- sepNavSelRange = "{717, 0}";
- 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}, {842, 3766}}";
- sepNavSelRange = "{5570, 0}";
- sepNavVisRange = "{5295, 761}";
- sepNavWindowFrame = "{{15, 140}, {874, 883}}";
- };
- };
- 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {934, 6104}}";
- sepNavSelRange = "{4658, 3}";
- sepNavVisRange = "{4001, 1277}";
- sepNavWindowFrame = "{{38, 67}, {993, 935}}";
- };
- };
- 2CB9E87D0D43B78400214DFA /* USong.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1550, 10290}}";
- sepNavSelRange = "{19153, 0}";
- sepNavVisRange = "{18134, 1509}";
- sepNavWindowFrame = "{{15, 88}, {993, 935}}";
- };
- };
- 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 1022}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRect = "{{0, 0}, {1013, 614}}";
- sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
- };
- };
- 2CDD4B5D0CB9354800549FAC /* UltraStarDX */ = {
- isa = PBXExecutable;
- activeArgIndices = (
- );
- argumentStrings = (
- );
- autoAttachOnCrash = 1;
- breakpointsEnabled = 0;
- configStateDict = {
- };
- customDataFormattersEnabled = 1;
- debuggerPlugin = GDBDebugging;
- disassemblyDisplayState = 0;
- dylibVariantSuffix = "";
- enableDebugStr = 1;
- environmentEntries = (
- );
- executableSystemSymbolLevel = 0;
- executableUserSymbolLevel = 0;
- libgmallocEnabled = 0;
- name = UltraStarDX;
- savedGlobals = {
- };
- sourceDirectories = (
- );
- variableFormatDictionary = {
- $cs = 1;
- $ds = 1;
- $eax = 1;
- $ebp = 1;
- $ebx = 1;
- $ecx = 1;
- $edi = 1;
- $edx = 1;
- $eflags = 1;
- $eip = 1;
- $es = 1;
- $esi = 1;
- $esp = 1;
- $gs = 1;
- $ss = 1;
- };
- };
- 2CDD4B690CB9357000549FAC /* Source Control */ = {
- isa = PBXSourceControlManager;
- fallbackIsa = XCSourceControlManager;
- isSCMEnabled = 0;
- scmConfiguration = {
- };
- scmType = "";
- };
- 2CDD4B6A0CB9357000549FAC /* Code sense */ = {
- isa = PBXCodeSenseManager;
- indexTemplatePath = "";
- };
- 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {934, 1764}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{0, 1211}";
- sepNavWindowFrame = "{{15, 88}, {993, 935}}";
- };
- };
- 2CE603E10D715F8600DB0D88 /* UConfig.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 3080}}";
- sepNavSelRange = "{7279, 0}";
- sepNavVisRange = "{6847, 865}";
- };
- };
- 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 686}}";
- sepNavSelRange = "{598, 0}";
- sepNavVisRange = "{214, 458}";
- sepNavVisRect = "{{0, 0}, {737, 826}}";
- sepNavWindowFrame = "{{15, 68}, {776, 955}}";
- };
- };
- 2CF3EF210CDE13A0004F5956 /* Messages.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 614}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRect = "{{0, 0}, {1013, 614}}";
- sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
- };
- };
- 2CF3EF260CDE13BA004F5956 /* MacResources.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {834, 1750}}";
- sepNavSelRange = "{1218, 0}";
- sepNavVisRect = "{{0, 1120}, {834, 610}}";
- sepNavWindowFrame = "{{200, 248}, {873, 739}}";
- };
- };
- 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {695, 19544}}";
- sepNavSelRange = "{26865, 471}";
- sepNavVisRange = "{25408, 2367}";
- sepNavVisRect = "{{0, 1770}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1610}}";
- sepNavSelRange = "{34, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {842, 8484}}";
- sepNavSelRange = "{13516, 0}";
- sepNavVisRange = "{13202, 415}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 5180}}";
- sepNavSelRange = "{59, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1040, 19236}}";
- sepNavSelRange = "{37, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1302}}";
- sepNavSelRange = "{54, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 815}}";
- sepNavSelRange = "{58, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {695, 4326}}";
- sepNavSelRange = "{1560, 17}";
- sepNavVisRange = "{1022, 1336}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 79}, {754, 944}}";
- };
- };
- 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {956, 3318}}";
- sepNavSelRange = "{34, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 2366}}";
- sepNavSelRange = "{55, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 2506}}";
- sepNavSelRange = "{311, 0}";
- sepNavVisRect = "{{0, 188}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1484}}";
- sepNavSelRange = "{45, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1582}}";
- sepNavSelRange = "{60, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1400}}";
- sepNavSelRange = "{64, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1330}}";
- sepNavSelRange = "{62, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {776, 1974}}";
- sepNavSelRange = "{39, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1414}}";
- sepNavSelRange = "{42, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1680}}";
- sepNavSelRange = "{43, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 5880}}";
- sepNavSelRange = "{62, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 3640}}";
- sepNavSelRange = "{61, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {956, 4648}}";
- sepNavSelRange = "{62, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1046, 4116}}";
- sepNavSelRange = "{61, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {752, 3640}}";
- sepNavSelRange = "{59, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */ = {
- uiCtxt = {
- 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}, {792, 14714}}";
- sepNavSelRange = "{4909, 0}";
- sepNavVisRange = "{4202, 810}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1250, 18788}}";
- sepNavSelRange = "{39356, 0}";
- sepNavVisRange = "{39482, 1725}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 78}, {754, 944}}";
- };
- };
- 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {729, 9912}}";
- sepNavSelRange = "{21169, 11}";
- sepNavVisRange = "{20602, 649}";
- sepNavVisRect = "{{0, 187}, {1277, 312}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {881, 31066}}";
- sepNavSelRange = "{7241, 96}";
- sepNavVisRange = "{6687, 1426}";
- sepNavVisRect = "{{0, 11219}, {1277, 312}}";
- sepNavWindowFrame = "{{38, 78}, {754, 944}}";
- };
- };
- 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1160, 2884}}";
- sepNavSelRange = "{61, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */ = {
- uiCtxt = {
- 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}, {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}, {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}, {729, 2492}}";
- sepNavSelRange = "{996, 0}";
- sepNavVisRange = "{458, 883}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {715, 1694}}";
- sepNavSelRange = "{58, 0}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{38, 58}, {754, 944}}";
- };
- };
- 2CF5508B0CDA22B000627463 /* ModiSDK.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {986, 2128}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{0, 2269}";
- sepNavVisRect = "{{0, 0}, {715, 815}}";
- sepNavWindowFrame = "{{15, 79}, {754, 944}}";
- };
- };
- 2CF5510E0CDA293700627463 /* SQLite3.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1364, 2800}}";
- sepNavSelRange = "{517, 0}";
- sepNavVisRect = "{{0, 0}, {1031, 840}}";
- sepNavWindowFrame = "{{15, 54}, {1070, 969}}";
- };
- };
- 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1031, 10766}}";
- sepNavSelRange = "{559, 0}";
- sepNavVisRect = "{{0, 0}, {1031, 840}}";
- sepNavWindowFrame = "{{15, 54}, {1070, 969}}";
- };
- };
- 2CF551A70CDA356800627463 /* UltraStar.dpr */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {914, 2674}}";
- sepNavSelRange = "{4560, 0}";
- sepNavVisRect = "{{0, 990}, {737, 827}}";
- sepNavWindowFrame = "{{15, 67}, {776, 956}}";
- };
- };
- 2CF552110CDA3D1400627463 /* UPluginDefs.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 2506}}";
- sepNavSelRange = "{5, 11}";
- sepNavVisRect = "{{0, 0}, {1013, 614}}";
- sepNavWindowFrame = "{{107, 196}, {1052, 743}}";
- };
- };
- 2CF5529E0CDA42C900627463 /* avcodec.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {993, 28406}}";
- sepNavSelRange = "{1536, 0}";
- sepNavVisRange = "{0, 1591}";
- sepNavVisRect = "{{0, 375}, {1013, 614}}";
- sepNavWindowFrame = "{{176, 133}, {1052, 743}}";
- };
- };
- 2CF5529F0CDA42C900627463 /* avformat.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {993, 10206}}";
- sepNavSelRange = "{1559, 189}";
- sepNavVisRange = "{1159, 858}";
- sepNavVisRect = "{{0, 298}, {1013, 614}}";
- sepNavWindowFrame = "{{245, 70}, {1052, 743}}";
- };
- };
- 2CF552A00CDA42C900627463 /* avio.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 3598}}";
- sepNavSelRange = "{347, 0}";
- sepNavVisRect = "{{0, 190}, {1013, 614}}";
- sepNavWindowFrame = "{{199, 112}, {1052, 743}}";
- };
- };
- 2CF552A10CDA42C900627463 /* avutil.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {993, 2170}}";
- sepNavSelRange = "{1520, 0}";
- sepNavVisRange = "{0, 1756}";
- sepNavVisRect = "{{0, 293}, {1013, 614}}";
- sepNavWindowFrame = "{{222, 91}, {1052, 743}}";
- };
- };
- 2CF553070CDA51B500627463 /* sdlutils.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 61068}}";
- sepNavSelRange = "{8481, 20}";
- sepNavVisRect = "{{0, 1054}, {1013, 614}}";
- sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
- };
- };
- 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */ = {
- activeExec = 0;
- };
- 98B8BE5C0B1F974F00162019 /* sdl.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1268, 58492}}";
- sepNavSelRange = "{157855, 0}";
- sepNavVisRect = "{{0, 3444}, {948, 730}}";
- sepNavWindowFrame = "{{211, 143}, {987, 859}}";
- };
- };
- DD37F2420A60255800975B2D /* fpcrtl */ = {
- activeExec = 0;
- };
- DDC6850F09F5717A004E4BFF /* Project object */ = {
- activeArchitecture = i386;
- activeBuildConfigurationName = Release;
- activeExecutable = 2CDD4B5D0CB9354800549FAC /* UltraStarDX */;
- activeTarget = DDC688C709F574E9004E4BFF /* UltraStarDX */;
- addToTargets = (
- );
- breakpoints = (
- );
- codeSenseManager = 2CDD4B6A0CB9357000549FAC /* Code sense */;
- executables = (
- 2CDD4B5D0CB9354800549FAC /* UltraStarDX */,
- );
- perUserDictionary = {
- "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 20,
- 20,
- 198,
- 20,
- 99,
- 99,
- 29,
- 20,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXBreakpointsDataSource_ActionID,
- PBXBreakpointsDataSource_TypeID,
- PBXBreakpointsDataSource_BreakpointID,
- PBXBreakpointsDataSource_UseID,
- PBXBreakpointsDataSource_LocationID,
- PBXBreakpointsDataSource_ConditionID,
- PBXBreakpointsDataSource_IgnoreCountID,
- PBXBreakpointsDataSource_ContinueID,
- );
- };
- PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 22,
- 300,
- 67,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXExecutablesDataSource_ActiveFlagID,
- PBXExecutablesDataSource_NameID,
- PBXExecutablesDataSource_CommentsID,
- );
- };
- PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 20,
- 290,
- 20,
- 48,
- 43,
- 43,
- 20,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXFileDataSource_FiletypeID,
- PBXFileDataSource_Filename_ColumnID,
- PBXFileDataSource_Built_ColumnID,
- PBXFileDataSource_ObjectSize_ColumnID,
- PBXFileDataSource_Errors_ColumnID,
- PBXFileDataSource_Warnings_ColumnID,
- PBXFileDataSource_Target_ColumnID,
- );
- };
- PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 16,
- 200,
- 50,
- 119,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXSymbolsDataSource_SymbolTypeIconID,
- PBXSymbolsDataSource_SymbolNameID,
- PBXSymbolsDataSource_SymbolTypeID,
- PBXSymbolsDataSource_ReferenceNameID,
- );
- };
- PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 20,
- 20,
- 266,
- 20,
- 48,
- 43,
- 43,
- 20,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXFileDataSource_SCM_ColumnID,
- PBXFileDataSource_FiletypeID,
- PBXFileDataSource_Filename_ColumnID,
- PBXFileDataSource_Built_ColumnID,
- PBXFileDataSource_ObjectSize_ColumnID,
- PBXFileDataSource_Errors_ColumnID,
- PBXFileDataSource_Warnings_ColumnID,
- PBXFileDataSource_Target_ColumnID,
- );
- };
- PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
- PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
- PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
- PBXFileTableDataSourceColumnWidthsKey = (
- 20,
- 250,
- 60,
- 20,
- 48,
- 43,
- 43,
- );
- PBXFileTableDataSourceColumnsKey = (
- PBXFileDataSource_FiletypeID,
- PBXFileDataSource_Filename_ColumnID,
- PBXTargetDataSource_PrimaryAttribute,
- PBXFileDataSource_Built_ColumnID,
- PBXFileDataSource_ObjectSize_ColumnID,
- PBXFileDataSource_Errors_ColumnID,
- PBXFileDataSource_Warnings_ColumnID,
- );
- };
- PBXPerProjectTemplateStateSaveDate = 228166993;
- PBXWorkspaceStateSaveDate = 228166993;
- };
- perUserProjectItems = {
- 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 = {
- };
- };
- DDC6851B09F57195004E4BFF /* UltraStarDX.pas */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {928, 731}}";
- sepNavSelRange = "{72, 0}";
- sepNavVisRange = "{0, 152}";
- sepNavVisRect = "{{0, 0}, {948, 730}}";
- sepNavWindowFrame = "{{311, 112}, {987, 859}}";
- };
- };
- DDC6868B09F571C2004E4BFF /* Info.plist */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 614}}";
- sepNavSelRange = "{366, 0}";
- sepNavVisRect = "{{0, 0}, {1013, 614}}";
- sepNavWindowFrame = "{{15, 280}, {1052, 743}}";
- };
- };
- DDC688C709F574E9004E4BFF /* UltraStarDX */ = {
- activeExec = 0;
- executables = (
- 2CDD4B5D0CB9354800549FAC /* UltraStarDX */,
- );
- };
- DDC688D409F57523004E4BFF /* Put all program sources also in this target */ = {
- activeExec = 0;
- };
- DDC689B309F57C69004E4BFF /* InfoPlist.strings */ = {
- uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1385, 731}}";
- sepNavSelRange = "{256, 0}";
- sepNavVisRect = "{{0, 0}, {1385, 731}}";
- sepNavWindowFrame = "{{38, 142}, {1424, 860}}";
- };
- };
-}
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj b/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
deleted file mode 100644
index d7902145..00000000
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1613 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXBuildFile section */
- 2C4B70230CF7581000B0F0BD /* Until5000.dpr in Sources */ = {isa = PBXBuildFile; fileRef = 2C4B70220CF757A400B0F0BD /* Until5000.dpr */; };
- 2C4B70240CF7584500B0F0BD /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
- 2C4D9C8F0CC9EC8C0031092D /* TextGL.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C620CC9EC8C0031092D /* TextGL.pas */; };
- 2C4D9C920CC9EC8C0031092D /* UCatCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */; };
- 2C4D9C930CC9EC8C0031092D /* UCommandLine.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */; };
- 2C4D9C940CC9EC8C0031092D /* UCommon.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; };
- 2C4D9C950CC9EC8C0031092D /* UCore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C680CC9EC8C0031092D /* UCore.pas */; };
- 2C4D9C960CC9EC8C0031092D /* UCoreModule.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */; };
- 2C4D9C970CC9EC8C0031092D /* UCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */; };
- 2C4D9C980CC9EC8C0031092D /* UDataBase.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */; };
- 2C4D9C990CC9EC8C0031092D /* UDLLManager.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */; };
- 2C4D9C9A0CC9EC8C0031092D /* UDraw.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */; };
- 2C4D9C9B0CC9EC8C0031092D /* UFiles.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */; };
- 2C4D9C9C0CC9EC8C0031092D /* UGraphic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */; };
- 2C4D9C9D0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */; };
- 2C4D9C9E0CC9EC8C0031092D /* UHooks.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C710CC9EC8C0031092D /* UHooks.pas */; };
- 2C4D9C9F0CC9EC8C0031092D /* UIni.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C720CC9EC8C0031092D /* UIni.pas */; };
- 2C4D9CA00CC9EC8C0031092D /* UJoystick.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */; };
- 2C4D9CA10CC9EC8C0031092D /* ULanguage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */; };
- 2C4D9CA30CC9EC8C0031092D /* ULCD.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C760CC9EC8C0031092D /* ULCD.pas */; };
- 2C4D9CA40CC9EC8C0031092D /* ULight.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C770CC9EC8C0031092D /* ULight.pas */; };
- 2C4D9CA50CC9EC8C0031092D /* ULog.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C780CC9EC8C0031092D /* ULog.pas */; };
- 2C4D9CA60CC9EC8C0031092D /* ULyrics_bak.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */; };
- 2C4D9CA70CC9EC8C0031092D /* ULyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */; };
- 2C4D9CA80CC9EC8C0031092D /* UMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; };
- 2C4D9CA90CC9EC8C0031092D /* UMedia_dummy.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */; };
- 2C4D9CAA0CC9EC8C0031092D /* UModules.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */; };
- 2C4D9CAB0CC9EC8C0031092D /* UMusic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */; };
- 2C4D9CAC0CC9EC8C0031092D /* UParty.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */; };
- 2C4D9CAD0CC9EC8C0031092D /* UPlaylist.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */; };
- 2C4D9CAF0CC9EC8C0031092D /* UPluginInterface.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */; };
- 2C4D9CB00CC9EC8C0031092D /* uPluginLoader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */; };
- 2C4D9CB10CC9EC8C0031092D /* URecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C840CC9EC8C0031092D /* URecord.pas */; };
- 2C4D9CB20CC9EC8C0031092D /* UServices.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C850CC9EC8C0031092D /* UServices.pas */; };
- 2C4D9CB30CC9EC8C0031092D /* USingNotes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */; };
- 2C4D9CB40CC9EC8C0031092D /* USingScores.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C870CC9EC8C0031092D /* USingScores.pas */; };
- 2C4D9CB50CC9EC8C0031092D /* USkins.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C880CC9EC8C0031092D /* USkins.pas */; };
- 2C4D9CB60CC9EC8C0031092D /* USongs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */; };
- 2C4D9CB70CC9EC8C0031092D /* UTextClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */; };
- 2C4D9CB80CC9EC8C0031092D /* UTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; };
- 2C4D9CB90CC9EC8C0031092D /* UThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */; };
- 2C4D9CBA0CC9EC8C0031092D /* UTime.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */; };
- 2C4D9CBB0CC9EC8C0031092D /* UVideo.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */; };
- 2C4D9CBC0CC9EC8C0031092D /* TextGL.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C620CC9EC8C0031092D /* TextGL.pas */; };
- 2C4D9CBF0CC9EC8C0031092D /* UCatCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */; };
- 2C4D9CC00CC9EC8C0031092D /* UCommandLine.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */; };
- 2C4D9CC10CC9EC8C0031092D /* UCommon.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; };
- 2C4D9CC20CC9EC8C0031092D /* UCore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C680CC9EC8C0031092D /* UCore.pas */; };
- 2C4D9CC30CC9EC8C0031092D /* UCoreModule.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */; };
- 2C4D9CC40CC9EC8C0031092D /* UCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */; };
- 2C4D9CC50CC9EC8C0031092D /* UDataBase.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */; };
- 2C4D9CC60CC9EC8C0031092D /* UDLLManager.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */; };
- 2C4D9CC70CC9EC8C0031092D /* UDraw.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */; };
- 2C4D9CC80CC9EC8C0031092D /* UFiles.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */; };
- 2C4D9CC90CC9EC8C0031092D /* UGraphic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */; };
- 2C4D9CCA0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */; };
- 2C4D9CCB0CC9EC8C0031092D /* UHooks.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C710CC9EC8C0031092D /* UHooks.pas */; };
- 2C4D9CCC0CC9EC8C0031092D /* UIni.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C720CC9EC8C0031092D /* UIni.pas */; };
- 2C4D9CCD0CC9EC8C0031092D /* UJoystick.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */; };
- 2C4D9CCE0CC9EC8C0031092D /* ULanguage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */; };
- 2C4D9CD00CC9EC8C0031092D /* ULCD.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C760CC9EC8C0031092D /* ULCD.pas */; };
- 2C4D9CD10CC9EC8C0031092D /* ULight.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C770CC9EC8C0031092D /* ULight.pas */; };
- 2C4D9CD20CC9EC8C0031092D /* ULog.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C780CC9EC8C0031092D /* ULog.pas */; };
- 2C4D9CD30CC9EC8C0031092D /* ULyrics_bak.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */; };
- 2C4D9CD40CC9EC8C0031092D /* ULyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */; };
- 2C4D9CD50CC9EC8C0031092D /* UMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; };
- 2C4D9CD60CC9EC8C0031092D /* UMedia_dummy.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */; };
- 2C4D9CD70CC9EC8C0031092D /* UModules.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */; };
- 2C4D9CD80CC9EC8C0031092D /* UMusic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */; };
- 2C4D9CD90CC9EC8C0031092D /* UParty.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */; };
- 2C4D9CDA0CC9EC8C0031092D /* UPlaylist.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */; };
- 2C4D9CDC0CC9EC8C0031092D /* UPluginInterface.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */; };
- 2C4D9CDD0CC9EC8C0031092D /* uPluginLoader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */; };
- 2C4D9CDE0CC9EC8C0031092D /* URecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C840CC9EC8C0031092D /* URecord.pas */; };
- 2C4D9CDF0CC9EC8C0031092D /* UServices.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C850CC9EC8C0031092D /* UServices.pas */; };
- 2C4D9CE00CC9EC8C0031092D /* USingNotes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */; };
- 2C4D9CE10CC9EC8C0031092D /* USingScores.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C870CC9EC8C0031092D /* USingScores.pas */; };
- 2C4D9CE20CC9EC8C0031092D /* USkins.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C880CC9EC8C0031092D /* USkins.pas */; };
- 2C4D9CE30CC9EC8C0031092D /* USongs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */; };
- 2C4D9CE40CC9EC8C0031092D /* UTextClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */; };
- 2C4D9CE50CC9EC8C0031092D /* UTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; };
- 2C4D9CE60CC9EC8C0031092D /* UThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */; };
- 2C4D9CE70CC9EC8C0031092D /* UTime.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */; };
- 2C4D9CE80CC9EC8C0031092D /* UVideo.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */; };
- 2C4D9D920CC9ED4F0031092D /* FreeBitmap.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */; };
- 2C4D9D930CC9ED4F0031092D /* FreeImage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */; };
- 2C4D9D940CC9ED4F0031092D /* FreeBitmap.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */; };
- 2C4D9D950CC9ED4F0031092D /* FreeImage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */; };
- 2C4D9D970CC9EDEB0031092D /* libfreeimage.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */; };
- 2C4D9D9A0CC9EE0B0031092D /* SDL_image.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */; };
- 2C4D9D9B0CC9EE0B0031092D /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */; };
- 2C4D9DD60CC9EE6F0031092D /* UDisplay.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */; };
- 2C4D9DD70CC9EE6F0031092D /* UDrawTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */; };
- 2C4D9DD80CC9EE6F0031092D /* UMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */; };
- 2C4D9DD90CC9EE6F0031092D /* UMenuButton.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */; };
- 2C4D9DDA0CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */; };
- 2C4D9DDB0CC9EE6F0031092D /* UMenuInteract.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */; };
- 2C4D9DDC0CC9EE6F0031092D /* UMenuSelect.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */; };
- 2C4D9DDD0CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */; };
- 2C4D9DDE0CC9EE6F0031092D /* UMenuStatic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */; };
- 2C4D9DDF0CC9EE6F0031092D /* UMenuText.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */; };
- 2C4D9DE00CC9EE6F0031092D /* UDisplay.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */; };
- 2C4D9DE10CC9EE6F0031092D /* UDrawTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */; };
- 2C4D9DE20CC9EE6F0031092D /* UMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */; };
- 2C4D9DE30CC9EE6F0031092D /* UMenuButton.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */; };
- 2C4D9DE40CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */; };
- 2C4D9DE50CC9EE6F0031092D /* UMenuInteract.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */; };
- 2C4D9DE60CC9EE6F0031092D /* UMenuSelect.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */; };
- 2C4D9DE70CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */; };
- 2C4D9DE80CC9EE6F0031092D /* UMenuStatic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */; };
- 2C4D9DE90CC9EE6F0031092D /* UMenuText.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */; };
- 2C4D9DED0CC9EF0A0031092D /* sdl_image.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */; };
- 2C4D9DEE0CC9EF0A0031092D /* sdl_image.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */; };
- 2C4D9DF10CC9EF210031092D /* sdl_ttf.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */; };
- 2C4D9DF30CC9EF210031092D /* sdl_ttf.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */; };
- 2C4D9E100CC9EF840031092D /* OpenGL12.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; };
- 2C4D9E150CC9EF840031092D /* Windows.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E090CC9EF840031092D /* Windows.pas */; };
- 2C4D9E1C0CC9EF840031092D /* OpenGL12.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; };
- 2C4D9E210CC9EF840031092D /* Windows.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E090CC9EF840031092D /* Windows.pas */; };
- 2C4D9E450CC9F0ED0031092D /* switches.inc in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E440CC9F0ED0031092D /* switches.inc */; };
- 2C4D9E460CC9F0ED0031092D /* switches.inc in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E440CC9F0ED0031092D /* switches.inc */; };
- 2C4FA2A80CDBAD1E002CC3B0 /* ustar-icon_v01.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */; };
- 2C5663EF0D35645700D4FF53 /* portaudio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C5663EE0D35645700D4FF53 /* portaudio.pas */; };
- 2C5663F00D35645700D4FF53 /* portaudio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C5663EE0D35645700D4FF53 /* portaudio.pas */; };
- 2C56642C0D35683200D4FF53 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C56642B0D35683200D4FF53 /* SDLMain.m */; };
- 2C89372A0CE393FB005D8A87 /* UPlatform.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937290CE393FB005D8A87 /* UPlatform.pas */; };
- 2C89372B0CE393FB005D8A87 /* UPlatform.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937290CE393FB005D8A87 /* UPlatform.pas */; };
- 2C8937340CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; };
- 2C8937370CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; };
- 2CAC2BE20D3809F500CA518A /* UAudioInput_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */; };
- 2CAC2BE40D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; };
- 2CAC2BE70D3809F500CA518A /* UAudioInput_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */; };
- 2CAC2BE90D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; };
- 2CAC2BF10D380AC200CA518A /* libbass.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CAC2BF00D380AC200CA518A /* libbass.dylib */; };
- 2CAC2BF40D380AE800CA518A /* libbass.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CAC2BF00D380AC200CA518A /* libbass.dylib */; };
- 2CAC2BF80D380B1B00CA518A /* Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BF70D380B1B00CA518A /* Bass.pas */; };
- 2CAC2BF90D380B1B00CA518A /* Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BF70D380B1B00CA518A /* Bass.pas */; };
- 2CB9E87E0D43B78400214DFA /* USong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E87D0D43B78400214DFA /* USong.pas */; };
- 2CB9E87F0D43B78400214DFA /* USong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E87D0D43B78400214DFA /* USong.pas */; };
- 2CDC716C0CDB9CB70018F966 /* StrUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */; };
- 2CDC716D0CDB9CB70018F966 /* StrUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */; };
- 2CDD4BDE0CB947A400549FAC /* sdl.pas in Sources */ = {isa = PBXBuildFile; fileRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */; };
- 2CDD4BE00CB947B100549FAC /* sdl.pas in Sources */ = {isa = PBXBuildFile; fileRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */; };
- 2CDD4BE20CB947BE00549FAC /* UltraStarDX.pas in Sources */ = {isa = PBXBuildFile; fileRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; };
- 2CDEA4F70CBD725B0096994C /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CDEA4F60CBD725B0096994C /* OpenGL.framework */; };
- 2CDEC4960CC5264600FFA244 /* SDL.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98B8BE570B1F972400162019 /* SDL.framework */; };
- 2CE603DA0D715F2100DB0D88 /* mathematics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603D90D715F2100DB0D88 /* mathematics.pas */; };
- 2CE603DB0D715F2100DB0D88 /* mathematics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603D90D715F2100DB0D88 /* mathematics.pas */; };
- 2CE603DE0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; };
- 2CE603DF0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; };
- 2CE603E20D715F8600DB0D88 /* UConfig.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603E10D715F8600DB0D88 /* UConfig.pas */; };
- 2CE603E30D715F8600DB0D88 /* UConfig.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603E10D715F8600DB0D88 /* UConfig.pas */; };
- 2CE907930D1BC8A800A1FDFF /* libavcodec.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */; };
- 2CE907940D1BC8A800A1FDFF /* libavformat.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */; };
- 2CE907950D1BC8A800A1FDFF /* libavutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */; };
- 2CE907980D1BC90A00A1FDFF /* libavcodec.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */; };
- 2CE907990D1BC91D00A1FDFF /* libavformat.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */; };
- 2CE9079A0D1BC91D00A1FDFF /* libavutil.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */; };
- 2CEA2AE00CE385190097A5FF /* Graphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADE0CE385190097A5FF /* Graphics.pas */; };
- 2CEA2AE10CE385190097A5FF /* JPEG.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADF0CE385190097A5FF /* JPEG.pas */; };
- 2CEA2AE20CE385190097A5FF /* Graphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADE0CE385190097A5FF /* Graphics.pas */; };
- 2CEA2AE30CE385190097A5FF /* JPEG.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADF0CE385190097A5FF /* JPEG.pas */; };
- 2CEA2AF10CE3868E0097A5FF /* PseudoThread.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */; };
- 2CEA2AF20CE3868E0097A5FF /* PseudoThread.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */; };
- 2CF3EF220CDE13A0004F5956 /* Messages.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF210CDE13A0004F5956 /* Messages.pas */; };
- 2CF3EF230CDE13A0004F5956 /* Messages.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF210CDE13A0004F5956 /* Messages.pas */; };
- 2CF3EF270CDE13BA004F5956 /* MacResources.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF260CDE13BA004F5956 /* MacResources.pas */; };
- 2CF3EF280CDE13BA004F5956 /* MacResources.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF260CDE13BA004F5956 /* MacResources.pas */; };
- 2CF54F650CDA1B2B00627463 /* UScreenCredits.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */; };
- 2CF54F660CDA1B2B00627463 /* UScreenEdit.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */; };
- 2CF54F670CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */; };
- 2CF54F680CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */; };
- 2CF54F690CDA1B2B00627463 /* UScreenEditSub.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */; };
- 2CF54F6A0CDA1B2B00627463 /* UScreenLevel.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */; };
- 2CF54F6B0CDA1B2B00627463 /* UScreenLoading.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */; };
- 2CF54F6C0CDA1B2B00627463 /* UScreenMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; };
- 2CF54F6D0CDA1B2B00627463 /* UScreenName.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */; };
- 2CF54F6E0CDA1B2B00627463 /* UScreenOpen.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */; };
- 2CF54F6F0CDA1B2B00627463 /* UScreenOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */; };
- 2CF54F700CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */; };
- 2CF54F710CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */; };
- 2CF54F720CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */; };
- 2CF54F730CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */; };
- 2CF54F740CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */; };
- 2CF54F750CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */; };
- 2CF54F760CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */; };
- 2CF54F770CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */; };
- 2CF54F780CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */; };
- 2CF54F790CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */; };
- 2CF54F7A0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */; };
- 2CF54F7B0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */; };
- 2CF54F7C0CDA1B2B00627463 /* UScreenPopup.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */; };
- 2CF54F7D0CDA1B2B00627463 /* UScreenScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */; };
- 2CF54F7E0CDA1B2B00627463 /* UScreenSing.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */; };
- 2CF54F7F0CDA1B2B00627463 /* UScreenSingModi.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */; };
- 2CF54F800CDA1B2B00627463 /* UScreenSong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */; };
- 2CF54F810CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */; };
- 2CF54F820CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */; };
- 2CF54F830CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */; };
- 2CF54F840CDA1B2B00627463 /* UScreenStatMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */; };
- 2CF54F850CDA1B2B00627463 /* UScreenTop5.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */; };
- 2CF54F860CDA1B2B00627463 /* UScreenWelcome.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */; };
- 2CF54F870CDA1B2B00627463 /* UScreenCredits.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */; };
- 2CF54F880CDA1B2B00627463 /* UScreenEdit.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */; };
- 2CF54F890CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */; };
- 2CF54F8A0CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */; };
- 2CF54F8B0CDA1B2B00627463 /* UScreenEditSub.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */; };
- 2CF54F8C0CDA1B2B00627463 /* UScreenLevel.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */; };
- 2CF54F8D0CDA1B2B00627463 /* UScreenLoading.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */; };
- 2CF54F8E0CDA1B2B00627463 /* UScreenMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; };
- 2CF54F8F0CDA1B2B00627463 /* UScreenName.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */; };
- 2CF54F900CDA1B2B00627463 /* UScreenOpen.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */; };
- 2CF54F910CDA1B2B00627463 /* UScreenOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */; };
- 2CF54F920CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */; };
- 2CF54F930CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */; };
- 2CF54F940CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */; };
- 2CF54F950CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */; };
- 2CF54F960CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */; };
- 2CF54F970CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */; };
- 2CF54F980CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */; };
- 2CF54F990CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */; };
- 2CF54F9A0CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */; };
- 2CF54F9B0CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */; };
- 2CF54F9C0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */; };
- 2CF54F9D0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */; };
- 2CF54F9E0CDA1B2B00627463 /* UScreenPopup.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */; };
- 2CF54F9F0CDA1B2B00627463 /* UScreenScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */; };
- 2CF54FA00CDA1B2B00627463 /* UScreenSing.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */; };
- 2CF54FA10CDA1B2B00627463 /* UScreenSingModi.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */; };
- 2CF54FA20CDA1B2B00627463 /* UScreenSong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */; };
- 2CF54FA30CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */; };
- 2CF54FA40CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */; };
- 2CF54FA50CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */; };
- 2CF54FA60CDA1B2B00627463 /* UScreenStatMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */; };
- 2CF54FA70CDA1B2B00627463 /* UScreenTop5.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */; };
- 2CF54FA80CDA1B2B00627463 /* UScreenWelcome.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */; };
- 2CF5508C0CDA22B000627463 /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
- 2CF5508D0CDA22B000627463 /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
- 2CF551100CDA293700627463 /* SQLite3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510E0CDA293700627463 /* SQLite3.pas */; };
- 2CF551110CDA293700627463 /* SQLiteTable3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */; };
- 2CF551120CDA293700627463 /* SQLite3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510E0CDA293700627463 /* SQLite3.pas */; };
- 2CF551130CDA293700627463 /* SQLiteTable3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */; };
- 2CF5512D0CDA29C600627463 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */; };
- 2CF552140CDA3D1400627463 /* UPluginDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552110CDA3D1400627463 /* UPluginDefs.pas */; };
- 2CF552170CDA3D1400627463 /* UPluginDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552110CDA3D1400627463 /* UPluginDefs.pas */; };
- 2CF552A70CDA42C900627463 /* avcodec.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529E0CDA42C900627463 /* avcodec.pas */; };
- 2CF552A80CDA42C900627463 /* avformat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529F0CDA42C900627463 /* avformat.pas */; };
- 2CF552A90CDA42C900627463 /* avio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A00CDA42C900627463 /* avio.pas */; };
- 2CF552AA0CDA42C900627463 /* avutil.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A10CDA42C900627463 /* avutil.pas */; };
- 2CF552AD0CDA42C900627463 /* opt.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A40CDA42C900627463 /* opt.pas */; };
- 2CF552AE0CDA42C900627463 /* rational.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A50CDA42C900627463 /* rational.pas */; };
- 2CF552B00CDA42C900627463 /* avcodec.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529E0CDA42C900627463 /* avcodec.pas */; };
- 2CF552B10CDA42C900627463 /* avformat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529F0CDA42C900627463 /* avformat.pas */; };
- 2CF552B20CDA42C900627463 /* avio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A00CDA42C900627463 /* avio.pas */; };
- 2CF552B30CDA42C900627463 /* avutil.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A10CDA42C900627463 /* avutil.pas */; };
- 2CF552B60CDA42C900627463 /* opt.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A40CDA42C900627463 /* opt.pas */; };
- 2CF552B70CDA42C900627463 /* rational.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A50CDA42C900627463 /* rational.pas */; };
- 2CF553080CDA51B500627463 /* sdlutils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF553070CDA51B500627463 /* sdlutils.pas */; };
- 2CF553090CDA51B500627463 /* sdlutils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF553070CDA51B500627463 /* sdlutils.pas */; };
- 2CF553100CDA52D100627463 /* SDL_image.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */; };
- 2CF5533B0CDA52E200627463 /* SDL_ttf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */; };
- 2CF5533F0CDA531100627463 /* libfreeimage.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */; };
- 2CF553400CDA531100627463 /* libsqlite3.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */; };
- 2CF8E6BE0CDFA8E80053A996 /* UPartyDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */; };
- 2CF8E6BF0CDFA8E80053A996 /* UPartyDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */; };
- 98B8BE340B1F947800162019 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE330B1F947800162019 /* AppKit.framework */; };
- 98B8BE390B1F949C00162019 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE370B1F949C00162019 /* Cocoa.framework */; };
- 98B8BE3A0B1F949C00162019 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE380B1F949C00162019 /* Foundation.framework */; };
- 98B8BE580B1F972400162019 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE570B1F972400162019 /* SDL.framework */; };
- DD37F23D0A60252800975B2D /* UltraStarDX.pas in Sources */ = {isa = PBXBuildFile; fileRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; };
- DD37F2C70A6037EA00975B2D /* libfpcrtl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD37F2430A60255800975B2D /* libfpcrtl.a */; };
- DDC689B509F57C69004E4BFF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDC689B309F57C69004E4BFF /* InfoPlist.strings */; };
- DDC689B609F57C69004E4BFF /* SDLMain.nib in Resources */ = {isa = PBXBuildFile; fileRef = DDC689B409F57C69004E4BFF /* SDLMain.nib */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXBuildRule section */
- DD7C44CD0A6E5050003FA52B /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.proxy.script;
- filePatterns = "*.inc";
- fileType = pattern.proxy;
- isEditable = 1;
- outputFiles = (
- "$(TARGET_TEMP_DIR)/$(INPUT_FILE_NAME).compiled",
- );
- script = "echo \\\"-Fi$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\ntouch \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled\n";
- };
- DD7C45710A6E7E36003FA52B /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.proxy.script;
- filePatterns = "*.inc";
- fileType = pattern.proxy;
- isEditable = 1;
- outputFiles = (
- );
- script = "";
- };
- DDC688F309F57599004E4BFF /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.proxy.script;
- fileType = sourcecode.pascal;
- isEditable = 1;
- outputFiles = (
- "$(TARGET_TEMP_DIR)/$(INPUT_FILE_NAME).compiled",
- );
- script = "# set -vx\n\n# if FPC_MAIN_FILE is specified, only use that one\nif test \"x$FPC_MAIN_FILE\" = x ; then\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" >> \"$PROJECT_TEMP_DIR\"/files_to_compile\nelif test \"x$INPUT_FILE_NAME\" = \"x$FPC_MAIN_FILE\" || test \"x$INPUT_FILE_PATH\" = \"x$FPC_MAIN_FILE\" ; then\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/files_to_compile\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/mainfile\nfi\n\necho \\\"-Fu$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\necho \\\"-Fi$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\n\n# if this file was not yet before compiled, it may be a new file -> delete\n# source cache (there might be a new mainfile now, unless FPC_MAIN_FILE is specified)\nif test ! -f \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled && test \"x$FPC_MAIN_FILE\" = x ; then\n cd \"$PROJECT_TEMP_DIR\"\n rm -f mainfile scriptrun > /dev/null 2>&1\nfi\n\ntouch \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled\n";
- };
- DDC6891509F57648004E4BFF /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.proxy.script;
- fileType = sourcecode.pascal;
- isEditable = 1;
- outputFiles = (
- "$(PROJECT_DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).s",
- );
- script = "";
- };
-/* End PBXBuildRule section */
-
-/* Begin PBXContainerItemProxy section */
- DD37F25D0A60268D00975B2D /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = DDC6850F09F5717A004E4BFF /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DD37F2420A60255800975B2D;
- remoteInfo = fpcrtl;
- };
- DDC688ED09F57578004E4BFF /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = DDC6850F09F5717A004E4BFF /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DDC688D409F57523004E4BFF;
- remoteInfo = "Put unit sources in the 'Compile Sources' phase of this target";
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 2CDEC44F0CC5255600FFA244 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 6;
- files = (
- 2CAC2BF40D380AE800CA518A /* libbass.dylib in CopyFiles */,
- 2CE907990D1BC91D00A1FDFF /* libavformat.dylib in CopyFiles */,
- 2CE9079A0D1BC91D00A1FDFF /* libavutil.dylib in CopyFiles */,
- 2CE907980D1BC90A00A1FDFF /* libavcodec.dylib in CopyFiles */,
- 2CF5533F0CDA531100627463 /* libfreeimage.dylib in CopyFiles */,
- 2CF553400CDA531100627463 /* libsqlite3.dylib in CopyFiles */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 2CDEC4940CC5262700FFA244 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- 2CDEC4960CC5264600FFA244 /* SDL.framework in CopyFiles */,
- 2CF553100CDA52D100627463 /* SDL_image.framework in CopyFiles */,
- 2CF5533B0CDA52E200627463 /* SDL_ttf.framework in CopyFiles */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* 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; };
- 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCommandLine.pas; path = ../Classes/UCommandLine.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C670CC9EC8C0031092D /* UCommon.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCommon.pas; path = ../Classes/UCommon.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C680CC9EC8C0031092D /* UCore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCore.pas; path = ../Classes/UCore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCoreModule.pas; path = ../Classes/UCoreModule.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCovers.pas; path = ../Classes/UCovers.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDataBase.pas; path = ../Classes/UDataBase.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDLLManager.pas; path = ../Classes/UDLLManager.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDraw.pas; path = ../Classes/UDraw.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UFiles.pas; path = ../Classes/UFiles.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UGraphic.pas; path = ../Classes/UGraphic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UGraphicClasses.pas; path = ../Classes/UGraphicClasses.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C710CC9EC8C0031092D /* UHooks.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UHooks.pas; path = ../Classes/UHooks.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C720CC9EC8C0031092D /* UIni.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UIni.pas; path = ../Classes/UIni.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */ = {isa = PBXFileReference; explicitFileType = sourcecode.pascal; fileEncoding = 5; indentWidth = 2; name = UJoystick.pas; path = ../Classes/UJoystick.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULanguage.pas; path = ../Classes/ULanguage.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C760CC9EC8C0031092D /* ULCD.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULCD.pas; path = ../Classes/ULCD.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C770CC9EC8C0031092D /* ULight.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULight.pas; path = ../Classes/ULight.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C780CC9EC8C0031092D /* ULog.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULog.pas; path = ../Classes/ULog.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULyrics_bak.pas; path = ../Classes/ULyrics_bak.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULyrics.pas; path = ../Classes/ULyrics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMain.pas; path = ../Classes/UMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMedia_dummy.pas; path = ../Classes/UMedia_dummy.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UModules.pas; path = ../Classes/UModules.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMusic.pas; path = ../Classes/UMusic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UParty.pas; path = ../Classes/UParty.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPlaylist.pas; path = ../Classes/UPlaylist.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPluginInterface.pas; path = ../Classes/UPluginInterface.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = uPluginLoader.pas; path = ../Classes/uPluginLoader.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C840CC9EC8C0031092D /* URecord.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = URecord.pas; path = ../Classes/URecord.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C850CC9EC8C0031092D /* UServices.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UServices.pas; path = ../Classes/UServices.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USingNotes.pas; path = ../Classes/USingNotes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C870CC9EC8C0031092D /* USingScores.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USingScores.pas; path = ../Classes/USingScores.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C880CC9EC8C0031092D /* USkins.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USkins.pas; path = ../Classes/USkins.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C890CC9EC8C0031092D /* USongs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USongs.pas; path = ../Classes/USongs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTextClasses.pas; path = ../Classes/UTextClasses.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTexture.pas; path = ../Classes/UTexture.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UThemes.pas; path = ../Classes/UThemes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTime.pas; path = ../Classes/UTime.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UVideo.pas; path = ../Classes/UVideo.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = FreeBitmap.pas; path = ../lib/FreeImage/FreeBitmap.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = FreeImage.pas; path = ../lib/FreeImage/FreeImage.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreeimage.dylib; path = ../lib/FreeImage/libfreeimage.dylib; sourceTree = SOURCE_ROOT; };
- 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_image.framework; path = /Library/Frameworks/SDL_image.framework; sourceTree = ""; };
- 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = ""; };
- 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDisplay.pas; path = ../Menu/UDisplay.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDrawTexture.pas; path = ../Menu/UDrawTexture.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenu.pas; path = ../Menu/UMenu.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuButton.pas; path = ../Menu/UMenuButton.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuButtonCollection.pas; path = ../Menu/UMenuButtonCollection.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuInteract.pas; path = ../Menu/UMenuInteract.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuSelect.pas; path = ../Menu/UMenuSelect.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuSelectSlide.pas; path = ../Menu/UMenuSelectSlide.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuStatic.pas; path = ../Menu/UMenuStatic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuText.pas; path = ../Menu/UMenuText.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl_image.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL_image/sdl_image.pas"; sourceTree = ""; tabWidth = 2; };
- 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl_ttf.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL_ttf/sdl_ttf.pas"; sourceTree = ""; tabWidth = 2; };
- 2C4D9E040CC9EF840031092D /* OpenGL12.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = OpenGL12.pas; path = Wrapper/OpenGL12.pas; sourceTree = ""; tabWidth = 2; };
- 2C4D9E090CC9EF840031092D /* Windows.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = Windows.pas; path = Wrapper/Windows.pas; sourceTree = ""; tabWidth = 2; };
- 2C4D9E440CC9F0ED0031092D /* switches.inc */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = switches.inc; path = ../switches.inc; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = "ustar-icon_v01.icns"; path = "../../Graphics/ustar-icon_v01.icns"; sourceTree = SOURCE_ROOT; };
- 2C5663EE0D35645700D4FF53 /* portaudio.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = portaudio.pas; path = ../lib/portaudio/delphi/portaudio.pas; sourceTree = SOURCE_ROOT; };
- 2C56642B0D35683200D4FF53 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = SDLMain.m; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/SDLMain.m"; sourceTree = ""; };
- 2C56642F0D35688200D4FF53 /* SDL.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = SDL.h; path = /Library/Frameworks/SDL.framework/Versions/A/Headers/SDL.h; sourceTree = ""; };
- 2C8937290CE393FB005D8A87 /* UPlatform.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UPlatform.pas; path = ../Classes/UPlatform.pas; sourceTree = SOURCE_ROOT; };
- 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; lineEnding = 0; name = UPlatformMacOSX.pas; path = ../Classes/UPlatformMacOSX.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UAudioInput_Bass.pas; path = ../Classes/UAudioInput_Bass.pas; sourceTree = SOURCE_ROOT; };
- 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UAudioPlayback_Bass.pas; path = ../Classes/UAudioPlayback_Bass.pas; sourceTree = SOURCE_ROOT; };
- 2CAC2BF00D380AC200CA518A /* libbass.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbass.dylib; path = ../lib/bass/libbass.dylib; sourceTree = SOURCE_ROOT; };
- 2CAC2BF70D380B1B00CA518A /* Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = Bass.pas; path = ../lib/bass/MacOSX/Bass.pas; sourceTree = SOURCE_ROOT; };
- 2CB9E87D0D43B78400214DFA /* USong.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = USong.pas; path = ../Classes/USong.pas; sourceTree = SOURCE_ROOT; };
- 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = StrUtils.pas; path = ../../../Modis/SDK/StrUtils.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CDEA4F60CBD725B0096994C /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; };
- 2CE603D90D715F2100DB0D88 /* mathematics.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = mathematics.pas; path = ../lib/ffmpeg/mathematics.pas; sourceTree = SOURCE_ROOT; };
- 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = UAudioCore_Bass.pas; path = ../Classes/UAudioCore_Bass.pas; sourceTree = SOURCE_ROOT; };
- 2CE603E10D715F8600DB0D88 /* UConfig.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = UConfig.pas; path = ../Classes/UConfig.pas; sourceTree = SOURCE_ROOT; };
- 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.dylib; path = ../lib/ffmpeg/libavcodec.dylib; sourceTree = SOURCE_ROOT; };
- 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavformat.dylib; path = ../lib/ffmpeg/libavformat.dylib; sourceTree = SOURCE_ROOT; };
- 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavutil.dylib; path = ../lib/ffmpeg/libavutil.dylib; sourceTree = SOURCE_ROOT; };
- 2CEA2ADE0CE385190097A5FF /* Graphics.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = Graphics.pas; path = Wrapper/Graphics.pas; sourceTree = ""; };
- 2CEA2ADF0CE385190097A5FF /* JPEG.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = JPEG.pas; path = Wrapper/JPEG.pas; sourceTree = ""; };
- 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = PseudoThread.pas; path = Wrapper/PseudoThread.pas; sourceTree = ""; };
- 2CF3EF210CDE13A0004F5956 /* Messages.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = Messages.pas; path = Wrapper/Messages.pas; sourceTree = ""; tabWidth = 2; };
- 2CF3EF260CDE13BA004F5956 /* MacResources.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = MacResources.pas; path = Wrapper/MacResources.pas; sourceTree = ""; tabWidth = 2; };
- 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenCredits.pas; path = ../Screens/UScreenCredits.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEdit.pas; path = ../Screens/UScreenEdit.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditConvert.pas; path = ../Screens/UScreenEditConvert.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditHeader.pas; path = ../Screens/UScreenEditHeader.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditSub.pas; path = ../Screens/UScreenEditSub.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenLevel.pas; path = ../Screens/UScreenLevel.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenLoading.pas; path = ../Screens/UScreenLoading.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenMain.pas; path = ../Screens/UScreenMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenName.pas; path = ../Screens/UScreenName.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOpen.pas; path = ../Screens/UScreenOpen.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptions.pas; path = ../Screens/UScreenOptions.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsAdvanced.pas; path = ../Screens/UScreenOptionsAdvanced.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsGame.pas; path = ../Screens/UScreenOptionsGame.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsGraphics.pas; path = ../Screens/UScreenOptionsGraphics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsLyrics.pas; path = ../Screens/UScreenOptionsLyrics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsRecord.pas; path = ../Screens/UScreenOptionsRecord.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsSound.pas; path = ../Screens/UScreenOptionsSound.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsThemes.pas; path = ../Screens/UScreenOptionsThemes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyNewRound.pas; path = ../Screens/UScreenPartyNewRound.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyOptions.pas; path = ../Screens/UScreenPartyOptions.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyPlayer.pas; path = ../Screens/UScreenPartyPlayer.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyScore.pas; path = ../Screens/UScreenPartyScore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyWin.pas; path = ../Screens/UScreenPartyWin.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPopup.pas; path = ../Screens/UScreenPopup.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenScore.pas; path = ../Screens/UScreenScore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSing.pas; path = ../Screens/UScreenSing.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSingModi.pas; path = ../Screens/UScreenSingModi.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSong.pas; path = ../Screens/UScreenSong.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSongJumpto.pas; path = ../Screens/UScreenSongJumpto.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSongMenu.pas; path = ../Screens/UScreenSongMenu.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenStatDetail.pas; path = ../Screens/UScreenStatDetail.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenStatMain.pas; path = ../Screens/UScreenStatMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenTop5.pas; path = ../Screens/UScreenTop5.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenWelcome.pas; path = ../Screens/UScreenWelcome.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5508B0CDA22B000627463 /* ModiSDK.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ModiSDK.pas; path = ../../../Modis/SDK/ModiSDK.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5510E0CDA293700627463 /* SQLite3.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = SQLite3.pas; path = ../lib/SQLite/SQLite3.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = SQLiteTable3.pas; path = ../lib/SQLite/SQLiteTable3.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = ../lib/SQLite/libsqlite3.dylib; sourceTree = SOURCE_ROOT; };
- 2CF551A70CDA356800627463 /* UltraStar.dpr */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = text; name = UltraStar.dpr; path = ../UltraStar.dpr; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF552110CDA3D1400627463 /* UPluginDefs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPluginDefs.pas; path = ../../../Modis/SDK/UPluginDefs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5529E0CDA42C900627463 /* avcodec.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avcodec.pas; path = ../lib/ffmpeg/avcodec.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF5529F0CDA42C900627463 /* avformat.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avformat.pas; path = ../lib/ffmpeg/avformat.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF552A00CDA42C900627463 /* avio.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avio.pas; path = ../lib/ffmpeg/avio.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF552A10CDA42C900627463 /* avutil.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avutil.pas; path = ../lib/ffmpeg/avutil.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF552A40CDA42C900627463 /* opt.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = opt.pas; path = ../lib/ffmpeg/opt.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF552A50CDA42C900627463 /* rational.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = rational.pas; path = ../lib/ffmpeg/rational.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 2CF553070CDA51B500627463 /* sdlutils.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdlutils.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/sdlutils.pas"; sourceTree = ""; tabWidth = 2; };
- 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libLib_UltraPong.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
- 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPartyDefs.pas; path = ../../../Modis/SDK/UPartyDefs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
- 98B8BE330B1F947800162019 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = ""; };
- 98B8BE370B1F949C00162019 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = ""; };
- 98B8BE380B1F949C00162019 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = ""; };
- 98B8BE570B1F972400162019 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; };
- 98B8BE5C0B1F974F00162019 /* sdl.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/sdl.pas"; sourceTree = ""; tabWidth = 2; };
- DD37F2430A60255800975B2D /* libfpcrtl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfpcrtl.a; sourceTree = BUILT_PRODUCTS_DIR; };
- DDC6851B09F57195004E4BFF /* UltraStarDX.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; path = UltraStarDX.pas; sourceTree = ""; tabWidth = 2; };
- DDC6868B09F571C2004E4BFF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; };
- DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UltraStar Deluxe.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- DDC688CA09F574E9004E4BFF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; };
- DDC689B309F57C69004E4BFF /* InfoPlist.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = InfoPlist.strings; path = English.lproj/InfoPlist.strings; sourceTree = ""; };
- DDC689B409F57C69004E4BFF /* SDLMain.nib */ = {isa = PBXFileReference; explicitFileType = wrapper.nib; name = SDLMain.nib; path = English.lproj/SDLMain.nib; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 2CF77DB40CF7556C00F3B101 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC688C609F574E9004E4BFF /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DD37F2C70A6037EA00975B2D /* libfpcrtl.a in Frameworks */,
- 98B8BE340B1F947800162019 /* AppKit.framework in Frameworks */,
- 98B8BE390B1F949C00162019 /* Cocoa.framework in Frameworks */,
- 98B8BE3A0B1F949C00162019 /* Foundation.framework in Frameworks */,
- 98B8BE580B1F972400162019 /* SDL.framework in Frameworks */,
- 2CDEA4F70CBD725B0096994C /* OpenGL.framework in Frameworks */,
- 2C4D9D970CC9EDEB0031092D /* libfreeimage.dylib in Frameworks */,
- 2C4D9D9A0CC9EE0B0031092D /* SDL_image.framework in Frameworks */,
- 2C4D9D9B0CC9EE0B0031092D /* SDL_ttf.framework in Frameworks */,
- 2CF5512D0CDA29C600627463 /* libsqlite3.dylib in Frameworks */,
- 2CE907930D1BC8A800A1FDFF /* libavcodec.dylib in Frameworks */,
- 2CE907940D1BC8A800A1FDFF /* libavformat.dylib in Frameworks */,
- 2CE907950D1BC8A800A1FDFF /* libavutil.dylib in Frameworks */,
- 2CAC2BF10D380AC200CA518A /* libbass.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 2C4D9DEB0CC9EECC0031092D /* SDL */ = {
- isa = PBXGroup;
- children = (
- 2C56642F0D35688200D4FF53 /* SDL.h */,
- 2C56642B0D35683200D4FF53 /* SDLMain.m */,
- 2CF553070CDA51B500627463 /* sdlutils.pas */,
- 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */,
- 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */,
- 98B8BE5C0B1F974F00162019 /* sdl.pas */,
- );
- name = SDL;
- sourceTree = "";
- };
- 2C4D9DF50CC9EF3A0031092D /* Wrapper */ = {
- isa = PBXGroup;
- children = (
- 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */,
- 2CEA2ADE0CE385190097A5FF /* Graphics.pas */,
- 2CEA2ADF0CE385190097A5FF /* JPEG.pas */,
- 2CF3EF260CDE13BA004F5956 /* MacResources.pas */,
- 2CF3EF210CDE13A0004F5956 /* Messages.pas */,
- 2C4D9E040CC9EF840031092D /* OpenGL12.pas */,
- 2C4D9E090CC9EF840031092D /* Windows.pas */,
- );
- name = Wrapper;
- sourceTree = "";
- };
- 2C5663EC0D35642E00D4FF53 /* portaudio */ = {
- isa = PBXGroup;
- children = (
- 2C5663EE0D35645700D4FF53 /* portaudio.pas */,
- );
- name = portaudio;
- sourceTree = "";
- };
- 2CAC2BF60D380B0800CA518A /* BASS */ = {
- isa = PBXGroup;
- children = (
- 2CAC2BF70D380B1B00CA518A /* Bass.pas */,
- );
- name = BASS;
- sourceTree = "";
- };
- 2CDD43820CBBE8D400F364DE /* Classes */ = {
- isa = PBXGroup;
- children = (
- 2CE603E10D715F8600DB0D88 /* UConfig.pas */,
- 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */,
- 2CB9E87D0D43B78400214DFA /* USong.pas */,
- 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */,
- 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */,
- 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */,
- 2C8937290CE393FB005D8A87 /* UPlatform.pas */,
- 2C4D9C620CC9EC8C0031092D /* TextGL.pas */,
- 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */,
- 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */,
- 2C4D9C670CC9EC8C0031092D /* UCommon.pas */,
- 2C4D9C680CC9EC8C0031092D /* UCore.pas */,
- 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */,
- 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */,
- 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */,
- 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */,
- 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */,
- 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */,
- 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */,
- 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */,
- 2C4D9C710CC9EC8C0031092D /* UHooks.pas */,
- 2C4D9C720CC9EC8C0031092D /* UIni.pas */,
- 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */,
- 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */,
- 2C4D9C760CC9EC8C0031092D /* ULCD.pas */,
- 2C4D9C770CC9EC8C0031092D /* ULight.pas */,
- 2C4D9C780CC9EC8C0031092D /* ULog.pas */,
- 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */,
- 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */,
- 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */,
- 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */,
- 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */,
- 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */,
- 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */,
- 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */,
- 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */,
- 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */,
- 2C4D9C840CC9EC8C0031092D /* URecord.pas */,
- 2C4D9C850CC9EC8C0031092D /* UServices.pas */,
- 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */,
- 2C4D9C870CC9EC8C0031092D /* USingScores.pas */,
- 2C4D9C880CC9EC8C0031092D /* USkins.pas */,
- 2C4D9C890CC9EC8C0031092D /* USongs.pas */,
- 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */,
- 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */,
- 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */,
- 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */,
- 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */,
- );
- name = Classes;
- sourceTree = "";
- };
- 2CDD438D0CBBE8F700F364DE /* Menu */ = {
- isa = PBXGroup;
- children = (
- 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */,
- 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */,
- 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */,
- 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */,
- 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */,
- 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */,
- 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */,
- 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */,
- 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */,
- 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */,
- );
- name = Menu;
- sourceTree = "";
- };
- 2CDD8D0B0CC5539900E4169D /* UltraStarDX Resources */ = {
- isa = PBXGroup;
- children = (
- );
- name = "UltraStarDX Resources";
- sourceTree = "";
- };
- 2CE1F4080CC3EEA400CD02E5 /* FreeImage */ = {
- isa = PBXGroup;
- children = (
- 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */,
- 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */,
- );
- name = FreeImage;
- sourceTree = "";
- };
- 2CF54F420CDA1B0C00627463 /* Screens */ = {
- isa = PBXGroup;
- children = (
- 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */,
- 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */,
- 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */,
- 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */,
- 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */,
- 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */,
- 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */,
- 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */,
- 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */,
- 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */,
- 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */,
- 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */,
- 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */,
- 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */,
- 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */,
- 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */,
- 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */,
- 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */,
- 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */,
- 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */,
- 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */,
- 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */,
- 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */,
- 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */,
- 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */,
- 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */,
- 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */,
- 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */,
- 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */,
- 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */,
- 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */,
- 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */,
- 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */,
- 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */,
- );
- name = Screens;
- sourceTree = "";
- };
- 2CF5508A0CDA228800627463 /* SDK */ = {
- isa = PBXGroup;
- children = (
- 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */,
- 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */,
- 2CF552110CDA3D1400627463 /* UPluginDefs.pas */,
- 2CF5508B0CDA22B000627463 /* ModiSDK.pas */,
- );
- name = SDK;
- sourceTree = "";
- };
- 2CF5510C0CDA28F000627463 /* Lib */ = {
- isa = PBXGroup;
- children = (
- 2CAC2BF60D380B0800CA518A /* BASS */,
- 2C5663EC0D35642E00D4FF53 /* portaudio */,
- 2CF5529C0CDA428000627463 /* ffmpeg */,
- 2CE1F4080CC3EEA400CD02E5 /* FreeImage */,
- 2C4D9DEB0CC9EECC0031092D /* SDL */,
- 2CF5510D0CDA291200627463 /* SQLite */,
- );
- name = Lib;
- sourceTree = "";
- };
- 2CF5510D0CDA291200627463 /* SQLite */ = {
- isa = PBXGroup;
- children = (
- 2CF5510E0CDA293700627463 /* SQLite3.pas */,
- 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */,
- );
- name = SQLite;
- sourceTree = "";
- };
- 2CF5529C0CDA428000627463 /* ffmpeg */ = {
- isa = PBXGroup;
- children = (
- 2CE603D90D715F2100DB0D88 /* mathematics.pas */,
- 2CF5529E0CDA42C900627463 /* avcodec.pas */,
- 2CF5529F0CDA42C900627463 /* avformat.pas */,
- 2CF552A00CDA42C900627463 /* avio.pas */,
- 2CF552A10CDA42C900627463 /* avutil.pas */,
- 2CF552A40CDA42C900627463 /* opt.pas */,
- 2CF552A50CDA42C900627463 /* rational.pas */,
- );
- name = ffmpeg;
- sourceTree = "";
- };
- 2CF77DBA0CF755CA00F3B101 /* Modis */ = {
- isa = PBXGroup;
- children = (
- 2C4B70220CF757A400B0F0BD /* Until5000.dpr */,
- );
- name = Modis;
- sourceTree = "";
- };
- DD7C45450A6E72DE003FA52B /* Source */ = {
- isa = PBXGroup;
- children = (
- 2CF5510C0CDA28F000627463 /* Lib */,
- 2CDD43820CBBE8D400F364DE /* Classes */,
- 2CF54F420CDA1B0C00627463 /* Screens */,
- 2CDD438D0CBBE8F700F364DE /* Menu */,
- 2CF5508A0CDA228800627463 /* SDK */,
- 2C4D9DF50CC9EF3A0031092D /* Wrapper */,
- 2CF77DBA0CF755CA00F3B101 /* Modis */,
- DDC6851B09F57195004E4BFF /* UltraStarDX.pas */,
- 2CF551A70CDA356800627463 /* UltraStar.dpr */,
- 2C4D9E440CC9F0ED0031092D /* switches.inc */,
- 2C0199800D99840900974970 /* config-macosx.inc */,
- );
- name = Source;
- sourceTree = "";
- };
- DDC6850D09F5717A004E4BFF = {
- isa = PBXGroup;
- children = (
- 2CAC2BF00D380AC200CA518A /* libbass.dylib */,
- 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */,
- 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */,
- 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */,
- 98B8BE570B1F972400162019 /* SDL.framework */,
- 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */,
- 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */,
- 2CDEA4F60CBD725B0096994C /* OpenGL.framework */,
- 98B8BE370B1F949C00162019 /* Cocoa.framework */,
- 98B8BE380B1F949C00162019 /* Foundation.framework */,
- 98B8BE330B1F947800162019 /* AppKit.framework */,
- 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */,
- 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */,
- DD7C45450A6E72DE003FA52B /* Source */,
- DDC6868A09F571C2004E4BFF /* Resources */,
- 2CDD8D0B0CC5539900E4169D /* UltraStarDX Resources */,
- DDC6888C09F57243004E4BFF /* Products */,
- DDC688CA09F574E9004E4BFF /* Info.plist */,
- );
- comments = "(note: \"Main target\" is used below to indicate the target with the same name as your project)\n\nSee the comments for the \"Main target\" under \"Targets\" for detailed information on how this project operates.\n\nIn short:\n\na) add your sources to the target called 'Put all program sources also in this target'\nb) add your sources *EXCEPT FOR INCLUDE FILES* to the Main Target\nd) add all frameworks, resources, libraries etc to the Main target\n\nIf there are errors, the \"Errors and Warnings\" smart group will probably not work properly (e.g. errors may disappear after you double click on them). To work around this Xcode bug, go to the Build Transcript by double clicking on the icon of the \"Errors and Warnings\" smart group. There you can (double) click on the errors to go to the right position in the right source file.\n\nNote that the assembly view of Xcode does not work before Xcode 2.3. And in Xcode 2.3, you will not be able to step over PowerPC Pascal function calls (this should be fixed in the next Xcode release though).";
- sourceTree = "";
- };
- DDC6868A09F571C2004E4BFF /* Resources */ = {
- isa = PBXGroup;
- children = (
- 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */,
- DDC689B309F57C69004E4BFF /* InfoPlist.strings */,
- DDC689B409F57C69004E4BFF /* SDLMain.nib */,
- DDC6868B09F571C2004E4BFF /* Info.plist */,
- );
- name = Resources;
- sourceTree = "";
- };
- DDC6888C09F57243004E4BFF /* Products */ = {
- isa = PBXGroup;
- children = (
- DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */,
- DD37F2430A60255800975B2D /* libfpcrtl.a */,
- 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */,
- );
- name = Products;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
- 2CF77DB20CF7556C00F3B101 /* Headers */ = {
- isa = PBXHeadersBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
- 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 2CF77DB90CF7558B00F3B101 /* Build configuration list for PBXNativeTarget "Modi_Until5000" */;
- buildPhases = (
- 2CF77DB20CF7556C00F3B101 /* Headers */,
- 2CF77DB30CF7556C00F3B101 /* Sources */,
- 2CF77DB40CF7556C00F3B101 /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = Modi_Until5000;
- productName = Lib_UltraPong;
- productReference = 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */;
- productType = "com.apple.product-type.library.dynamic";
- };
- DD37F2420A60255800975B2D /* fpcrtl */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DD37F2560A60258300975B2D /* Build configuration list for PBXNativeTarget "fpcrtl" */;
- buildPhases = (
- DD37F2460A60257100975B2D /* ShellScript */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = fpcrtl;
- productName = fpcrtl;
- productReference = DD37F2430A60255800975B2D /* libfpcrtl.a */;
- productType = "com.apple.product-type.library.static";
- };
- DDC688C709F574E9004E4BFF /* UltraStarDX */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DDC688CB09F574E9004E4BFF /* Build configuration list for PBXNativeTarget "UltraStarDX" */;
- buildPhases = (
- DDC688C409F574E9004E4BFF /* Resources */,
- 2CDEC44F0CC5255600FFA244 /* CopyFiles */,
- 2CDEC4940CC5262700FFA244 /* CopyFiles */,
- DDC6891B09F576D9004E4BFF /* ShellScript */,
- DDC688C509F574E9004E4BFF /* Sources */,
- DDC688C609F574E9004E4BFF /* Frameworks */,
- DDC6890909F5761D004E4BFF /* Rez */,
- 2CDD8E450CC554A000E4169D /* ShellScript */,
- );
- buildRules = (
- DD7C45710A6E7E36003FA52B /* PBXBuildRule */,
- DDC6891509F57648004E4BFF /* PBXBuildRule */,
- );
- comments = "This is the main target that does the actual compilation work. Because of several Xcode bugs and holes in its support for third party compilers, the structure is quite convoluted. There are three targets, but you only have to care about the first two:\n\na) This target (make sure this target is set as the \"Active Target\"!)\n\nThis target does the assembling and linking. It is dependent on the three other targets, so the scripts for those targets are run first. Next, it runs a script which compiles the main program and units (using the previously gathered information) and generate the assembler code. Then its \"Compile Sources\" phase will assemble the code, because if we directly generate the object files then Xcode will not perform any linking.\n\nb) The target called 'Put all program sources also in this target'\n\nAs the name says, you should add your sources to that target. The \"compilation rule\" for the Pascal files in that target will add those source files to a list of files to be compiled.\n\nc) The target called 'fpcrtl'\n\nThis target creates a static library of the FPC run time library. You should not have to change this target (you cannot add sources to it either)\n\n\nThe standard Xcode process is used to link in any necessary frameworks, libraries and resources. Therefore these frameworks, libraries and resources can be added to the project and this (the main) target like in any other Xcode project.\n";
- dependencies = (
- DDC688EE09F57578004E4BFF /* PBXTargetDependency */,
- DD37F25E0A60268D00975B2D /* PBXTargetDependency */,
- );
- name = UltraStarDX;
- productName = "JEDI-SDLCocoa";
- productReference = DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */;
- productType = "com.apple.product-type.application";
- };
- DDC688D409F57523004E4BFF /* Put all program sources also in this target */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DDC688DC09F57542004E4BFF /* Build configuration list for PBXNativeTarget "Put all program sources also in this target" */;
- buildPhases = (
- DD37F2350A60250900975B2D /* ShellScript */,
- DDC688D209F57523004E4BFF /* Sources */,
- );
- buildRules = (
- DD7C44CD0A6E5050003FA52B /* PBXBuildRule */,
- DDC688F309F57599004E4BFF /* PBXBuildRule */,
- );
- comments = "See the comments for the target called the same as your project for details.";
- dependencies = (
- );
- name = "Put all program sources also in this target";
- productName = "Put unit sources in the 'Compile Sources' phase of this target";
- productType = "com.apple.product-type.objfile";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- DDC6850F09F5717A004E4BFF /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = DDC6851009F5717A004E4BFF /* Build configuration list for PBXProject "UltraStarDX" */;
- compatibilityVersion = "Xcode 2.4";
- hasScannedForEncodings = 0;
- mainGroup = DDC6850D09F5717A004E4BFF;
- productRefGroup = DDC6888C09F57243004E4BFF /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- DDC688C709F574E9004E4BFF /* UltraStarDX */,
- DDC688D409F57523004E4BFF /* Put all program sources also in this target */,
- DD37F2420A60255800975B2D /* fpcrtl */,
- 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- DDC688C409F574E9004E4BFF /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DDC689B509F57C69004E4BFF /* InfoPlist.strings in Resources */,
- DDC689B609F57C69004E4BFF /* SDLMain.nib in Resources */,
- 2C4FA2A80CDBAD1E002CC3B0 /* ustar-icon_v01.icns in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXRezBuildPhase section */
- DDC6890909F5761D004E4BFF /* Rez */ = {
- isa = PBXRezBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXRezBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 2CDD8E450CC554A000E4169D /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\nUS_RESOURCES_SOURCE_DIR=UltraStarResources\nUS_RESOURCES_DEST_DIR=\"$CONFIGURATION_BUILD_DIR\"/\"$PRODUCT_NAME\".app/Contents\n\n#cp -Rf $US_RESOURCES_SOURCE_DIR $US_RESOURCES_DEST_DIR";
- };
- DD37F2350A60250900975B2D /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- "$(PROJECT_TEMP_DIR)/cleanscriptrun",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# hack to workaround Xcode bug that $PROJECT_TEMP_DIR isn't cleaned when you clean,\n# and that scripts aren't run when you clean a project\n\nmkdir -p \"$PROJECT_TEMP_DIR\"\n\n# when the \"scripts not run when cleaning\" bug is fixed, this doesn't have be run\n# when cleaning\n\nif [ x\"$ACTION\" = \"xbuild\" ]; then\n # remove unit path and source file cache\n cd \"$PROJECT_TEMP_DIR\"\n rm -f mainfile scriptrun unitpaths files_to_compile > /dev/null 2>&1\nfi\n\n# simple so that the script isn't run every time you compile\ntouch \"$PROJECT_TEMP_DIR\"/cleanscriptrun";
- };
- DD37F2460A60257100975B2D /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- "$(TARGET_BUILD_DIR)/libfpcrtl.a",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# if you activate this to see what the script does, Xcode will take a *VERY LONG* time to process the output of the \"ar\" command line\n# set -vx\n\n\n# put the entire RTL in one static library so we can link it easily (without automatically linking all object files)\n\nif [ x\"$ACTION\" = \"xbuild\" ]; then\n \n rm -f \"$PROJECT_TEMP_DIR\"/rtllibs\n for arch in $ARCHS\n do\n # get the correct compiler name\n case $arch in\n i386)\n FPC_ARCH=386\n RTL_ARCH=i386\n ;;\n ppc)\n FPC_ARCH=ppc\n RTL_ARCH=powerpc\n ;;\n * )\n echo warning: Unsupported target architecture ${arch}, skipping...\n continue\n ;;\n esac\n\n FPC_VERSION=`/usr/local/bin/ppc${FPC_ARCH} -iV`\n if [ $? != 0 ]; then\n echo \"error: Cannot find the FPC binary for $RTL_ARCH (/usr/local/bin/ppc${FPC_ARCH}). Check if you have installed FPC for this architecture.\"\n exit 1\n fi\n MY_OUTPUT_FILE=\"$PROJECT_TEMP_DIR\"/libfpcrtl-${FPC_ARCH}.a\n ar -ru \"$MY_OUTPUT_FILE\" `ls \"$FPC_RTL_UNITS_BASE\"/\"$FPC_VERSION\"/units/${RTL_ARCH}-darwin/*/*.o | grep -v 'darwin/fv/'`\n if [ $? != 0 ]; then\n echo \"error: Problem creating static library for FPC Run Time Library. Check the FPC_RTL_UNITS_BASE setting in the global project configuration.\"\n exit 1\n fi\n echo -n \" \"\\\"\"$MY_OUTPUT_FILE\"\\\" >> \"$PROJECT_TEMP_DIR\"/rtllibs\n done\n /bin/sh -c \"lipo -create `cat \\\"$PROJECT_TEMP_DIR\\\"/rtllibs` -output \\\"$TARGET_BUILD_DIR\\\"/libfpcrtl.a\"\n ranlib \"$TARGET_BUILD_DIR\"/libfpcrtl.a > /dev/null 2>&1\n # delete working files\n rm -f `cat \"$PROJECT_TEMP_DIR\"/rtllibs`\n rm -f \"$PROJECT_TEMP_DIR\"/rtllibs\nfi\n";
- };
- DDC6891B09F576D9004E4BFF /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(PROJECT_TEMP_DIR)/files_to_compile",
- );
- outputPaths = (
- "$(PROJECT_TEMP_DIR)/scriptrun",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# set -vx\n\nif [ x\"$ACTION\" = \"xclean\" ]; then\n exit 0\nfi\n\nfunction make_conditional() {\n for arch in $ARCHS\n do\n for file in \"$PROJECT_DERIVED_FILE_DIR\"/\"$arch\"/*.s\n do\n DEST_FILE=\"$PROJECT_DERIVED_FILE_DIR\"/`basename \"$file\"`\n echo \"#ifdef __${arch}__\" >> /\"$DEST_FILE\"\n cat \"$file\" >> \"$DEST_FILE\"\n echo \"#endif\" >> \"$DEST_FILE\"\n done\n done\n}\n\n\nUNIT_PATHS_FILE=\"$PROJECT_TEMP_DIR\"/unitpaths\n\n# remove duplicate unit search paths\nif test -f \"$UNIT_PATHS_FILE\"; then\n sort -u < \"$UNIT_PATHS_FILE\" > \"$UNIT_PATHS_FILE\".tmp\n mv \"$UNIT_PATHS_FILE\".tmp \"$UNIT_PATHS_FILE\"\nelse\n touch \"$UNIT_PATHS_FILE\"\nfi\n\n# Make sure there are some files to compile\nif test ! -f \"$PROJECT_TEMP_DIR\"/files_to_compile; then\n echo error: Add your main program and its units to the \\\"Put all program sources also in this target\\\" target\n exit 1\nfi\n\n\n# support for previous Xcode naming scheme\nif [ \"$BUILD_STYLE\" = Development ]\nthen\n BUILD_STYLE=Debug\nfi\n\nif [ \"$BUILD_STYLE\" = Deployment ]\nthen\n BUILD_STYLE=Release\nfi\n\n# keep track of whether we compiled the main program so that once we did, we can stop\nMAIN_PROGRAM_COMPILED=0\n\n# don't skip the first file, since it may be the main program.\nFIRST_FILE=1\n\nFILES_TO_SKIP=\n\nrm \"$PROJECT_DERIVED_FILE_DIR\"/*.s >/dev/null 2>&1\n\n\nwhile read INPUT_FILE_SUFFIX INPUT_FILE_PATH\ndo\n # skip include files (crude, may miss some)\n if ! egrep -qi 'end\\.' \"$INPUT_FILE_PATH\" >/dev/null 2>&1; then\n FIRST_FILE=0\n echo warning: Skipping compilation of \\\"$INPUT_FILE_PATH\\\", seems to be an include file or not a Pascal file\n FILES_TO_SKIP=`echo -e \"$INPUT_FILE_PATH\"'\\n'\"$FILES_TO_SKIP\"`\n continue\n fi\n\n for variant in $BUILD_VARIANTS\n do\n for arch in $ARCHS\n do\n # get the name of the objects file dir\n####\n #FULL_OBJECT_FILES_DIR=\"$OBJECT_FILE_DIR\"-\"$variant\"/\"$arch\"\n FULL_OBJECT_FILES_DIR=\"$PROJECT_DERIVED_FILE_DIR\"/\"$arch\"\n####\n\n # create the necessary directories (not done by Xcode because we only specify a fake output file)\n mkdir -p \"$PROJECT_TEMP_DIR\" \"$FULL_OBJECT_FILES_DIR\"\n \n # if the file was already compiled (because an earlier compiled unit depended on it), skip it\n if test \"$FULL_OBJECT_FILES_DIR\"/`basename \"$INPUT_FILE_PATH\" $INPUT_FILE_SUFFIX`.o -nt \"$INPUT_FILE_PATH\" -a $FIRST_FILE -ne 1 ; then\n continue 3\n fi\n \n # get the correct compiler name\n if [ \"$arch\" = \"i386\" ]\n then\n FPCARCH=386\n RTLARCH=i386\n else\n FPCARCH=ppc\n RTLARCH=powerpc\n fi\n\n # check if the compiler exists\n if ! test -f /usr/local/bin/ppc${FPCARCH}\n then\n echo \"error: FPC for $arch is not installed on this machine. You can probably solve this problem by setting the architectures to build for to your native target only and rebuilding.\"\n exit 2\n fi\n \n # go into the object files dir so we can use short paths\n cd \"$FULL_OBJECT_FILES_DIR\"\n \n # actually compile (but do not assemble nor link)\n echo -n /usr/local/bin/ppc${FPCARCH} \\\"$INPUT_FILE_PATH\\\" $FPC_SPECIFIC_OPTIONS $FPC_COMMON_OPTIONS -Tdarwin -a -s -FE. -vbr $FPC_OVERRIDE_OPTIONS > docompile.sh\n\n # add unit paths\n while read unitsearchpath\n do\n echo -n \" \" $unitsearchpath >> docompile.sh\n done < \"$UNIT_PATHS_FILE\"\n \n echo ' > \"$PROJECT_TEMP_DIR\"/compiler_output 2>&1' >> docompile.sh\n echo 'compres=$?' >> docompile.sh\n echo 'sed -e \"s/\\([^:]*\\):\\([^:]*\\):\\([^:]*\\):\\([^:]*\\):\\(.*\\)/\\1:\\2:\\3:column \\4 -\\5/\" < \"$PROJECT_TEMP_DIR\"/compiler_output' >> docompile.sh\n echo 'exit $compres' >> docompile.sh\n /bin/sh ./docompile.sh\n \n # Compilation successful?\n if [ $? == 0 ]; then\n \n # if it was a unit, continue with the next file (no need to compile all its variants and archs, that\n # will be done when compiling the main program)\n if test ! -f ./link.res; then\n continue 3\n fi\n \n echo Main file found!\n\n # this is the main program -> next time only compile this file\n # (if units are modified, they will be added after this file, but that doesn't matter\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/files_to_compile\n \n # record that the main program was compiled, so we don't have to compile any more units\n MAIN_PROGRAM_COMPILED=1\n \n # delete leftovers\n rm -f ppas.sh link.res\n \n # log the name of the input file so it can be touched if necessary for recompilation\n echo -n \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/mainfile\n \n else\n exit 2\n fi\n done\n done\n\n # if the main program was compiled, we can stop\n if test $MAIN_PROGRAM_COMPILED -ne 0; then\n make_conditional\n touch \"$PROJECT_TEMP_DIR\"/scriptrun\n exit 0\n fi\n FIRST_FILE=0\n\ndone < \"$PROJECT_TEMP_DIR\"/files_to_compile\n\necho \"warning: It seems your project only contains units and no main program\"\ngrep -Fv \"$FILES_TO_SKIP\" < \"$PROJECT_TEMP_DIR\"/files_to_compile > \"$PROJECT_TEMP_DIR\"/files_to_compile.tmp\nsort -u < \"$PROJECT_TEMP_DIR\"/files_to_compile.tmp > \"$PROJECT_TEMP_DIR\"/files_to_compile\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 2CF77DB30CF7556C00F3B101 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 2C4B70240CF7584500B0F0BD /* ModiSDK.pas in Sources */,
- 2C4B70230CF7581000B0F0BD /* Until5000.dpr in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC688C509F574E9004E4BFF /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 2CDD4BE20CB947BE00549FAC /* UltraStarDX.pas in Sources */,
- 2CDD4BE00CB947B100549FAC /* sdl.pas in Sources */,
- 2C4D9C8F0CC9EC8C0031092D /* TextGL.pas in Sources */,
- 2C4D9C920CC9EC8C0031092D /* UCatCovers.pas in Sources */,
- 2C4D9C930CC9EC8C0031092D /* UCommandLine.pas in Sources */,
- 2C4D9C940CC9EC8C0031092D /* UCommon.pas in Sources */,
- 2C4D9C950CC9EC8C0031092D /* UCore.pas in Sources */,
- 2C4D9C960CC9EC8C0031092D /* UCoreModule.pas in Sources */,
- 2C4D9C970CC9EC8C0031092D /* UCovers.pas in Sources */,
- 2C4D9C980CC9EC8C0031092D /* UDataBase.pas in Sources */,
- 2C4D9C990CC9EC8C0031092D /* UDLLManager.pas in Sources */,
- 2C4D9C9A0CC9EC8C0031092D /* UDraw.pas in Sources */,
- 2C4D9C9B0CC9EC8C0031092D /* UFiles.pas in Sources */,
- 2C4D9C9C0CC9EC8C0031092D /* UGraphic.pas in Sources */,
- 2C4D9C9D0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */,
- 2C4D9C9E0CC9EC8C0031092D /* UHooks.pas in Sources */,
- 2C4D9C9F0CC9EC8C0031092D /* UIni.pas in Sources */,
- 2C4D9CA00CC9EC8C0031092D /* UJoystick.pas in Sources */,
- 2C4D9CA10CC9EC8C0031092D /* ULanguage.pas in Sources */,
- 2C4D9CA30CC9EC8C0031092D /* ULCD.pas in Sources */,
- 2C4D9CA40CC9EC8C0031092D /* ULight.pas in Sources */,
- 2C4D9CA50CC9EC8C0031092D /* ULog.pas in Sources */,
- 2C4D9CA60CC9EC8C0031092D /* ULyrics_bak.pas in Sources */,
- 2C4D9CA70CC9EC8C0031092D /* ULyrics.pas in Sources */,
- 2C4D9CA80CC9EC8C0031092D /* UMain.pas in Sources */,
- 2C4D9CA90CC9EC8C0031092D /* UMedia_dummy.pas in Sources */,
- 2C4D9CAA0CC9EC8C0031092D /* UModules.pas in Sources */,
- 2C4D9CAB0CC9EC8C0031092D /* UMusic.pas in Sources */,
- 2C4D9CAC0CC9EC8C0031092D /* UParty.pas in Sources */,
- 2C4D9CAD0CC9EC8C0031092D /* UPlaylist.pas in Sources */,
- 2C4D9CAF0CC9EC8C0031092D /* UPluginInterface.pas in Sources */,
- 2C4D9CB00CC9EC8C0031092D /* uPluginLoader.pas in Sources */,
- 2C4D9CB10CC9EC8C0031092D /* URecord.pas in Sources */,
- 2C4D9CB20CC9EC8C0031092D /* UServices.pas in Sources */,
- 2C4D9CB30CC9EC8C0031092D /* USingNotes.pas in Sources */,
- 2C4D9CB40CC9EC8C0031092D /* USingScores.pas in Sources */,
- 2C4D9CB50CC9EC8C0031092D /* USkins.pas in Sources */,
- 2C4D9CB60CC9EC8C0031092D /* USongs.pas in Sources */,
- 2C4D9CB70CC9EC8C0031092D /* UTextClasses.pas in Sources */,
- 2C4D9CB80CC9EC8C0031092D /* UTexture.pas in Sources */,
- 2C4D9CB90CC9EC8C0031092D /* UThemes.pas in Sources */,
- 2C4D9CBA0CC9EC8C0031092D /* UTime.pas in Sources */,
- 2C4D9CBB0CC9EC8C0031092D /* UVideo.pas in Sources */,
- 2C4D9D920CC9ED4F0031092D /* FreeBitmap.pas in Sources */,
- 2C4D9D930CC9ED4F0031092D /* FreeImage.pas in Sources */,
- 2C4D9DD60CC9EE6F0031092D /* UDisplay.pas in Sources */,
- 2C4D9DD70CC9EE6F0031092D /* UDrawTexture.pas in Sources */,
- 2C4D9DD80CC9EE6F0031092D /* UMenu.pas in Sources */,
- 2C4D9DD90CC9EE6F0031092D /* UMenuButton.pas in Sources */,
- 2C4D9DDA0CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */,
- 2C4D9DDB0CC9EE6F0031092D /* UMenuInteract.pas in Sources */,
- 2C4D9DDC0CC9EE6F0031092D /* UMenuSelect.pas in Sources */,
- 2C4D9DDD0CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */,
- 2C4D9DDE0CC9EE6F0031092D /* UMenuStatic.pas in Sources */,
- 2C4D9DDF0CC9EE6F0031092D /* UMenuText.pas in Sources */,
- 2C4D9DED0CC9EF0A0031092D /* sdl_image.pas in Sources */,
- 2C4D9DF10CC9EF210031092D /* sdl_ttf.pas in Sources */,
- 2C4D9E100CC9EF840031092D /* OpenGL12.pas in Sources */,
- 2C4D9E150CC9EF840031092D /* Windows.pas in Sources */,
- 2C4D9E450CC9F0ED0031092D /* switches.inc in Sources */,
- 2CF54F650CDA1B2B00627463 /* UScreenCredits.pas in Sources */,
- 2CF54F660CDA1B2B00627463 /* UScreenEdit.pas in Sources */,
- 2CF54F670CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */,
- 2CF54F680CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */,
- 2CF54F690CDA1B2B00627463 /* UScreenEditSub.pas in Sources */,
- 2CF54F6A0CDA1B2B00627463 /* UScreenLevel.pas in Sources */,
- 2CF54F6B0CDA1B2B00627463 /* UScreenLoading.pas in Sources */,
- 2CF54F6C0CDA1B2B00627463 /* UScreenMain.pas in Sources */,
- 2CF54F6D0CDA1B2B00627463 /* UScreenName.pas in Sources */,
- 2CF54F6E0CDA1B2B00627463 /* UScreenOpen.pas in Sources */,
- 2CF54F6F0CDA1B2B00627463 /* UScreenOptions.pas in Sources */,
- 2CF54F700CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */,
- 2CF54F710CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */,
- 2CF54F720CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */,
- 2CF54F730CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */,
- 2CF54F740CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */,
- 2CF54F750CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */,
- 2CF54F760CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */,
- 2CF54F770CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */,
- 2CF54F780CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */,
- 2CF54F790CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */,
- 2CF54F7A0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */,
- 2CF54F7B0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */,
- 2CF54F7C0CDA1B2B00627463 /* UScreenPopup.pas in Sources */,
- 2CF54F7D0CDA1B2B00627463 /* UScreenScore.pas in Sources */,
- 2CF54F7E0CDA1B2B00627463 /* UScreenSing.pas in Sources */,
- 2CF54F7F0CDA1B2B00627463 /* UScreenSingModi.pas in Sources */,
- 2CF54F800CDA1B2B00627463 /* UScreenSong.pas in Sources */,
- 2CF54F810CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */,
- 2CF54F820CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */,
- 2CF54F830CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */,
- 2CF54F840CDA1B2B00627463 /* UScreenStatMain.pas in Sources */,
- 2CF54F850CDA1B2B00627463 /* UScreenTop5.pas in Sources */,
- 2CF54F860CDA1B2B00627463 /* UScreenWelcome.pas in Sources */,
- 2CF5508C0CDA22B000627463 /* ModiSDK.pas in Sources */,
- 2CF551100CDA293700627463 /* SQLite3.pas in Sources */,
- 2CF551110CDA293700627463 /* SQLiteTable3.pas in Sources */,
- 2CF552140CDA3D1400627463 /* UPluginDefs.pas in Sources */,
- 2CF552B00CDA42C900627463 /* avcodec.pas in Sources */,
- 2CF552B10CDA42C900627463 /* avformat.pas in Sources */,
- 2CF552B20CDA42C900627463 /* avio.pas in Sources */,
- 2CF552B30CDA42C900627463 /* avutil.pas in Sources */,
- 2CF552B60CDA42C900627463 /* opt.pas in Sources */,
- 2CF552B70CDA42C900627463 /* rational.pas in Sources */,
- 2CF553080CDA51B500627463 /* sdlutils.pas in Sources */,
- 2CDC716C0CDB9CB70018F966 /* StrUtils.pas in Sources */,
- 2CF3EF220CDE13A0004F5956 /* Messages.pas in Sources */,
- 2CF3EF270CDE13BA004F5956 /* MacResources.pas in Sources */,
- 2CF8E6BE0CDFA8E80053A996 /* UPartyDefs.pas in Sources */,
- 2CEA2AE00CE385190097A5FF /* Graphics.pas in Sources */,
- 2CEA2AE10CE385190097A5FF /* JPEG.pas in Sources */,
- 2CEA2AF10CE3868E0097A5FF /* PseudoThread.pas in Sources */,
- 2C89372A0CE393FB005D8A87 /* UPlatform.pas in Sources */,
- 2C8937340CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */,
- 2C5663EF0D35645700D4FF53 /* portaudio.pas in Sources */,
- 2C56642C0D35683200D4FF53 /* SDLMain.m in Sources */,
- 2CAC2BE20D3809F500CA518A /* UAudioInput_Bass.pas in Sources */,
- 2CAC2BE40D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */,
- 2CAC2BF80D380B1B00CA518A /* Bass.pas in Sources */,
- 2CB9E87E0D43B78400214DFA /* USong.pas in Sources */,
- 2CE603DA0D715F2100DB0D88 /* mathematics.pas in Sources */,
- 2CE603DE0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */,
- 2CE603E20D715F8600DB0D88 /* UConfig.pas in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC688D209F57523004E4BFF /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 2CDD4BDE0CB947A400549FAC /* sdl.pas in Sources */,
- DD37F23D0A60252800975B2D /* UltraStarDX.pas in Sources */,
- 2C4D9CBC0CC9EC8C0031092D /* TextGL.pas in Sources */,
- 2C4D9CBF0CC9EC8C0031092D /* UCatCovers.pas in Sources */,
- 2C4D9CC00CC9EC8C0031092D /* UCommandLine.pas in Sources */,
- 2C4D9CC10CC9EC8C0031092D /* UCommon.pas in Sources */,
- 2C4D9CC20CC9EC8C0031092D /* UCore.pas in Sources */,
- 2C4D9CC30CC9EC8C0031092D /* UCoreModule.pas in Sources */,
- 2C4D9CC40CC9EC8C0031092D /* UCovers.pas in Sources */,
- 2C4D9CC50CC9EC8C0031092D /* UDataBase.pas in Sources */,
- 2C4D9CC60CC9EC8C0031092D /* UDLLManager.pas in Sources */,
- 2C4D9CC70CC9EC8C0031092D /* UDraw.pas in Sources */,
- 2C4D9CC80CC9EC8C0031092D /* UFiles.pas in Sources */,
- 2C4D9CC90CC9EC8C0031092D /* UGraphic.pas in Sources */,
- 2C4D9CCA0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */,
- 2C4D9CCB0CC9EC8C0031092D /* UHooks.pas in Sources */,
- 2C4D9CCC0CC9EC8C0031092D /* UIni.pas in Sources */,
- 2C4D9CCD0CC9EC8C0031092D /* UJoystick.pas in Sources */,
- 2C4D9CCE0CC9EC8C0031092D /* ULanguage.pas in Sources */,
- 2C4D9CD00CC9EC8C0031092D /* ULCD.pas in Sources */,
- 2C4D9CD10CC9EC8C0031092D /* ULight.pas in Sources */,
- 2C4D9CD20CC9EC8C0031092D /* ULog.pas in Sources */,
- 2C4D9CD30CC9EC8C0031092D /* ULyrics_bak.pas in Sources */,
- 2C4D9CD40CC9EC8C0031092D /* ULyrics.pas in Sources */,
- 2C4D9CD50CC9EC8C0031092D /* UMain.pas in Sources */,
- 2C4D9CD60CC9EC8C0031092D /* UMedia_dummy.pas in Sources */,
- 2C4D9CD70CC9EC8C0031092D /* UModules.pas in Sources */,
- 2C4D9CD80CC9EC8C0031092D /* UMusic.pas in Sources */,
- 2C4D9CD90CC9EC8C0031092D /* UParty.pas in Sources */,
- 2C4D9CDA0CC9EC8C0031092D /* UPlaylist.pas in Sources */,
- 2C4D9CDC0CC9EC8C0031092D /* UPluginInterface.pas in Sources */,
- 2C4D9CDD0CC9EC8C0031092D /* uPluginLoader.pas in Sources */,
- 2C4D9CDE0CC9EC8C0031092D /* URecord.pas in Sources */,
- 2C4D9CDF0CC9EC8C0031092D /* UServices.pas in Sources */,
- 2C4D9CE00CC9EC8C0031092D /* USingNotes.pas in Sources */,
- 2C4D9CE10CC9EC8C0031092D /* USingScores.pas in Sources */,
- 2C4D9CE20CC9EC8C0031092D /* USkins.pas in Sources */,
- 2C4D9CE30CC9EC8C0031092D /* USongs.pas in Sources */,
- 2C4D9CE40CC9EC8C0031092D /* UTextClasses.pas in Sources */,
- 2C4D9CE50CC9EC8C0031092D /* UTexture.pas in Sources */,
- 2C4D9CE60CC9EC8C0031092D /* UThemes.pas in Sources */,
- 2C4D9CE70CC9EC8C0031092D /* UTime.pas in Sources */,
- 2C4D9CE80CC9EC8C0031092D /* UVideo.pas in Sources */,
- 2C4D9D940CC9ED4F0031092D /* FreeBitmap.pas in Sources */,
- 2C4D9D950CC9ED4F0031092D /* FreeImage.pas in Sources */,
- 2C4D9DE00CC9EE6F0031092D /* UDisplay.pas in Sources */,
- 2C4D9DE10CC9EE6F0031092D /* UDrawTexture.pas in Sources */,
- 2C4D9DE20CC9EE6F0031092D /* UMenu.pas in Sources */,
- 2C4D9DE30CC9EE6F0031092D /* UMenuButton.pas in Sources */,
- 2C4D9DE40CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */,
- 2C4D9DE50CC9EE6F0031092D /* UMenuInteract.pas in Sources */,
- 2C4D9DE60CC9EE6F0031092D /* UMenuSelect.pas in Sources */,
- 2C4D9DE70CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */,
- 2C4D9DE80CC9EE6F0031092D /* UMenuStatic.pas in Sources */,
- 2C4D9DE90CC9EE6F0031092D /* UMenuText.pas in Sources */,
- 2C4D9DEE0CC9EF0A0031092D /* sdl_image.pas in Sources */,
- 2C4D9DF30CC9EF210031092D /* sdl_ttf.pas in Sources */,
- 2C4D9E1C0CC9EF840031092D /* OpenGL12.pas in Sources */,
- 2C4D9E210CC9EF840031092D /* Windows.pas in Sources */,
- 2C4D9E460CC9F0ED0031092D /* switches.inc in Sources */,
- 2CF54F870CDA1B2B00627463 /* UScreenCredits.pas in Sources */,
- 2CF54F880CDA1B2B00627463 /* UScreenEdit.pas in Sources */,
- 2CF54F890CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */,
- 2CF54F8A0CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */,
- 2CF54F8B0CDA1B2B00627463 /* UScreenEditSub.pas in Sources */,
- 2CF54F8C0CDA1B2B00627463 /* UScreenLevel.pas in Sources */,
- 2CF54F8D0CDA1B2B00627463 /* UScreenLoading.pas in Sources */,
- 2CF54F8E0CDA1B2B00627463 /* UScreenMain.pas in Sources */,
- 2CF54F8F0CDA1B2B00627463 /* UScreenName.pas in Sources */,
- 2CF54F900CDA1B2B00627463 /* UScreenOpen.pas in Sources */,
- 2CF54F910CDA1B2B00627463 /* UScreenOptions.pas in Sources */,
- 2CF54F920CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */,
- 2CF54F930CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */,
- 2CF54F940CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */,
- 2CF54F950CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */,
- 2CF54F960CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */,
- 2CF54F970CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */,
- 2CF54F980CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */,
- 2CF54F990CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */,
- 2CF54F9A0CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */,
- 2CF54F9B0CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */,
- 2CF54F9C0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */,
- 2CF54F9D0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */,
- 2CF54F9E0CDA1B2B00627463 /* UScreenPopup.pas in Sources */,
- 2CF54F9F0CDA1B2B00627463 /* UScreenScore.pas in Sources */,
- 2CF54FA00CDA1B2B00627463 /* UScreenSing.pas in Sources */,
- 2CF54FA10CDA1B2B00627463 /* UScreenSingModi.pas in Sources */,
- 2CF54FA20CDA1B2B00627463 /* UScreenSong.pas in Sources */,
- 2CF54FA30CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */,
- 2CF54FA40CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */,
- 2CF54FA50CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */,
- 2CF54FA60CDA1B2B00627463 /* UScreenStatMain.pas in Sources */,
- 2CF54FA70CDA1B2B00627463 /* UScreenTop5.pas in Sources */,
- 2CF54FA80CDA1B2B00627463 /* UScreenWelcome.pas in Sources */,
- 2CF5508D0CDA22B000627463 /* ModiSDK.pas in Sources */,
- 2CF551120CDA293700627463 /* SQLite3.pas in Sources */,
- 2CF551130CDA293700627463 /* SQLiteTable3.pas in Sources */,
- 2CF552170CDA3D1400627463 /* UPluginDefs.pas in Sources */,
- 2CF552A70CDA42C900627463 /* avcodec.pas in Sources */,
- 2CF552A80CDA42C900627463 /* avformat.pas in Sources */,
- 2CF552A90CDA42C900627463 /* avio.pas in Sources */,
- 2CF552AA0CDA42C900627463 /* avutil.pas in Sources */,
- 2CF552AD0CDA42C900627463 /* opt.pas in Sources */,
- 2CF552AE0CDA42C900627463 /* rational.pas in Sources */,
- 2CF553090CDA51B500627463 /* sdlutils.pas in Sources */,
- 2CDC716D0CDB9CB70018F966 /* StrUtils.pas in Sources */,
- 2CF3EF230CDE13A0004F5956 /* Messages.pas in Sources */,
- 2CF3EF280CDE13BA004F5956 /* MacResources.pas in Sources */,
- 2CF8E6BF0CDFA8E80053A996 /* UPartyDefs.pas in Sources */,
- 2CEA2AE20CE385190097A5FF /* Graphics.pas in Sources */,
- 2CEA2AE30CE385190097A5FF /* JPEG.pas in Sources */,
- 2CEA2AF20CE3868E0097A5FF /* PseudoThread.pas in Sources */,
- 2C89372B0CE393FB005D8A87 /* UPlatform.pas in Sources */,
- 2C8937370CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */,
- 2C5663F00D35645700D4FF53 /* portaudio.pas in Sources */,
- 2CAC2BE70D3809F500CA518A /* UAudioInput_Bass.pas in Sources */,
- 2CAC2BE90D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */,
- 2CAC2BF90D380B1B00CA518A /* Bass.pas in Sources */,
- 2CB9E87F0D43B78400214DFA /* USong.pas in Sources */,
- 2CE603DB0D715F2100DB0D88 /* mathematics.pas in Sources */,
- 2CE603DF0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */,
- 2CE603E30D715F8600DB0D88 /* UConfig.pas in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
- DD37F25E0A60268D00975B2D /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DD37F2420A60255800975B2D /* fpcrtl */;
- targetProxy = DD37F25D0A60268D00975B2D /* PBXContainerItemProxy */;
- };
- DDC688EE09F57578004E4BFF /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DDC688D409F57523004E4BFF /* Put all program sources also in this target */;
- targetProxy = DDC688ED09F57578004E4BFF /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
- 2CF77DB70CF7556D00F3B101 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- EXECUTABLE_PREFIX = lib;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- INSTALL_PATH = /usr/local/lib;
- LD_DYLIB_INSTALL_NAME = "@executable_path/libUntil5000.dylib";
- PREBINDING = NO;
- PRODUCT_NAME = Until5000;
- ZERO_LINK = YES;
- };
- name = Debug;
- };
- 2CF77DB80CF7556D00F3B101 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- EXECUTABLE_PREFIX = lib;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_MODEL_TUNING = G5;
- INSTALL_PATH = /usr/local/lib;
- PREBINDING = NO;
- PRODUCT_NAME = Lib_UltraPong;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DD37F2570A60258300975B2D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- INSTALL_PATH = /usr/local/lib;
- PREBINDING = NO;
- PRODUCT_NAME = fpcrtl;
- ZERO_LINK = YES;
- };
- name = Debug;
- };
- DD37F2580A60258300975B2D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_MODEL_TUNING = G5;
- INSTALL_PATH = /usr/local/lib;
- PREBINDING = NO;
- PRODUCT_NAME = fpcrtl;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DDC6851109F5717A004E4BFF /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- FPC_COMMON_OPTIONS = "-Sd -XMSDL_main";
- FPC_MAIN_FILE = "";
- FPC_OVERRIDE_OPTIONS = "";
- FPC_RTL_UNITS_BASE = /usr/local/lib/fpc/;
- FPC_SPECIFIC_OPTIONS = "-Ci -Cr -Co -gl -O-";
- FRAMEWORK_SEARCH_PATHS = "";
- HEADER_SEARCH_PATHS = "";
- LIBRARY_SEARCH_PATHS = "";
- REZ_SEARCH_PATHS = "";
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- USER_HEADER_SEARCH_PATHS = "";
- };
- name = Debug;
- };
- DDC6851209F5717A004E4BFF /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- FPC_COMMON_OPTIONS = "-Sd -XMSDL_main";
- FPC_MAIN_FILE = "";
- FPC_OVERRIDE_OPTIONS = "";
- FPC_RTL_UNITS_BASE = /usr/local/lib/fpc/;
- FPC_SPECIFIC_OPTIONS = "-Ci- -Cr- -Co- -O3 -Xs ";
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- };
- name = Release;
- };
- DDC688CC09F574E9004E4BFF /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
- );
- FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\"";
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
- INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_4)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_5)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_6)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
- );
- LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\"";
- LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../lib/SQLite\"";
- LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../lib/ffmpeg\"";
- LIBRARY_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../lib/bass\"";
- LIBRARY_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../lib/FreeImage\"";
- LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../lib/ffmpeg\"";
- LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../lib/bass\"";
- LINK_WITH_STANDARD_LIBRARIES = YES;
- OTHER_LDFLAGS = (
- "-framework",
- Carbon,
- );
- PREBINDING = NO;
- PRODUCT_NAME = "UltraStar Deluxe";
- WRAPPER_EXTENSION = app;
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- DDC688CD09F574E9004E4BFF /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
- );
- FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\"";
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_MODEL_TUNING = G5;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
- INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_4)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_5)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_6)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_7)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_8)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_9)",
- "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
- );
- LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\"";
- LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/Bass\"";
- LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/FreeImage\"";
- LIBRARY_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/FreeImage\"";
- LIBRARY_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../lib/bass\"";
- LIBRARY_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../lib/FreeImage\"";
- LIBRARY_SEARCH_PATHS_QUOTED_7 = "\"$(SRCROOT)/../lib/SQLite\"";
- LIBRARY_SEARCH_PATHS_QUOTED_8 = "\"$(SRCROOT)/../lib/ffmpeg\"";
- LIBRARY_SEARCH_PATHS_QUOTED_9 = "\"$(SRCROOT)/../lib/ffmpeg\"";
- LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../lib/bass\"";
- LINK_WITH_STANDARD_LIBRARIES = YES;
- OTHER_LDFLAGS = (
- "-framework",
- Carbon,
- );
- PREBINDING = NO;
- PRODUCT_NAME = "UltraStar Deluxe";
- WRAPPER_EXTENSION = app;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DDC688DD09F57542004E4BFF /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
- INSTALL_PATH = /usr/local/lib;
- OTHER_LDFLAGS = (
- "-framework",
- Carbon,
- );
- PREBINDING = NO;
- PRODUCT_NAME = "Put unit sources in the 'Compile Sources' phase of this target";
- };
- name = Debug;
- };
- DDC688DE09F57542004E4BFF /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_MODEL_TUNING = G5;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
- INSTALL_PATH = /usr/local/lib;
- OTHER_LDFLAGS = (
- "-framework",
- Carbon,
- );
- PREBINDING = NO;
- PRODUCT_NAME = "Put unit sources in the 'Compile Sources' phase of this target";
- ZERO_LINK = NO;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 2CF77DB90CF7558B00F3B101 /* Build configuration list for PBXNativeTarget "Modi_Until5000" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 2CF77DB70CF7556D00F3B101 /* Debug */,
- 2CF77DB80CF7556D00F3B101 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DD37F2560A60258300975B2D /* Build configuration list for PBXNativeTarget "fpcrtl" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DD37F2570A60258300975B2D /* Debug */,
- DD37F2580A60258300975B2D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DDC6851009F5717A004E4BFF /* Build configuration list for PBXProject "UltraStarDX" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DDC6851109F5717A004E4BFF /* Debug */,
- DDC6851209F5717A004E4BFF /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DDC688CB09F574E9004E4BFF /* Build configuration list for PBXNativeTarget "UltraStarDX" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DDC688CC09F574E9004E4BFF /* Debug */,
- DDC688CD09F574E9004E4BFF /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DDC688DC09F57542004E4BFF /* Build configuration list for PBXNativeTarget "Put all program sources also in this target" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DDC688DD09F57542004E4BFF /* Debug */,
- DDC688DE09F57542004E4BFF /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
-/* End XCConfigurationList section */
- };
- rootObject = DDC6850F09F5717A004E4BFF /* Project object */;
-}
diff --git a/Game/Code/MacOSX/Wrapper/MacResources.pas b/Game/Code/MacOSX/Wrapper/MacResources.pas
deleted file mode 100644
index a97fb565..00000000
--- a/Game/Code/MacOSX/Wrapper/MacResources.pas
+++ /dev/null
@@ -1,124 +0,0 @@
-unit MacResources;
-
-{$I switches.inc}
-
-interface
-
-uses
- Classes, Windows, SysUtils;
-
-type
-
- TResourceStream = class(TFileStream)
- private
- public
- constructor Create(Instance: THandle; const ResName: string; ResType: PChar);
- end;
-
- Function FindResource( hInstance : THandle; pcIdentifier : PChar; pcResType : PChar) : THandle;
-
-implementation
-
-Function FindResource( hInstance : THandle; pcIdentifier : PChar; pcResType : PChar) : THandle;
-begin
- Result := 1;
-end;
-
-Function GetResourcesPath : String;
-var
- x,
- i : integer;
-begin
- Result := ExtractFilePath(ParamStr(0));
- for x := 0 to 2 do begin
- i := Length(Result);
- repeat
- Delete( Result, i, 1);
- i := Length(Result);
- until (i = 0) or (Result[i] = '/');
- end;
-end;
-
-{ TResourceStream }
-
-constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);
-var
- sResNameLower : string;
- sFileName : String;
-begin
- sResNameLower := LowerCase(string(ResName));
-
- if ResType = 'TEX' then begin
- if sResNameLower = 'font' then
- sFileName := GetResourcesPath + 'Fonts/Normal/eurostar_regular.png'
- else if sResNameLower = 'fontb' then
- sFileName := GetResourcesPath + 'Fonts/Bold/eurostar_regular_bold.png'
- else if sResNameLower = 'fonto' then
- sFileName := GetResourcesPath + 'Fonts/Outline 1/Outline 1.png'
- else if sResNameLower = 'fonto2' then
- sFileName := GetResourcesPath + 'Fonts/Outline 2/Outline 2.png'
- else if sResNameLower = 'crdts_bg' then
- sFileName := GetResourcesPath + 'Graphics/credits_v5_bg.png'
- else if sResNameLower = 'crdts_ovl' then
- sFileName := GetResourcesPath + 'Graphics/credits_v5_overlay.png'
- else if sResNameLower = 'crdts_blindguard' then
- sFileName := GetResourcesPath + 'Graphics/names_blindguard.png'
- else if sResNameLower = 'crdts_blindy' then
- sFileName := GetResourcesPath + 'Graphics/names_blindy.png'
- else if sResNameLower = 'crdts_canni' then
- sFileName := GetResourcesPath + 'Graphics/names_canni.png'
- else if sResNameLower = 'crdts_commandio' then
- sFileName := GetResourcesPath + 'Graphics/names_commandio.png'
- else if sResNameLower = 'crdts_lazyjoker' then
- sFileName := GetResourcesPath + 'Graphics/names_lazyjoker.png'
- else if sResNameLower = 'crdts_mog' then
- sFileName := GetResourcesPath + 'Graphics/names_mog.png'
- else if sResNameLower = 'crdts_mota' then
- sFileName := GetResourcesPath + 'Graphics/names_mota.png'
- else if sResNameLower = 'crdts_skillmaster' then
- sFileName := GetResourcesPath + 'Graphics/names_skillmaster.png'
- else if sResNameLower = 'crdts_whiteshark' then
- sFileName := GetResourcesPath + 'Graphics/names_whiteshark.png'
- else if sResNameLower = 'intro_l01' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-01.png'
- else if sResNameLower = 'intro_l02' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-02.png'
- else if sResNameLower = 'intro_l03' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-03.png'
- else if sResNameLower = 'intro_l04' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-04.png'
- else if sResNameLower = 'intro_l05' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-05.png'
- else if sResNameLower = 'intro_l06' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-06.png'
- else if sResNameLower = 'intro_l07' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-07.png'
- else if sResNameLower = 'intro_l08' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-08.png'
- else if sResNameLower = 'intro_l09' then
- sFileName := GetResourcesPath + 'Graphics/intro-l-09.png'
- else if sResNameLower = 'outro_bg' then
- sFileName := GetResourcesPath + 'Graphics/outro-bg.png'
- else if sResNameLower = 'outro_esc' then
- sFileName := GetResourcesPath + 'Graphics/outro-esc.png'
- else if sResNameLower = 'outro_exd' then
- sFileName := GetResourcesPath + 'Graphics/outro-exit-dark.png';
- end
- else if ResType = 'FNT' then begin
- if sResNameLower = 'font' then
- sFileName := GetResourcesPath + 'Fonts/Normal/eurostar_regular.dat'
- else if sResNameLower = 'fontb' then
- sFileName := GetResourcesPath + 'Fonts/Bold/eurostar_regular_bold.dat'
- else if sResNameLower = 'fonto' then
- sFileName := GetResourcesPath + 'Fonts/Outline 1/Outline 1.dat'
- else if sResNameLower = 'fonto2' then
- sFileName := GetResourcesPath + 'Fonts/Outline 2/Outline 2.dat';
- end;
-
- if FileExists(sFileName) then
- inherited Create( sFileName, fmOpenReadWrite)
- else
- raise Exception.Create('MacResources.TResourceStream.Create: File "' + sFileName + '" not found.');
-end;
-
-end.
diff --git a/Game/Code/MacOSX/Wrapper/PseudoThread.pas b/Game/Code/MacOSX/Wrapper/PseudoThread.pas
deleted file mode 100644
index 16157646..00000000
--- a/Game/Code/MacOSX/Wrapper/PseudoThread.pas
+++ /dev/null
@@ -1,48 +0,0 @@
-unit PseudoThread;
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-interface
-
-type
-
-// Debugging threads with XCode doesn't seem to work.
-// We use PseudoThread in Debug mode to get proper debugging.
-TPseudoThread = class(TObject)
- private
- protected
- Terminated,
- FreeOnTerminate : Boolean;
- procedure Execute; virtual; abstract;
- procedure Resume;
- procedure Suspend;
- public
- constructor Create(const suspended : Boolean);
-end;
-
-implementation
-
-{ TPseudoThread }
-
-constructor TPseudoThread.Create(const suspended : Boolean);
-begin
- if not suspended then begin
- Execute;
- end;
-end;
-
-procedure TPseudoThread.Resume;
-begin
- Execute;
-end;
-
-procedure TPseudoThread.Suspend;
-begin
-end;
-
-end.
-
diff --git a/Game/Code/MacOSX/Wrapper/Windows.pas b/Game/Code/MacOSX/Wrapper/Windows.pas
deleted file mode 100644
index cee75591..00000000
--- a/Game/Code/MacOSX/Wrapper/Windows.pas
+++ /dev/null
@@ -1,167 +0,0 @@
-unit Windows;
-
-{$I switches.inc}
-
-interface
-
-uses Types;
-
-const
- opengl32 = 'OpenGL';
- MAX_PATH = 260;
-
-type
-
- DWORD = Types.DWORD;
- {$EXTERNALSYM DWORD}
- BOOL = LongBool;
- {$EXTERNALSYM BOOL}
- PBOOL = ^BOOL;
- {$EXTERNALSYM PBOOL}
- PByte = Types.PByte;
- PINT = ^Integer;
- {$EXTERNALSYM PINT}
- PSingle = ^Single;
- PWORD = ^Word;
- {$EXTERNALSYM PWORD}
- PDWORD = ^DWORD;
- {$EXTERNALSYM PDWORD}
- LPDWORD = PDWORD;
- {$EXTERNALSYM LPDWORD}
- HDC = type LongWord;
- {$EXTERNALSYM HDC}
- HGLRC = type LongWord;
- {$EXTERNALSYM HGLRC}
- TLargeInteger = Int64;
- HFONT = type LongWord;
- {$EXTERNALSYM HFONT}
- HWND = type LongWord;
- {$EXTERNALSYM HWND}
-
- PPaletteEntry = ^TPaletteEntry;
- {$EXTERNALSYM tagPALETTEENTRY}
- tagPALETTEENTRY = packed record
- peRed: Byte;
- peGreen: Byte;
- peBlue: Byte;
- peFlags: Byte;
- end;
- TPaletteEntry = tagPALETTEENTRY;
- {$EXTERNALSYM PALETTEENTRY}
- PALETTEENTRY = tagPALETTEENTRY;
-
- PRGBQuad = ^TRGBQuad;
- {$EXTERNALSYM tagRGBQUAD}
- tagRGBQUAD = packed record
- rgbBlue: Byte;
- rgbGreen: Byte;
- rgbRed: Byte;
- rgbReserved: Byte;
- end;
- TRGBQuad = tagRGBQUAD;
- {$EXTERNALSYM RGBQUAD}
- RGBQUAD = tagRGBQUAD;
-
- PBitmapInfoHeader = ^TBitmapInfoHeader;
- {$EXTERNALSYM tagBITMAPINFOHEADER}
- tagBITMAPINFOHEADER = packed record
- biSize: DWORD;
- biWidth: Longint;
- biHeight: Longint;
- biPlanes: Word;
- biBitCount: Word;
- biCompression: DWORD;
- biSizeImage: DWORD;
- biXPelsPerMeter: Longint;
- biYPelsPerMeter: Longint;
- biClrUsed: DWORD;
- biClrImportant: DWORD;
- end;
- TBitmapInfoHeader = tagBITMAPINFOHEADER;
- {$EXTERNALSYM BITMAPINFOHEADER}
- BITMAPINFOHEADER = tagBITMAPINFOHEADER;
-
- PBitmapInfo = ^TBitmapInfo;
- {$EXTERNALSYM tagBITMAPINFO}
- tagBITMAPINFO = packed record
- bmiHeader: TBitmapInfoHeader;
- bmiColors: array[0..0] of TRGBQuad;
- end;
- TBitmapInfo = tagBITMAPINFO;
- {$EXTERNALSYM BITMAPINFO}
- BITMAPINFO = tagBITMAPINFO;
-
- PBitmapFileHeader = ^TBitmapFileHeader;
- {$EXTERNALSYM tagBITMAPFILEHEADER}
- tagBITMAPFILEHEADER = packed record
- bfType: Word;
- bfSize: DWORD;
- bfReserved1: Word;
- bfReserved2: Word;
- bfOffBits: DWORD;
- end;
- TBitmapFileHeader = tagBITMAPFILEHEADER;
- {$EXTERNALSYM BITMAPFILEHEADER}
- BITMAPFILEHEADER = tagBITMAPFILEHEADER;
-
-
- function MakeLong(a, b: Word): Longint;
- procedure ZeroMemory(Destination: Pointer; Length: DWORD);
- function QueryPerformanceFrequency(var lpFrequency: TLargeInteger): BOOL;
- function QueryPerformanceCounter(var lpPerformanceCount: TLargeInteger): BOOL;
- function GetTickCount : Cardinal;
- Procedure ShowMessage(msg : string);
- procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
-
-implementation
-
-uses SDL;
-
-procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
-begin
- Move(Source^, Destination^, Length);
-end;
-
-Procedure ShowMessage(msg : string);
-begin
- // to be implemented
-end;
-
-function MakeLong(A, B: Word): Longint;
-begin
- Result := (LongInt(B) shl 16) + A;
-end;
-
-procedure ZeroMemory(Destination: Pointer; Length: DWORD);
-begin
- FillChar( Destination^, Length, 0);
-end;
-
-function QueryPerformanceFrequency(var lpFrequency: TLargeInteger): BOOL;
-begin
-{$IFDEF MSWINDOWS}
- Result := Windows.QueryPerformanceFrequency(lpFrequency);
-{$ENDIF}
-{$IFDEF MACOS}
- Result := true;
- lpFrequency := 1000;
-{$ENDIF}
-end;
-
-function QueryPerformanceCounter(var lpPerformanceCount: TLargeInteger): BOOL;
-begin
-{$IFDEF MSWINDOWS}
- Result := Windows.QueryPerformanceCounter(lpPerformanceCount);
-{$ENDIF}
-{$IFDEF MACOS}
- Result := true;
- lpPerformanceCount := SDL_GetTicks;
-{$ENDIF}
-end;
-
-function GetTickCount : Cardinal;
-begin
- Result := SDL_GetTicks;
-end;
-
-end.
diff --git a/Game/Code/Makefile.in b/Game/Code/Makefile.in
deleted file mode 100644
index 8fc31bd8..00000000
--- a/Game/Code/Makefile.in
+++ /dev/null
@@ -1,393 +0,0 @@
-#################################################
-# Makefile for @PACKAGE_STRING@
-# @configure_input@
-#################################################
-
-# general definitions
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-libdir = @libdir@
-infodir = @infodir@
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-datarootdir = @datarootdir@
-VPATH = @srcdir@
-usdxrootdir = @usdxrootdir@
-
-INSTALL_PATH_SUFFIX = @suffix@
-INSTALL_datadir = $(datarootdir)/$(INSTALL_PATH_SUFFIX)
-
-@SET_MAKE@
-
-# recursive dir creation tool
-MKDIR_P = @MKDIR_P@
-# install tool
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-# calls "ln -s"
-LN_S = @LN_S@
-
-# Package configuration
-USDX_PACKAGE_NAME = @PACKAGE_NAME@
-# should be $(USDX_PACKAGE_NAME) instead
-USDX_PREFIX = ultrastardx
-USDX_VERSION = @PACKAGE_VERSION@
-USDX_TARNAME = @PACKAGE_TARNAME@
-
-USDX_TOOLS_DIR = $(usdxrootdir)/Tools
-USDX_LIB_DIR = ./lib
-USDX_BUILD_DIR = ./build
-
-# file-type suffix of executables (e.g. ".exe" in windows)
-EXE_SUFFIX = @EXEEXT@
-
-# Free Pascal compiler
-PPC = @PPC@
-# FPC target platform and processor
-PPLATFORM = @FPC_PLATFORM@
-PPROCESSOR = @FPC_PROCESSOR@
-
-EXTRA_SRCDIRS =
-
-# RC resource extraction config
-RESEXTRACTOR_NAME = ResourceExtractor
-RESEXTRACTOR_DIR = $(USDX_TOOLS_DIR)/$(RESEXTRACTOR_NAME)
-RESEXTRACTOR_BIN = $(RESEXTRACTOR_DIR)/$(RESEXTRACTOR_NAME)$(EXE_SUFFIX)
-RESOURCE_DIR = $(usdxrootdir)/Resources
-RESOURCE_FILE = resource.inc
-RC_FILE = UltraStar.rc
-EXTRA_SRCDIRS += $(RESEXTRACTOR_DIR)
-
-# cwrapper settings
-PROJECTM_CWRAPPER_DIR = $(USDX_LIB_DIR)/projectM/cwrapper
-@COMMENT_PROJECTM_CWRAPPER@EXTRA_SRCDIRS += $(PROJECTM_CWRAPPER_DIR)
-
-# Directories added to the unit path
-PUNIT_TOKEN = -Fu
-PUNIT_FLAGS = $(PUNIT_TOKEN).
-
-# Directory where compiled units (.ppu and .o files) are stored
-PCUNIT_TOKEN = -FU
-PCUNIT_DIR = $(USDX_BUILD_DIR)/$(PPLATFORM)/fpc
-PCUNIT_FLAGS = $(PCUNIT_TOKEN)$(PCUNIT_DIR)
-
-# Directories added to the includes path
-PINC_TOKEN = -Fi
-PINC_FLAGS = $(PINC_TOKEN)$(USDX_LIB_DIR)/JEDI-SDL/SDL/Pas
-
-# FPC flags
-
-# The user can overwrite the default flags with
-# make PFLAGS_BASE="myflags"
-PFLAGS_BASE = -S2gi -vB
-# The user can specify additional flags with
-# make PFLAGS_EXTRA="myflags"
-PFLAGS_EXTRA = @PFLAGS_EXTRA@
-PFLAGS_DEBUG = @PFLAGS_DEBUG@
-PFLAGS_RELEASE = @PFLAGS_RELEASE@
-# the user's flags (specified with configure) must be the last in
-# the list to overwrite the defaults (e.g.with the - option: -Xs-).
-PFLAGS = $(PFLAGS_BASE) @PFLAGS_MAKE@ $(PFLAGS_EXTRA)
-
-LIBS = @LIBS@
-LDFLAGS = @LDFLAGS@
-linkflags = $(strip $(LDFLAGS) $(LIBS))
-ifneq ($(linkflags),)
-PLINKFLAGS = -k"$(linkflags)"
-endif
-
-# dpr project file used as input
-USDX_SRC = UltraStar.dpr
-# name of executable
-USDX_BIN_NAME = $(USDX_PREFIX)$(EXE_SUFFIX)
-USDX_BIN = $(usdxrootdir)/$(USDX_BIN_NAME)
-
-# name of the modification timestamp filename
-modfile = lastmod
-
-# otool: Mac OS X object file displaying tool
-OTOOL = /usr/bin/otool
-# install_name_tool: Mac OS X tool to change dynamic shared library install names
-INSTALL_NAME_TOOL = /usr/bin/install_name_tool
-# hdiutil: Mac OS X disk image tool
-HDIUTIL = /usr/bin/hdiutil
-
-#################################################
-# general targets
-#################################################
-
-.PHONY: debug release recursive all recursive-all dependencies install install-local install-global install-data install-data-recursive install-exec uninstall uninstall-local uninstall-global uninstall-data uninstall-exec clean recursive-clean distclean recursive-distclean clean_obj clean_res dist debian-package update-modfile $(EXTRA_SRCDIRS)
-
-debug: PFLAGS = $(PFLAGS_BASE) $(PFLAGS_DEBUG) $(PFLAGS_EXTRA)
-debug: all
-
-release: PFLAGS = $(PFLAGS_BASE) $(PFLAGS_RELEASE) $(PFLAGS_EXTRA)
-release: all
-
-all: recursive-all update-modfile dependencies $(USDX_BIN)
-
-recursive-all: recursive-target = all
-recursive-all: recursive
-
-dependencies: $(RESOURCE_FILE)
-
-# call Makefiles in other source-dirs
-recursive: $(EXTRA_SRCDIRS)
-$(EXTRA_SRCDIRS):
- $(MAKE) -C $@ $(recursive-target)
-
-#################################################
-# build
-#################################################
-
-# clean old data before compiling, otherwise FPC might miss some changes.
-$(USDX_BIN): lastmod
- $(MAKE) clean_obj
- mkdir -p "$(PCUNIT_DIR)"
- $(PPC) $(strip $(PFLAGS) $(PDEFINES) $(PLINKFLAGS) $(PINC_FLAGS) $(PUNIT_FLAGS) $(PCUNIT_FLAGS)) -o$@ $(USDX_SRC)
-
-#################################################
-# install/uninstall
-#################################################
-
-install: all install-@install_type@
-
-uninstall: uninstall-@install_type@
-
-
-# local build
-
-install-local:
-
-uninstall-local:
- rm -f "$(USDX_BIN)"
-
-
-# global build
-
-install-global: install-data install-exec
-
-install-data:
- $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Artwork" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Artwork" install-data-recursive
- $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Languages" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Languages" install-data-recursive
- $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Sounds" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Sounds" install-data-recursive
- $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Themes" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Themes" install-data-recursive
- $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Resources" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Resources" install-data-recursive
- $(INSTALL_DATA) "$(usdxrootdir)/License.txt" "$(INSTALL_datadir)"
-
-install-data-recursive:
- $(MKDIR_P) "$(RECURSIVE_DST_DIR)"
- @for file in "$(RECURSIVE_SRC_DIR)"/*; do \
- if test -f "$$file"; then \
- echo $(INSTALL_DATA) "$$file" "$(RECURSIVE_DST_DIR)"; \
- $(INSTALL_DATA) "$$file" "$(RECURSIVE_DST_DIR)"; \
- fi; \
- if test -d "$$file"; then \
- subdir="$$file"; \
- subdirname=`basename "$$subdir"`; \
- $(MAKE) RECURSIVE_SRC_DIR="$$subdir" RECURSIVE_DST_DIR="$(RECURSIVE_DST_DIR)/$$subdirname" install-data-recursive; \
- fi; \
- done
-
-install-exec:
- $(MKDIR_P) "$(bindir)"
- $(INSTALL) "$(USDX_BIN)" "$(bindir)"
-
-uninstall-global: uninstall-data uninstall-exec
-
-uninstall-data:
- rm -rf "$(INSTALL_datadir)/Artwork"
- rm -rf "$(INSTALL_datadir)/Languages"
- rm -rf "$(INSTALL_datadir)/Sounds"
- rm -rf "$(INSTALL_datadir)/Themes"
- rm -rf "$(INSTALL_datadir)/Resources"
- rm -f "$(INSTALL_datadir)/License.txt"
- -rmdir "$(INSTALL_datadir)"
-
-uninstall-exec:
- rm -f "$(bindir)/$(USDX_BIN_NAME)"
-
-#################################################
-# Distributable source-package (TODO)
-#################################################
-
-disttmpdir = ./distdir
-
-dist:
-# $(MKDIR_P) $(disttmpdir)
-# acm $(usdxrootdir) $(disttmpdir)
-# $(MAKE) -C $(disttmpdir)/Game/Code distclean
-# tar cvzf $(USDX_TARNAME)-$(USDX_VERSION).tar.gz $(usdxrootdir)
- @echo "Comming soon"
-
-#################################################
-# Debian package
-#################################################
-
-debpkgoutdir = $(usdxrootdir)/packages
-debpkgtmpdir = $(debpkgoutdir)/deb-package
-# should be $(USDX_PACKAGE_NAME) instead
-debpkgprefix = ultrastardx
-debpkgname = $(debpkgprefix)_$(USDX_VERSION)_$(PPROCESSOR).deb
-
-debian-pkg: all
- rm -rf $(debpkgtmpdir)
- rm -rf $(debpkgoutdir)
-
- $(MKDIR_P) $(debpkgoutdir)
- $(MKDIR_P) $(debpkgtmpdir)/DEBIAN
-
- $(MAKE) prefix=$(debpkgtmpdir)/$(prefix) install
-
- $(INSTALL_DATA) $(debpkgprefix).control $(debpkgtmpdir)/DEBIAN/control
-
- dpkg-deb --build $(debpkgtmpdir)
- mv $(debpkgtmpdir)/../deb-package.deb $(debpkgoutdir)/$(debpkgname)
-
- rm -rf $(debpkgtmpdir)
-
-#################################################
-# RPM (TODO)
-#################################################
-
-rpm: all
- @echo "Coming soon"
-
-#################################################
-# Mac OS X app-bundle
-#################################################
-
-macosx_bundle_path = $(usdxrootdir)/UltraStarDeluxe.app/Contents
-macosx-app: all
-# Create double clickable Mac OS X application.
-
- @echo ""
- @echo "Creating the Mac OS X application"
- @echo ""
-
- $(MKDIR_P) $(macosx_bundle_path)/Resources
-
-# Put the icon file into its particular place.
-# Must be done BEFORE info.plist is created.
- $(INSTALL_DATA) $(usdxrootdir)/Resources/Graphics/ustar-icon_v01.icns $(macosx_bundle_path)/Resources/
-
-# the info.plist file
- $(INSTALL_DATA) MacOSX/Info.plist $(macosx_bundle_path)/
-
-# Copy the resources.
- $(MAKE) install-global INSTALL_datadir=$(macosx_bundle_path)/Resources bindir=$(macosx_bundle_path)/MacOS
-
-# final messages
- @echo ""
- @echo "Mac OS X application created."
- @echo "Please report issues to the developer team, preferably mischi."
- @echo "Have fun."
- @echo ""
-
-macosx-standalone-app: macosx-app
-# Create double clickable standalone (does not need fink) Mac OS X
-# application. Not fully test, but should work on 10.5.
-
- @echo ""
- @echo "Creating the standalone Mac OS X application"
- @echo ""
-
-# copy the dylib and change its install names
-
-define install_osx_libraries
- $(shell $(INSTALL) -m 755 $(dylib) $(macosx_bundle_path)/MacOS)
- $(shell $(INSTALL_NAME_TOOL) -change $(dylib) @executable_path/$(notdir $(dylib)) $(macosx_bundle_path)/MacOS/ultrastardx)
- $(shell $(INSTALL_NAME_TOOL) -id @executable_path/$(notdir $(dylib)) $(macosx_bundle_path)/MacOS/$(notdir $(dylib)))
- $(foreach linked_dylibs_2,$(shell $(OTOOL) -L $(dylib) | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \usr\/lib | grep -v executable_path),$(rename_secondary_osx_libraries))
-endef
-
-define rename_secondary_osx_libraries
- $(shell $(INSTALL_NAME_TOOL) -change $(linked_dylibs_2) @executable_path/$(notdir $(linked_dylibs_2)) $(macosx_bundle_path)/MacOS/$(notdir $(dylib)))
-endef
-
-# work on the dylibs in $(macosx_bundle_path)/MacOS/ultrastardx
- $(foreach dylib,$(shell $(OTOOL) -L $(macosx_bundle_path)/MacOS/ultrastardx | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
-
-# work on the secondary dylibs from ffmpeg
-# libavcodec references all tertiary libraries of the ffmpeg libs
- $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libavcodec.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
-# same procedure in libfaac. it gets libgnugetopt
- $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libfaac.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
-
-# same procedure for tertiary libs in SDL_image
- $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libSDL_image.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
-
-# X11 libs as well, because users may not have installed it on 10.4
- $(foreach dylib,$(shell $(OTOOL) -L /usr/X11R6/lib/libX11.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
-
-# final messages
- @echo "Standalone Mac OS X application created."
- @echo ""
-
-macosx-disk-image: macosx-standalone-app
- /bin/rm -f ultrastardx.dmg
- $(HDIUTIL) create -type SPARSE -size 30m -fs HFS+ -volname UltraStarDeluxe -ov -attach UltraStarDeluxe.sparseimage
- /bin/cp -R ../../UltraStarDeluxe.app /Volumes/UltraStarDeluxe
-# /bin/cp ultrastardx/icons/UltraStarDeluxeVolumeIcon.icns /Volumes/UltraStarDeluxe/.VolumeIcon.icns
-# /Developer/Tools/SetFile -a C /Volumes/UltraStarDeluxe/.VolumeIcon.icns /Volumes/UltraStarDeluxe
- $(HDIUTIL) detach /Volumes/UltraStarDeluxe
- $(HDIUTIL) convert UltraStarDeluxe.sparseimage -format UDBZ -o ultrastardx.dmg
- /bin/rm -f UltraStarDeluxe.sparseimage
-#################################################
-# clean-up
-#################################################
-
-clean: recursive-clean clean_obj
-
-recursive-clean: recursive-target = clean
-recursive-clean: recursive
-
-distclean: recursive-distclean clean clean_res
- find . -name "*.o" -o -name "*.ppu" -o -name "*.rst" -o -name "*.compiled" | xargs rm -f
- find . -name "*~" -name "*.bak" -o -name "*.orig" -o -name "*.dcu" | xargs rm -f
- find . -name "__history" | xargs rm -r -f
- rm -f "$(USDX_PREFIX).res" "$(USDX_PREFIX).identcache"
- rm -f config.inc Makefile config.log config.status configure aclocal.m4
- rm -rf autom4te.cache
-
-recursive-distclean: recursive-target = distclean
-recursive-distclean: recursive
-
-clean_obj:
- find "$(PCUNIT_DIR)" -name "*.o" -o -name "*.ppu" -o -name "*.rst" -o -name "*.compiled" | xargs rm -f
- rm -f "$(USDX_BIN)"
-
-#################################################
-# Resource-file
-#################################################
-
-$(RESOURCE_FILE): $(RC_FILE)
- $(RESEXTRACTOR_BIN) $(RC_FILE) $(RESOURCE_DIR) $(RESOURCE_FILE)
-
-clean_res:
- rm -f "$(RESOURCE_FILE)"
-
-#################################################
-# auto-update
-#################################################
-
-# FPC does not recognize changes correctly. E.g. sometimes changes in .inc-files or
-# conditional .pas dependencies are ignored which results in corrupted builds.
-# So check for changes with a modification timestamp.
-update-modfile:
- test -e $(modfile) || touch $(modfile)
- find . \( -name "*.pas" -o -name "*.pp" -o -name "*.inc" -o -name "*.dpr" \) -newer $(modfile) -exec touch $(modfile) \;
- find $(USDX_LIB_DIR) -name "*.a" -newer $(modfile) -exec touch $(modfile) \;
-
-Makefile: Makefile.in config.status
- ./config.status
-
-config.status: configure
- ./config.status --recheck
-
-configure: configure.ac config.inc.in aclocal.m4
- autoconf
-
-aclocal.m4: m4/*
- aclocal -I m4
diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas
deleted file mode 100644
index 2b10b2c6..00000000
--- a/Game/Code/Menu/UDisplay.pas
+++ /dev/null
@@ -1,383 +0,0 @@
-unit UDisplay;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- ucommon,
- SDL,
- UMenu,
- gl,
- glu,
- SysUtils;
-
-type
- TDisplay = class
- private
- //fade-to-black-hack
- BlackScreen: Boolean;
-
- FadeEnabled: Boolean; // true if fading is enabled
- FadeFailed: Boolean; // true if fading is possible (enough memory, etc.)
- FadeState: integer; // fading state, 0 means that the fade texture must be initialized
- LastFadeTime: Cardinal; // last fade update time
-
- FadeTex: array[1..2] of GLuint;
-
- FPSCounter : Cardinal;
- LastFPS : Cardinal;
- NextFPSSwap : Cardinal;
-
- OSD_LastError : String;
-
- procedure DrawDebugInformation;
- public
- NextScreen : PMenu;
- CurrentScreen : PMenu;
-
- //popup data
- NextScreenWithCheck: Pmenu;
- CheckOK : Boolean;
-
- // FIXME: Fade is set to 0 in UMain and other files but not used here anymore.
- Fade : Real;
-
- constructor Create;
- destructor Destroy; override;
-
- procedure SaveScreenShot;
-
- function Draw: Boolean;
- end;
-
-var
- Display: TDisplay;
-
-implementation
-
-uses
- UImage,
- TextGL,
- ULog,
- UMain,
- UTexture,
- UIni,
- UGraphic,
- UTime,
- UCommandLine;
-
-constructor TDisplay.Create;
-var
- i: integer;
-begin
- inherited Create;
-
- //popup hack
- CheckOK := False;
- NextScreen := nil;
- NextScreenWithCheck := nil;
- BlackScreen := False;
-
- // fade mod
- FadeState := 0;
- FadeEnabled := (Ini.ScreenFade = 1);
- FadeFailed:= false;
-
- glGenTextures(2, @FadeTex);
-
- for i := 1 to 2 do
- begin
- glBindTexture(GL_TEXTURE_2D, FadeTex[i]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- end;
-
- //Set LastError for OSD to No Error
- OSD_LastError := 'No Errors';
-end;
-
-destructor TDisplay.Destroy;
-begin
- glDeleteTextures(2, @FadeTex);
- inherited Destroy;
-end;
-
-function TDisplay.Draw: Boolean;
-var
- S: integer;
- FadeStateSquare: Real;
- currentTime: Cardinal;
- glError: glEnum;
-begin
- Result := True;
-
- glClearColor(1, 1, 1 , 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- for S := 1 to Screens do
- begin
- ScreenAct := S;
-
- //if Screens = 1 then ScreenX := 0;
- //if (Screens = 2) and (S = 1) then ScreenX := -1;
- //if (Screens = 2) and (S = 2) then ScreenX := 1;
- ScreenX := 0;
-
- glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
-
- // popup hack
- // check was successful... move on
- if CheckOK then
- begin
- if assigned(NextScreenWithCheck) then
- begin
- NextScreen := NextScreenWithCheck;
- NextScreenWithCheck := nil;
- CheckOk := False;
- end
- else
- begin
- // on end of game fade to black before exit
- BlackScreen := True;
- end;
- end;
-
- if (not assigned(NextScreen)) and (not BlackScreen) then
- begin
- CurrentScreen.Draw;
-
- //popup mod
- if (ScreenPopupError <> nil) and ScreenPopupError.Visible then
- ScreenPopupError.Draw
- else if (ScreenPopupCheck <> nil) and ScreenPopupCheck.Visible then
- ScreenPopupCheck.Draw;
-
- // fade mod
- FadeState := 0;
- if ((Ini.ScreenFade = 1) and (not FadeFailed)) then
- FadeEnabled := True
- else if (Ini.ScreenFade = 0) then
- FadeEnabled := False;
- end
- else
- begin
- // disable fading if initialization failed
- if (FadeEnabled and FadeFailed) then
- begin
- FadeEnabled := False;
- end;
-
- if (FadeEnabled and not FadeFailed) then
- begin
- //Create Fading texture if we're just starting
- if FadeState = 0 then
- begin
- // save old viewport and resize to fit texture
- glPushAttrib(GL_VIEWPORT_BIT);
- glViewPort(0, 0, 512, 512);
-
- // draw screen that will be faded
- CurrentScreen.Draw;
-
- // clear OpenGL errors, otherwise fading might be disabled due to some
- // older errors in previous OpenGL calls.
- glGetError();
-
- // copy screen to texture
- glBindTexture(GL_TEXTURE_2D, FadeTex[S]);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0);
- glError := glGetError();
- if (glError <> GL_NO_ERROR) then
- begin
- FadeFailed := true;
- Log.LogWarn('Fading disabled: ' + gluErrorString(glError), 'TDisplay.Draw');
- end;
-
- // restore viewport
- glPopAttrib();
-
- // blackscreen-hack
- if not BlackScreen then
- NextScreen.onShow;
-
- // update fade state
- LastFadeTime := SDL_GetTicks();
- if (S = 2) or (Screens = 1) then
- FadeState := FadeState + 1;
- end; // end texture creation in first fading step
-
- //do some time-based fading
- currentTime := SDL_GetTicks();
- if (currentTime > LastFadeTime+30) and (S = 1) then
- begin
- FadeState := FadeState + 4;
- LastFadeTime := currentTime;
- end;
-
- // blackscreen-hack
- if not BlackScreen then
- NextScreen.Draw // draw next screen
- else if ScreenAct = 1 then
- begin
- glClearColor(0, 0, 0 , 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end;
-
- // and draw old screen over it... slowly fading out
-
- FadeStateSquare := (FadeState*FadeState)/10000;
-
- glBindTexture(GL_TEXTURE_2D, FadeTex[S]);
- glColor4f(1, 1, 1, 1-FadeStateSquare);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glTexCoord2f(0+FadeStateSquare, 0+FadeStateSquare); glVertex2f(0, 600);
- glTexCoord2f(0+FadeStateSquare, 1-FadeStateSquare); glVertex2f(0, 0);
- glTexCoord2f(1-FadeStateSquare, 1-FadeStateSquare); glVertex2f(800, 0);
- glTexCoord2f(1-FadeStateSquare, 0+FadeStateSquare); glVertex2f(800, 600);
- glEnd;
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end
- // blackscreen hack
- else if not BlackScreen then
- begin
- NextScreen.OnShow;
- end;
-
- if ((FadeState > 40) or (not FadeEnabled) or FadeFailed) and (S = 1) then
- begin
- // fade out complete...
- FadeState := 0;
- CurrentScreen.onHide;
- CurrentScreen.ShowFinish := False;
- CurrentScreen := NextScreen;
- NextScreen := nil;
- if not BlackScreen then
- begin
- CurrentScreen.onShowFinish;
- CurrentScreen.ShowFinish := true;
- end
- else
- begin
- Result := False;
- Break;
- end;
- end;
- end; // if
-
- //Draw OSD only on first Screen if Debug Mode is enabled
- if ((Ini.Debug = 1) or (Params.Debug)) and (S = 1) then
- DrawDebugInformation;
- end; // for
-end;
-
-procedure TDisplay.SaveScreenShot;
-var
- Num: integer;
- FileName: string;
- ScreenData: PChar;
- Surface: PSDL_Surface;
- Success: boolean;
- Align: integer;
- RowSize: integer;
-begin
- // Exit if Screenshot-path does not exist or read-only
- if (ScreenshotsPath = '') then
- Exit;
-
- for Num := 1 to 9999 do
- begin
- FileName := IntToStr(Num);
- while Length(FileName) < 4 do
- FileName := '0' + FileName;
- FileName := ScreenshotsPath + 'screenshot' + FileName + '.png';
- if not FileExists(FileName) then
- break
- end;
-
- // we must take the row-alignment (4byte by default) into account
- glGetIntegerv(GL_PACK_ALIGNMENT, @Align);
- // calc aligned row-size
- RowSize := ((ScreenW*3 + (Align-1)) div Align) * Align;
-
- GetMem(ScreenData, RowSize * ScreenH);
- glReadPixels(0, 0, ScreenW, ScreenH, GL_RGB, GL_UNSIGNED_BYTE, ScreenData);
- Surface := SDL_CreateRGBSurfaceFrom(
- ScreenData, ScreenW, ScreenH, 24, RowSize,
- $0000FF, $00FF00, $FF0000, 0);
-
- //Success := WriteJPGImage(FileName, Surface, 95);
- //Success := WriteBMPImage(FileName, Surface);
- Success := WritePNGImage(FileName, Surface);
- if Success then
- ScreenPopupError.ShowPopup('Screenshot saved: ' + ExtractFileName(FileName))
- else
- ScreenPopupError.ShowPopup('Screenshot failed');
-
- SDL_FreeSurface(Surface);
- FreeMem(ScreenData);
-end;
-
-//------------
-// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
-//------------
-procedure TDisplay.DrawDebugInformation;
-var Ticks: Cardinal;
-begin
- //Some White Background for information
- glEnable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 0.5);
- glBegin(GL_QUADS);
- glVertex2f(690, 44);
- glVertex2f(690, 0);
- glVertex2f(800, 0);
- glVertex2f(800, 44);
- glEnd;
- glDisable(GL_BLEND);
-
- //Set Font Specs
- SetFontStyle(0);
- SetFontSize(7);
- SetFontItalic(False);
- glColor4f(0, 0, 0, 1);
-
- //Calculate FPS
- Ticks := SDL_GetTicks();
- if (Ticks >= NextFPSSwap) then
- begin
- LastFPS := FPSCounter * 4;
- FPSCounter := 0;
- NextFPSSwap := Ticks + 250;
- end;
-
- Inc(FPSCounter);
-
- //Draw Text
-
- //FPS
- SetFontPos(695, 0);
- glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
-
- //RSpeed
- SetFontPos(695, 13);
- glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
-
- //LastError
- SetFontPos(695, 26);
- glColor4f(1, 0, 0, 1);
- glPrint (PChar(OSD_LastError));
-
- glColor4f(1, 1, 1, 1);
-end;
-
-end.
diff --git a/Game/Code/Menu/UDrawTexture.pas b/Game/Code/Menu/UDrawTexture.pas
deleted file mode 100644
index a7dde18f..00000000
--- a/Game/Code/Menu/UDrawTexture.pas
+++ /dev/null
@@ -1,105 +0,0 @@
-unit UDrawTexture;
-
-interface
-
-{$I switches.inc}
-
-uses UTexture;
-
-procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
-procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
-procedure DrawTexture(Texture: TTexture);
-
-implementation
-
-uses gl;
-
-procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
-begin
- glColor3f(ColR, ColG, ColB);
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glEnd;
-end;
-
-procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
-begin
- glColor3f(ColR, ColG, ColB);
- glBegin(GL_QUADS);
- glVertex2f(x, y);
- glVertex2f(x, y+h);
- glVertex2f(x+w, y+h);
- glVertex2f(x+w, y);
- glEnd;
-end;
-
-procedure DrawTexture(Texture: TTexture);
-var
- x1, x2, x3, x4: real;
- y1, y2, y3, y4: real;
- xt1, xt2, xt3, xt4: real;
- yt1, yt2, yt3, yt4: real;
-begin
- with Texture do begin
- // rysuje paski gracza
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
-// glDepthFunc(GL_GEQUAL);
- glEnable(GL_DEPTH_TEST);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-// glBlendFunc(GL_SRC_COLOR, GL_ZERO);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- x1 := x;
- x2 := x;
- x3 := x+w*scaleW;
- x4 := x+w*scaleW;
- y1 := y;
- y2 := y+h*scaleH;
- y3 := y+h*scaleH;
- y4 := y;
- if Rot <> 0 then begin
- xt1 := x1 - (x + w/2);
- xt2 := x2 - (x + w/2);
- xt3 := x3 - (x + w/2);
- xt4 := x4 - (x + w/2);
- yt1 := y1 - (y + h/2);
- yt2 := y2 - (y + h/2);
- yt3 := y3 - (y + h/2);
- yt4 := y4 - (y + h/2);
-
- x1 := (x + w/2) + xt1 * cos(Rot) - yt1 * sin(Rot);
- x2 := (x + w/2) + xt2 * cos(Rot) - yt2 * sin(Rot);
- x3 := (x + w/2) + xt3 * cos(Rot) - yt3 * sin(Rot);
- x4 := (x + w/2) + xt4 * cos(Rot) - yt4 * sin(Rot);
-
- y1 := (y + h/2) + yt1 * cos(Rot) + xt1 * sin(Rot);
- y2 := (y + h/2) + yt2 * cos(Rot) + xt2 * sin(Rot);
- y3 := (y + h/2) + yt3 * cos(Rot) + xt3 * sin(Rot);
- y4 := (y + h/2) + yt4 * cos(Rot) + xt4 * sin(Rot);
-
- end;
-
-{ glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex3f(x1, y1, z);
- glTexCoord2f(0, TexH); glVertex3f(x2, y2, z);
- glTexCoord2f(TexW, TexH); glVertex3f(x3, y3, z);
- glTexCoord2f(TexW, 0); glVertex3f(x4, y4, z);
- glEnd;}
-
- glBegin(GL_QUADS);
- glTexCoord2f(TexX1*TexW, TexY1*TexH); glVertex3f(x1, y1, z);
- glTexCoord2f(TexX1*TexW, TexY2*TexH); glVertex3f(x2, y2, z);
- glTexCoord2f(TexX2*TexW, TexY2*TexH); glVertex3f(x3, y3, z);
- glTexCoord2f(TexX2*TexW, TexY1*TexH); glVertex3f(x4, y4, z);
- glEnd;
- end;
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_TEXTURE_2D);
-end;
-
-end.
diff --git a/Game/Code/Menu/UMenu.pas b/Game/Code/Menu/UMenu.pas
deleted file mode 100644
index e352febd..00000000
--- a/Game/Code/Menu/UMenu.pas
+++ /dev/null
@@ -1,1432 +0,0 @@
-unit UMenu;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses gl, SysUtils, UTexture, UMenuStatic, UMenuText, UMenuButton, UMenuSelectSlide,
- UMenuInteract, UThemes, UMenuButtonCollection, Math, UMusic;
-
-type
-{ Int16 = SmallInt;}
-
- PMenu = ^TMenu;
- TMenu = class
- protected
- ButtonPos: Integer;
-
- Interactions: array of TInteract;
- SelInteraction: integer;
- Button: array of TButton;
- SelectsS: array of TSelectSlide;
- ButtonCollection: array of TButtonCollection;
- BackImg: TTexture;
- BackW: integer;
- BackH: integer;
-
- fFileName : string;
- public
- Text: array of TText;
- Static: array of TStatic;
- mX: integer; // mouse X
- mY: integer; // mouse Y
-
- Fade: integer; // fade type
- ShowFinish: boolean; // true if there is no fade
-
-
- destructor Destroy; override;
- constructor Create; overload; virtual;
- //constructor Create(Back: string); overload; virtual; // Back is a JPG resource name for background
- //constructor Create(Back: string; W, H: integer); overload; virtual; // W and H are the number of overlaps
-
- // interaction
- function WideCharUpperCase(wchar: WideChar) : WideString;
- function WideStringUpperCase(wstring: WideString) : WideString;
- procedure AddInteraction(Typ, Num: integer);
- procedure SetInteraction(Num: integer);
- property Interaction: integer read SelInteraction write SetInteraction;
-
- //Procedure Load BG, Texts, Statics and Button Collections from ThemeBasic
- procedure LoadFromTheme(const ThemeBasic: TThemeBasic);
-
- procedure PrepareButtonCollections(const Collections: AThemeButtonCollection);
- procedure AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
-
- // background
- procedure AddBackground(Name: string);
-
- // static
- function AddStatic(ThemeStatic: TThemeStatic): integer; overload;
- function AddStatic(X, Y, W, H: real; const Name: string): integer; overload;
- function AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer; overload;
- function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload;
- function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload;
- function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload;
- function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload;
- function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: Boolean; ReflectionSpacing: Real): integer; overload;
-
- // text
- function AddText(ThemeText: TThemeText): integer; overload;
- function AddText(X, Y: real; const Text_: string): integer; overload;
- function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer; overload;
- function AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: Boolean; ReflectionSpacing_: Real; Z : Real): integer; overload;
-
- // button
- Procedure SetButtonLength(Length: Cardinal); //Function that Set Length of Button Array in one Step instead of register new Memory for every Button
- function AddButton(ThemeButton: TThemeButton): integer; overload;
- function AddButton(X, Y, W, H: real; const Name: String): integer; overload;
- function AddButton(X, Y, W, H: real; const Name: String; Typ: TTextureType; Reflection: Boolean): integer; overload;
- function AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; const Name: String; Typ: TTextureType; Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer; overload;
- procedure ClearButtons;
- procedure AddButtonText(AddX, AddY: real; const AddText: string); overload;
- procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string); overload;
- procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload;
- procedure AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload;
-
- // select slide
- function AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer; overload;
- function AddSelectSlide(X, Y, W, H, SkipX, SBGW, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
- TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
- SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
- STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
- const Name: String; Typ: TTextureType; const SBGName: String; SBGTyp: TTextureType;
- const Caption: string; var Data: integer): integer; overload;
- procedure AddSelectSlideOption(const AddText: string); overload;
- procedure AddSelectSlideOption(SelectNo: Cardinal; const AddText: string); overload;
- procedure UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
-
-// function AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
-// procedure ClearWidgets(MinNumber : Int16);
- procedure FadeTo(Screen: PMenu); overload;
- procedure FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream); overload;
- //popup hack
- procedure CheckFadeTo(Screen: PMenu; msg: String);
-
- function DrawBG: boolean; virtual;
- function DrawFG: boolean; virtual;
- function Draw: boolean; virtual;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown : Boolean): Boolean; virtual;
- // FIXME: ParseMouse is not implemented in any subclass and not even used anywhere in the code
- // -> do this before activation of this method
- //function ParseMouse(Typ: integer; X: integer; Y: integer): Boolean; virtual; abstract;
- procedure onShow; virtual;
- procedure onShowFinish; virtual;
- procedure onHide; virtual;
-
- procedure SetAnimationProgress(Progress: real); virtual;
-
- function IsSelectable(Int: Cardinal): Boolean;
-
- procedure InteractNext; virtual;
- procedure InteractCustom(CustomSwitch: integer); virtual;
- procedure InteractPrev; virtual;
- procedure InteractInc; virtual;
- procedure InteractDec; virtual;
- procedure InteractNextRow; virtual; // this is for the options screen, so button down makes sense
- procedure InteractPrevRow; virtual; // this is for the options screen, so button up makes sense
- procedure AddBox(X, Y, W, H: real);
- end;
-
-const
- pmMove = 1;
- pmClick = 2;
- pmUnClick = 3;
-
- iButton = 0; // interaction type
- iText = 2;
- iSelectS = 3;
- iBCollectionChild = 5;
-
-// fBlack = 0; // fade type
-// fWhite = 1;
-
-implementation
-
-uses UCommon,
- ULog,
- UMain,
- UDrawTexture,
- UGraphic,
- UDisplay,
- UCovers,
- UTime,
- USkins;
-
-destructor TMenu.Destroy;
-begin
- inherited;
-end;
-
-constructor TMenu.Create;
-begin
- inherited;
-
- Fade := 0;//fWhite;
-
- SetLength(Static, 0);
- SetLength(Button, 0);
-
- BackImg.TexNum := 0;
-
- //Set ButtonPos to Autoset Length
- ButtonPos := -1;
-end;
-{
-constructor TMenu.Create(Back: String);
-begin
- inherited Create;
-
- if Back <> '' then begin
-// BackImg := Texture.GetTexture(true, Back, TEXTURE_TYPE_PLAIN, 0);
- BackImg := Texture.GetTexture(Back, TEXTURE_TYPE_PLAIN, 0); // new theme system
- BackImg.W := 800;//640;
- BackImg.H := 600;//480;
- BackW := 1;
- BackH := 1;
- end else
- BackImg.TexNum := 0;
-
- //Set ButtonPos to Autoset Length
- ButtonPos := -1;
-end;
-
-constructor TMenu.Create(Back: string; W, H: integer);
-begin
- Create(Back);
- BackImg.W := BackImg.W / W;
- BackImg.H := BackImg.H / H;
- BackW := W;
- BackH := H;
-end; }
-
-function RGBFloatToInt(R, G, B: Double): Cardinal;
-begin
- Result := (Trunc(255 * R) shl 16) or
- (Trunc(255 * G) shl 8) or
- Trunc(255 * B);
-end;
-
-procedure TMenu.AddInteraction(Typ, Num: integer);
-var
- IntNum: integer;
-begin
- IntNum := Length(Interactions);
- SetLength(Interactions, IntNum+1);
- Interactions[IntNum].Typ := Typ;
- Interactions[IntNum].Num := Num;
- Interaction := 0;
-end;
-
-procedure TMenu.SetInteraction(Num: integer);
-var
- OldNum, OldTyp: integer;
- NewNum, NewTyp: integer;
-begin
- // set inactive
- OldNum := Interactions[Interaction].Num;
- OldTyp := Interactions[Interaction].Typ;
-
- NewNum := Interactions[Num].Num;
- NewTyp := Interactions[Num].Typ;
-
- case OldTyp of
- iButton: Button[OldNum].Selected := False;
- iText: Text[OldNum].Selected := False;
- iSelectS: SelectsS[OldNum].Selected := False;
- //Button Collection Mod
- iBCollectionChild:
- begin
- Button[OldNum].Selected := False;
-
- //Deselect Collection if Next Button is Not from Collection
- if (NewTyp <> iButton) Or (Button[NewNum].Parent <> Button[OldNum].Parent) then
- ButtonCollection[Button[OldNum].Parent-1].Selected := False;
- end;
- end;
-
- // set active
- SelInteraction := Num;
- case NewTyp of
- iButton: Button[NewNum].Selected := True;
- iText: Text[NewNum].Selected := True;
- iSelectS: SelectsS[NewNum].Selected := True;
-
- //Button Collection Mod
- iBCollectionChild:
- begin
- Button[NewNum].Selected := True;
- ButtonCollection[Button[NewNum].Parent-1].Selected := True;
- end;
- end;
-end;
-
-//----------------------
-//LoadFromTheme - Load BG, Texts, Statics and
-//Button Collections from ThemeBasic
-//----------------------
-procedure TMenu.LoadFromTheme(const ThemeBasic: TThemeBasic);
-var
- I: Integer;
-begin
- //Add Button Collections (Set Button CollectionsLength)
- //Button Collections are Created when the first ChildButton is Created
- PrepareButtonCollections(ThemeBasic.ButtonCollection);
-
- //Add Background
- AddBackground(ThemeBasic.Background.Tex);
-
- //Add Statics and Texts
- for I := 0 to High(ThemeBasic.Static) do
- AddStatic(ThemeBasic.Static[I]);
-
- for I := 0 to High(ThemeBasic.Text) do
- AddText(ThemeBasic.Text[I]);
-end;
-
-procedure TMenu.AddBackground(Name: string);
-//var
-// lFileName : string;
-begin
- if Name <> '' then
- begin
- fFileName := Skin.GetTextureFileName(Name);
- fFileName := AdaptFilePaths( fFileName );
-
- if fileexists( fFileName ) then
- begin
- BackImg := Texture.GetTexture( fFileName , TEXTURE_TYPE_PLAIN);
-
- if ( BackImg.TexNum = 0 ) then
- begin
- if VideoPlayback.Open( fFileName ) then
- begin
- VideoBGTimer.SetTime(0);
- VideoPlayback.Play;
- end;
- end;
-
- BackImg.W := 800;
- BackImg.H := 600;
- BackW := 1;
- BackH := 1;
- end;
- end;
-end;
-
-//----------------------
-//PrepareButtonCollections:
-//Add Button Collections (Set Button CollectionsLength)
-//----------------------
-procedure TMenu.PrepareButtonCollections(const Collections: AThemeButtonCollection);
-var
- I: Integer;
-begin
- SetLength(ButtonCollection, Length(Collections));
- For I := 0 to High(ButtonCollection) do
- AddButtonCollection(Collections[I], I);
-end;
-
-//----------------------
-//AddButtonCollection:
-//Create a Button Collection;
-//----------------------
-procedure TMenu.AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
-var
- BT, BTLen: Integer;
- TempCol, TempDCol: Cardinal;
-
-begin
- if (Num > High(ButtonCollection)) then
- exit;
-
- TempCol := 0;
-
- // colorize hack
- if (ThemeCollection.Style.Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- TempCol := RGBFloatToInt(ThemeCollection.Style.ColR, ThemeCollection.Style.ColG, ThemeCollection.Style.ColB);
- TempDCol := RGBFloatToInt(ThemeCollection.Style.DColR, ThemeCollection.Style.DColG, ThemeCollection.Style.DColB);
- // give encoded color to GetTexture()
- ButtonCollection[Num] := TButtonCollection.Create(
- Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempCol),
- Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempDCol));
- end
- else
- begin
- ButtonCollection[Num] := TButtonCollection.Create(Texture.GetTexture(
- Skin.GetTextureFileName(ThemeCollection.Style.Tex), ThemeCollection.Style.Typ));
- end;
-
- //Set Parent menu
- ButtonCollection[Num].ScreenButton := @Self.Button;
-
- //Set Attributes
- ButtonCollection[Num].FirstChild := ThemeCollection.FirstChild;
- ButtonCollection[Num].CountChilds := ThemeCollection.ChildCount;
- ButtonCollection[Num].Parent := Num + 1;
-
- //Set Style
- ButtonCollection[Num].X := ThemeCollection.Style.X;
- ButtonCollection[Num].Y := ThemeCollection.Style.Y;
- ButtonCollection[Num].W := ThemeCollection.Style.W;
- ButtonCollection[Num].H := ThemeCollection.Style.H;
- if (ThemeCollection.Style.Typ <> TEXTURE_TYPE_COLORIZED) then begin
- ButtonCollection[Num].SelectColR := ThemeCollection.Style.ColR;
- ButtonCollection[Num].SelectColG := ThemeCollection.Style.ColG;
- ButtonCollection[Num].SelectColB := ThemeCollection.Style.ColB;
- ButtonCollection[Num].DeselectColR := ThemeCollection.Style.DColR;
- ButtonCollection[Num].DeselectColG := ThemeCollection.Style.DColG;
- ButtonCollection[Num].DeselectColB := ThemeCollection.Style.DColB;
- end;
- ButtonCollection[Num].SelectInt := ThemeCollection.Style.Int;
- ButtonCollection[Num].DeselectInt := ThemeCollection.Style.DInt;
- ButtonCollection[Num].Texture.TexX1 := 0;
- ButtonCollection[Num].Texture.TexY1 := 0;
- ButtonCollection[Num].Texture.TexX2 := 1;
- ButtonCollection[Num].Texture.TexY2 := 1;
- ButtonCollection[Num].SetSelect(false);
-
- ButtonCollection[Num].Reflection := ThemeCollection.Style.Reflection;
- ButtonCollection[Num].Reflectionspacing := ThemeCollection.Style.ReflectionSpacing;
- ButtonCollection[Num].DeSelectReflectionspacing := ThemeCollection.Style.DeSelectReflectionSpacing;
-
- ButtonCollection[Num].Z := ThemeCollection.Style.Z;
-
- //Some Things from ButtonFading
- ButtonCollection[Num].SelectH := ThemeCollection.Style.SelectH;
- ButtonCollection[Num].SelectW := ThemeCollection.Style.SelectW;
-
- ButtonCollection[Num].Fade := ThemeCollection.Style.Fade;
- ButtonCollection[Num].FadeText := ThemeCollection.Style.FadeText;
- if (ThemeCollection.Style.Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- ButtonCollection[Num].FadeTex := Texture.GetTexture(
- Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), TEXTURE_TYPE_COLORIZED, TempCol)
- end else begin
- ButtonCollection[Num].FadeTex := Texture.GetTexture(
- Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), ThemeCollection.Style.Typ);
- end;
- ButtonCollection[Num].FadeTexPos := ThemeCollection.Style.FadeTexPos;
-
-
- BTLen := Length(ThemeCollection.Style.Text);
- for BT := 0 to BTLen-1 do begin
- AddButtonText(ButtonCollection[Num], ThemeCollection.Style.Text[BT].X, ThemeCollection.Style.Text[BT].Y,
- ThemeCollection.Style.Text[BT].ColR, ThemeCollection.Style.Text[BT].ColG, ThemeCollection.Style.Text[BT].ColB,
- ThemeCollection.Style.Text[BT].Font, ThemeCollection.Style.Text[BT].Size, ThemeCollection.Style.Text[BT].Align,
- ThemeCollection.Style.Text[BT].Text);
- end;
-end;
-
-function TMenu.AddStatic(ThemeStatic: TThemeStatic): integer;
-begin
- Result := AddStatic(ThemeStatic.X, ThemeStatic.Y, ThemeStatic.W, ThemeStatic.H, ThemeStatic.Z,
- ThemeStatic.ColR, ThemeStatic.ColG, ThemeStatic.ColB,
- ThemeStatic.TexX1, ThemeStatic.TexY1, ThemeStatic.TexX2, ThemeStatic.TexY2,
- Skin.GetTextureFileName(ThemeStatic.Tex),
- ThemeStatic.Typ, $FFFFFF, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing);
-end;
-
-function TMenu.AddStatic(X, Y, W, H: real; const Name: string): integer;
-begin
- Result := AddStatic(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN);
-end;
-
-function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer;
-begin
- Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, Name, Typ, $FFFFFF);
-end;
-
-function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer;
-begin
- Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, Name, Typ, $FFFFFF);
-end;
-
-function TMenu.AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer;
-var
- StatNum: integer;
-begin
- // adds static
- StatNum := Length(Static);
- SetLength(Static, StatNum + 1);
- Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, $FF00FF)); // new skin
-
- // configures static
- Static[StatNum].Texture.X := X;
- Static[StatNum].Texture.Y := Y;
- Static[StatNum].Texture.W := W;
- Static[StatNum].Texture.H := H;
- Static[StatNum].Visible := true;
- Result := StatNum;
-end;
-
-function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer;
-begin
- Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, Name, Typ, Color);
-end;
-
-function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer;
-begin
- Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, 0, 0, 1, 1, Name, Typ, Color, False, 0);
-end;
-
-function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: Boolean; ReflectionSpacing: Real): integer;
-var
- StatNum: integer;
-begin
- // adds static
- StatNum := Length(Static);
- SetLength(Static, StatNum + 1);
-
- // colorize hack
- if (Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- // give encoded color to GetTexture()
- Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)));
- end
- else
- begin
- Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, Color)); // new skin
- end;
-
- // configures static
- Static[StatNum].Texture.X := X;
- Static[StatNum].Texture.Y := Y;
- Static[StatNum].Texture.W := W;
- Static[StatNum].Texture.H := H;
- Static[StatNum].Texture.Z := Z;
- if (Typ <> TEXTURE_TYPE_COLORIZED) then
- begin
- Static[StatNum].Texture.ColR := ColR;
- Static[StatNum].Texture.ColG := ColG;
- Static[StatNum].Texture.ColB := ColB;
- end;
- Static[StatNum].Texture.TexX1 := TexX1;
- Static[StatNum].Texture.TexY1 := TexY1;
- Static[StatNum].Texture.TexX2 := TexX2;
- Static[StatNum].Texture.TexY2 := TexY2;
- Static[StatNum].Texture.Alpha := 1;
- Static[StatNum].Visible := true;
-
- //ReflectionMod
- Static[StatNum].Reflection := Reflection;
- Static[StatNum].ReflectionSpacing := ReflectionSpacing;
-
- Result := StatNum;
-end;
-
-function TMenu.AddText(ThemeText: TThemeText): integer;
-begin
- Result := AddText(ThemeText.X, ThemeText.Y, ThemeText.W, ThemeText.Font, ThemeText.Size,
- ThemeText.ColR, ThemeText.ColG, ThemeText.ColB, ThemeText.Align, ThemeText.Text, ThemeText.Reflection, ThemeText.ReflectionSpacing, ThemeText.Z);
-end;
-
-function TMenu.AddText(X, Y: real; const Text_: string): integer;
-var
- TextNum: integer;
-begin
- // adds text
- TextNum := Length(Text);
- SetLength(Text, TextNum + 1);
- Text[TextNum] := TText.Create(X, Y, Text_);
- Result := TextNum;
-end;
-
-function TMenu.AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer;
-begin
- Result := AddText(X, Y, 0, Style, Size, ColR, ColG, ColB, 0, Text, false, 0, 0);
-end;
-
-function TMenu.AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: Boolean; ReflectionSpacing_: Real; Z : Real): integer;
-var
- TextNum: integer;
-begin
- // adds text
- TextNum := Length(Text);
- SetLength(Text, TextNum + 1);
- Text[TextNum] := TText.Create(X, Y, W, Style, Size, ColR, ColG, ColB, Align, Text_, Reflection_, ReflectionSpacing_, Z);
- Result := TextNum;
-end;
-
-//Function that Set Length of Button Array in one Step instead of register new Memory for every Button
-Procedure TMenu.SetButtonLength(Length: Cardinal);
-begin
- if (ButtonPos = -1) AND (Length > 0) then
- begin
- //Set Length of Button
- SetLength(Button, Length);
-
- //Set ButtonPos to start with 0
- ButtonPos := 0;
- end;
-end;
-
-
-// Method to add a button in our TMenu. It returns the assigned ButtonNumber
-function TMenu.AddButton(ThemeButton: TThemeButton): integer;
-var
- BT: integer;
- BTLen: integer;
-begin
- Result := AddButton(ThemeButton.X, ThemeButton.Y, ThemeButton.W, ThemeButton.H,
- ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB, ThemeButton.Int,
- ThemeButton.DColR, ThemeButton.DColG, ThemeButton.DColB, ThemeButton.DInt,
- Skin.GetTextureFileName(ThemeButton.Tex), ThemeButton.Typ,
- ThemeButton.Reflection, ThemeButton.Reflectionspacing, ThemeButton.DeSelectReflectionspacing);
-
- Button[Result].Z := ThemeButton.Z;
-
- //Button Visibility
- Button[Result].Visible := ThemeButton.Visible;
-
- //Some Things from ButtonFading
- Button[Result].SelectH := ThemeButton.SelectH;
- Button[Result].SelectW := ThemeButton.SelectW;
-
- Button[Result].Fade := ThemeButton.Fade;
- Button[Result].FadeText := ThemeButton.FadeText;
- if (ThemeButton.Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- Button[Result].FadeTex := Texture.GetTexture(
- Skin.GetTextureFileName(ThemeButton.FadeTex), TEXTURE_TYPE_COLORIZED,
- RGBFloatToInt(ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB));
- end
- else
- begin
- Button[Result].FadeTex := Texture.GetTexture(
- Skin.GetTextureFileName(ThemeButton.FadeTex), ThemeButton.Typ);
- end;
-
- Button[Result].FadeTexPos := ThemeButton.FadeTexPos;
-
- BTLen := Length(ThemeButton.Text);
- for BT := 0 to BTLen-1 do
- begin
- AddButtonText(ThemeButton.Text[BT].X, ThemeButton.Text[BT].Y,
- ThemeButton.Text[BT].ColR, ThemeButton.Text[BT].ColG, ThemeButton.Text[BT].ColB,
- ThemeButton.Text[BT].Font, ThemeButton.Text[BT].Size, ThemeButton.Text[BT].Align,
- ThemeButton.Text[BT].Text);
- end;
-
- //BAutton Collection Mod
- if (ThemeButton.Parent <> 0) then
- begin
- //If Collection Exists then Change Interaction to Child Button
- if (@ButtonCollection[ThemeButton.Parent-1] <> nil) then
- begin
- Interactions[High(Interactions)].Typ := iBCollectionChild;
- Button[Result].Visible := False;
-
- for BT := 0 to BTLen-1 do
- Button[Result].Text[BT].Alpha := 0;
-
- Button[Result].Parent := ThemeButton.Parent;
- if (ButtonCollection[ThemeButton.Parent-1].Fade) then
- Button[Result].Texture.Alpha := 0;
- end;
- end;
- Log.BenchmarkEnd(6);
- Log.LogBenchmark('====> Screen Options32', 6);
-end;
-
-function TMenu.AddButton(X, Y, W, H: real; const Name: String): integer;
-begin
- Result := AddButton(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN, False);
-end;
-
-function TMenu.AddButton(X, Y, W, H: real; const Name: String; Typ: TTextureType; Reflection: Boolean): integer;
-begin
- Result := AddButton(X, Y, W, H, 1, 1, 1, 1, 1, 1, 1, 0.5, Name, TEXTURE_TYPE_PLAIN, Reflection, 15, 15);
-end;
-
-function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real;
- const Name: String; Typ: TTextureType;
- Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer;
-begin
- // adds button
- //SetLength is used once to reduce Memory usement
- if (ButtonPos <> -1) then
- begin
- Result := ButtonPos;
- Inc(ButtonPos)
- end
- else //Old Method -> Reserve new Memory for every Button
- begin
- Result := Length(Button);
- SetLength(Button, Result + 1);
- end;
-
- // colorize hack
- if (Typ = TEXTURE_TYPE_COLORIZED) then
- begin
- // give encoded color to GetTexture()
- Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)),
- Texture.GetTexture(Name, Typ, RGBFloatToInt(DColR, DColG, DColB)));
- end
- else
- begin
- Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ));
- end;
-
- // configures button
- Button[Result].X := X;
- Button[Result].Y := Y;
- Button[Result].W := W;
- Button[Result].H := H;
- if (Typ <> TEXTURE_TYPE_COLORIZED) then
- begin
- Button[Result].SelectColR := ColR;
- Button[Result].SelectColG := ColG;
- Button[Result].SelectColB := ColB;
- Button[Result].DeselectColR := DColR;
- Button[Result].DeselectColG := DColG;
- Button[Result].DeselectColB := DColB;
- end;
- Button[Result].SelectInt := Int;
- Button[Result].DeselectInt := DInt;
- Button[Result].Texture.TexX1 := 0;
- Button[Result].Texture.TexY1 := 0;
- Button[Result].Texture.TexX2 := 1;
- Button[Result].Texture.TexY2 := 1;
- Button[Result].SetSelect(false);
-
- Button[Result].Reflection := Reflection;
- Button[Result].Reflectionspacing := ReflectionSpacing;
- Button[Result].DeSelectReflectionspacing := DeSelectReflectionSpacing;
-
- //Button Collection Mod
- Button[Result].Parent := 0;
-
-
- // adds interaction
- AddInteraction(iButton, Result);
- Interaction := 0;
-end;
-
-procedure TMenu.ClearButtons;
-begin
- Setlength(Button, 0);
-end;
-
-// Method to draw our TMenu and all his child buttons
-function TMenu.DrawBG: boolean;
-begin
- BackImg.ColR := 1;
- BackImg.ColG := 1;
- BackImg.ColB := 1;
- BackImg.TexX1 := 0;
- BackImg.TexY1 := 0;
- BackImg.TexX2 := 1;
- BackImg.TexY2 := 1;
-
- if (BackImg.TexNum > 0) then
- begin
- BackImg.X := 0;
- BackImg.Y := 0;
- BackImg.Z := 0; // todo: eddie: to the opengl experts: please check this! On the mac z is not initialized???
- BackImg.W := 800;
- BackImg.H := 600;
- DrawTexture(BackImg);
- end
- else if (VideoPlayback <> nil) then
- begin
- VideoPlayback.GetFrame(VideoBGTimer.GetTime());
- // FIXME: why do we draw on screen 2? Seems to be wrong.
- VideoPlayback.DrawGL(2);
- end;
-
- Result := true;
-end;
-
-function TMenu.DrawFG: boolean;
-var
- J: Integer;
-begin
- // We don't forget about newly implemented static for nice skin ...
- for J := 0 to Length(Static) - 1 do
- Static[J].Draw;
-
- // ... and slightly implemented menutext unit
- for J := 0 to Length(Text) - 1 do
- Text[J].Draw;
-
- // Draw all ButtonCollections
- for J := 0 to High(ButtonCollection) do
- ButtonCollection[J].Draw;
-
- // Second, we draw all of our buttons
- for J := 0 to Length(Button) - 1 do
- Button[J].Draw;
-
- for J := 0 to Length(SelectsS) - 1 do
- SelectsS[J].Draw;
-
- // Third, we draw all our widgets
- // for J := 0 to Length(WidgetsSrc) - 1 do
- // SDL_BlitSurface(WidgetsSrc[J], nil, ParentBackBuf, WidgetsRect[J]);
- Result := True;
-end;
-
-function TMenu.Draw: boolean;
-begin
- DrawBG;
- DrawFG;
- Result := true;
-end;
-
-{
-function TMenu.GetNextScreen(): PMenu;
-begin
- Result := NextScreen;
-end;
-}
-
-{
-function TMenu.AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
-var
- WidgetNum : Int16;
-begin
- if (Assigned(WidgetSrc)) then
- begin
- WidgetNum := Length(WidgetsSrc);
-
- SetLength(WidgetsSrc, WidgetNum + 1);
- SetLength(WidgetsRect, WidgetNum + 1);
-
- WidgetsSrc[WidgetNum] := WidgetSrc;
- WidgetsRect[WidgetNum] := new(PSDL_Rect);
- WidgetsRect[WidgetNum]^.x := X;
- WidgetsRect[WidgetNum]^.y := Y;
- WidgetsRect[WidgetNum]^.w := WidgetSrc^.w;
- WidgetsRect[WidgetNum]^.h := WidgetSrc^.h;
-
- Result := WidgetNum;
- end
- else
- Result := -1;
-end;
-}
-
-{
-procedure TMenu.ClearWidgets(MinNumber : Int16);
-var
- J : Int16;
-begin
- for J := MinNumber to (Length(WidgetsSrc) - 1) do
- begin
- SDL_FreeSurface(WidgetsSrc[J]);
- dispose(WidgetsRect[J]);
- end;
-
- SetLength(WidgetsSrc, MinNumber);
- SetLength(WidgetsRect, MinNumber);
-end;
-}
-
-function TMenu.IsSelectable(Int: Cardinal): Boolean;
-begin
- Result := True;
- case Interactions[Int].Typ of
- //Button
- iButton: Result := Button[Interactions[Int].Num].Visible and Button[Interactions[Int].Num].Selectable;
-
- //Select Slide
- iSelectS: Result := SelectsS[Interactions[Int].Num].Visible;
-
- //ButtonCollection Child
- iBCollectionChild:
- Result := (ButtonCollection[Button[Interactions[Int].Num].Parent - 1].FirstChild - 1 = Int) and ((Interactions[Interaction].Typ <> iBCollectionChild) or (Button[Interactions[Interaction].Num].Parent <> Button[Interactions[Int].Num].Parent));
- end;
-end;
-
-// implemented for the sake of usablility
-// [curser down] picks the button left to the actual atm
-// this behaviour doesn't make sense for two rows of buttons
-procedure TMenu.InteractPrevRow;
-var
- Int: integer;
-begin
-// these two procedures just make sense for at least 5 buttons, because we
-// usually start a second row when there are more than 4 buttons
- Int := Interaction;
-
- Int := Int - ceil(Length(Interactions) / 2);
-
- //Set Interaction
- if ((Int < 0) or (Int > Length(Interactions) - 1))
- then Int := Interaction //nonvalid button, keep current one
- else Interaction := Int; //select row above
-end;
-
-procedure TMenu.InteractNextRow;
-var
- Int: integer;
-begin
- Int := Interaction;
-
- Int := Int + ceil(Length(Interactions) / 2);
-
- //Set Interaction
- if ((Int < 0) or (Int > Length(Interactions) - 1))
- then Int := Interaction //nonvalid button, keep current one
- else Interaction := Int; //select row above
-end;
-
-procedure TMenu.InteractNext;
-var
- Int: integer;
-begin
- Int := Interaction;
-
- // change interaction as long as it's needed
- repeat
- Int := (Int + 1) mod Length(Interactions);
-
- //If no Interaction is Selectable Simply Select Next
- if (Int = Interaction) then Break;
-
- until IsSelectable(Int);
-
- //Set Interaction
- Interaction := Int;
-end;
-
-procedure TMenu.InteractPrev;
-var
- Int: integer;
-begin
- Int := Interaction;
-
- // change interaction as long as it's needed
- repeat
- Int := Int - 1;
- if Int = -1 then Int := High(Interactions);
-
- //If no Interaction is Selectable Simply Select Next
- if (Int = Interaction) then Break;
- until IsSelectable(Int);
-
- //Set Interaction
- Interaction := Int
-end;
-
-
-procedure TMenu.InteractCustom(CustomSwitch: integer);
-{ needed only for below
-var
- Num: integer;
- Typ: integer;
- Again: boolean;
-}
-begin
- //Code Commented atm, because it needs to be Rewritten
- //it doesn't work with Button Collections
- {then begin
- CustomSwitch:= CustomSwitch*(-1);
- Again := true;
- // change interaction as long as it's needed
- while (Again = true) do begin
- Num := SelInteraction - CustomSwitch;
- if Num = -1 then Num := High(Interactions);
- Interaction := Num;
- Again := false; // reset, default to accept changing interaction
-
- // checking newly interacted element
- Num := Interactions[Interaction].Num;
- Typ := Interactions[Interaction].Typ;
- case Typ of
- iButton:
- begin
- if Button[Num].Selectable = false then Again := True;
- end;
- end; // case
- end; // while
- end
- else if num>0 then begin
- Again := true;
- // change interaction as long as it's needed
- while (Again = true) do begin
- Num := (Interaction + CustomSwitch) Mod Length(Interactions);
- Interaction := Num;
- Again := false; // reset, default to accept changing interaction
-
-
- // checking newly interacted element
- Num := Interactions[Interaction].Num;
- Typ := Interactions[Interaction].Typ;
- case Typ of
- iButton:
- begin
- if Button[Num].Selectable = false then Again := True;
- end;
- end; // case
- end; // while
- end }
-end;
-
-
-procedure TMenu.FadeTo(Screen: PMenu);
-begin
- Display.Fade := 0;
- Display.NextScreen := Screen;
-end;
-
-procedure TMenu.FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream);
-begin
- FadeTo( Screen );
- AudioPlayback.PlaySound( aSound );
-end;
-
-
-//popup hack
-procedure TMenu.CheckFadeTo(Screen: PMenu; msg: String);
-begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := Screen;
- Display.CheckOK:=False;
- ScreenPopupCheck.ShowPopup(msg);
-end;
-
-procedure TMenu.AddButtonText(AddX, AddY: real; const AddText: string);
-begin
- AddButtonText(AddX, AddY, 1, 1, 1, AddText);
-end;
-
-procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string);
-var
- Il: integer;
-begin
- with Button[High(Button)] do begin
- Il := Length(Text);
- SetLength(Text, Il+1);
- Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
- Text[Il].ColR := ColR;
- Text[Il].ColG := ColG;
- Text[Il].ColB := ColB;
- Text[Il].Int := 1;//0.5;
- end;
-end;
-
-procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string);
-var
- Il: integer;
-begin
- with Button[High(Button)] do begin
- Il := Length(Text);
- SetLength(Text, Il+1);
- Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
- Text[Il].ColR := ColR;
- Text[Il].ColG := ColG;
- Text[Il].ColB := ColB;
- Text[Il].Int := 1;//0.5;
- Text[Il].Style := Font;
- Text[Il].Size := Size;
- Text[Il].Align := Align;
- end;
-end;
-
-procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string);
-var
- Il: integer;
-begin
- with CustomButton do begin
- Il := Length(Text);
- SetLength(Text, Il+1);
- Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
- Text[Il].ColR := ColR;
- Text[Il].ColG := ColG;
- Text[Il].ColB := ColB;
- Text[Il].Int := 1;//0.5;
- Text[Il].Style := Font;
- Text[Il].Size := Size;
- Text[Il].Align := Align;
- end;
-end;
-
-
-function TMenu.AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer;
-var
- SO: integer;
-begin
- Result := AddSelectSlide(ThemeSelectS.X, ThemeSelectS.Y, ThemeSelectS.W, ThemeSelectS.H, ThemeSelectS.SkipX, ThemeSelectS.SBGW,
- ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeSelectS.Int,
- ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeSelectS.DInt,
- ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeSelectS.TInt,
- ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeSelectS.TDInt,
- ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeSelectS.SBGInt,
- ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeSelectS.SBGDInt,
- ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeSelectS.STInt,
- ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeSelectS.STDInt,
- Skin.GetTextureFileName(ThemeSelectS.Tex), TEXTURE_TYPE_COLORIZED,
- Skin.GetTextureFileName(ThemeSelectS.TexSBG), TEXTURE_TYPE_COLORIZED,
- ThemeSelectS.Text, Data);
- for SO := 0 to High(Values) do
- AddSelectSlideOption(Values[SO]);
-
- SelectsS[High(SelectsS)].Text.Size := ThemeSelectS.TextSize;
-
- SelectsS[High(SelectsS)].Texture.Z := ThemeSelectS.Z;
- SelectsS[High(SelectsS)].TextureSBG.Z := ThemeSelectS.Z;
-
- //Generate Lines
- SelectsS[High(SelectsS)].GenLines;
-
- SelectsS[High(SelectsS)].SelectedOption := SelectsS[High(SelectsS)].SelectOptInt; // refresh
-end;
-
-function TMenu.AddSelectSlide(X, Y, W, H, SkipX, SBGW, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
- TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
- SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
- STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
- const Name: String; Typ: TTextureType; const SBGName: String; SBGTyp: TTextureType;
- const Caption: string; var Data: integer): integer;
-var
- S: integer;
- I: integer;
-begin
- S := Length(SelectsS);
- SetLength(SelectsS, S + 1);
- SelectsS[S] := TSelectSlide.Create;
-
- if (Typ = TEXTURE_TYPE_COLORIZED) then
- SelectsS[S].Texture := Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB))
- else
- SelectsS[S].Texture := Texture.GetTexture(Name, Typ);
- SelectsS[S].X := X;
- SelectsS[S].Y := Y;
- SelectsS[S].W := W;
- SelectsS[S].H := H;
-
- SelectsS[S].ColR := ColR;
- SelectsS[S].ColG := ColG;
- SelectsS[S].ColB := ColB;
- SelectsS[S].Int := Int;
- SelectsS[S].DColR := DColR;
- SelectsS[S].DColG := DColG;
- SelectsS[S].DColB := DColB;
- SelectsS[S].DInt := DInt;
-
- if (SBGTyp = TEXTURE_TYPE_COLORIZED) then
- SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGColR, SBGColG, SBGColB))
- else
- SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp);
- SelectsS[S].TextureSBG.X := X + W + SkipX;
- SelectsS[S].TextureSBG.Y := Y;
- //SelectsS[S].TextureSBG.W := 450;
- SelectsS[S].SBGW := SBGW;
- SelectsS[S].TextureSBG.H := H;
- SelectsS[S].SBGColR := SBGColR;
- SelectsS[S].SBGColG := SBGColG;
- SelectsS[S].SBGColB := SBGColB;
- SelectsS[S].SBGInt := SBGInt;
- SelectsS[S].SBGDColR := SBGDColR;
- SelectsS[S].SBGDColG := SBGDColG;
- SelectsS[S].SBGDColB := SBGDColB;
- SelectsS[S].SBGDInt := SBGDInt;
-
- SelectsS[S].Text.X := X + 20;
- SelectsS[S].Text.Y := Y + (SelectsS[S].TextureSBG.H / 2) - 15;
- SelectsS[S].Text.Text := Caption;
- SelectsS[S].Text.Size := 10;
- SelectsS[S].Text.Visible := true;
- SelectsS[S].TColR := TColR;
- SelectsS[S].TColG := TColG;
- SelectsS[S].TColB := TColB;
- SelectsS[S].TInt := TInt;
- SelectsS[S].TDColR := TDColR;
- SelectsS[S].TDColG := TDColG;
- SelectsS[S].TDColB := TDColB;
- SelectsS[S].TDInt := TDInt;
-
- SelectsS[S].STColR := STColR;
- SelectsS[S].STColG := STColG;
- SelectsS[S].STColB := STColB;
- SelectsS[S].STInt := STInt;
- SelectsS[S].STDColR := STDColR;
- SelectsS[S].STDColG := STDColG;
- SelectsS[S].STDColB := STDColB;
- SelectsS[S].STDInt := STDInt;
-
- // new
- SelectsS[S].Texture.TexX1 := 0;
- SelectsS[S].Texture.TexY1 := 0;
- SelectsS[S].Texture.TexX2 := 1;
- SelectsS[S].Texture.TexY2 := 1;
- SelectsS[S].TextureSBG.TexX1 := 0;
- SelectsS[S].TextureSBG.TexY1 := 0;
- SelectsS[S].TextureSBG.TexX2 := 1;
- SelectsS[S].TextureSBG.TexY2 := 1;
-
- // Sets Data to copy the value of selectops to global value;
- SelectsS[S].PData := @Data;
- // Configures Select options
- {//SelectsS[S].TextOpt[0].Text := IntToStr(I+1);
- SelectsS[S].TextOpt[0].Size := 10;
- SelectsS[S].TextOpt[0].Align := 1;
-
- SelectsS[S].TextOpt[0].ColR := SelectsS[S].STDColR;
- SelectsS[S].TextOpt[0].ColG := SelectsS[S].STDColG;
- SelectsS[S].TextOpt[0].ColB := SelectsS[S].STDColB;
- SelectsS[S].TextOpt[0].Int := SelectsS[S].STDInt;
- SelectsS[S].TextOpt[0].Visible := true; }
-
- // Sets default value of selectopt from Data;
- SelectsS[S].SelectedOption := Data;
-
- // Disables default selection
- SelectsS[S].SetSelect(false);
-
- {// Configures 3 select options
- for I := 0 to 2 do begin
- SelectsS[S].TextOpt[I].X := SelectsS[S].TextureSBG.X + 20 + (50 + 20) + (150 - 20) * I;
- SelectsS[S].TextOpt[I].Y := SelectsS[S].TextureSBG.Y + 20;
- SelectsS[S].TextOpt[I].Text := IntToStr(I+1);
- SelectsS[S].TextOpt[I].Size := 10;
- SelectsS[S].TextOpt[I].Align := 1;
-
-
- SelectsS[S].TextOpt[I].ColR := SelectsS[S].STDColR;
- SelectsS[S].TextOpt[I].ColG := SelectsS[S].STDColG;
- SelectsS[S].TextOpt[I].ColB := SelectsS[S].STDColB;
- SelectsS[S].TextOpt[I].Int := SelectsS[S].STDInt;
- SelectsS[S].TextOpt[I].Visible := true;
- end;}
-
-
- // adds interaction
- AddInteraction(iSelectS, S);
- Result := S;
-end;
-
-procedure TMenu.AddSelectSlideOption(const AddText: string);
-begin
- AddSelectSlideOption(High(SelectsS), AddText);
-end;
-
-procedure TMenu.AddSelectSlideOption(SelectNo: Cardinal; const AddText: string);
-var
- SO: integer;
-begin
- SO := Length(SelectsS[SelectNo].TextOptT);
-
- SetLength(SelectsS[SelectNo].TextOptT, SO + 1);
- SelectsS[SelectNo].TextOptT[SO] := AddText;
-
- //SelectsS[S].SelectedOption := SelectsS[S].SelectOptInt; // refresh
-
- //if SO = Selects[S].PData^ then Selects[S].SelectedOption := SO;
-end;
-
-procedure TMenu.UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
-var
- SO: integer;
-begin
- SetLength(SelectsS[SelectNum].TextOptT, 0);
- for SO := 0 to High(Values) do
- AddSelectSlideOption(SelectNum, Values[SO]);
-
- SelectsS[SelectNum].GenLines;
-
-// SelectsS[SelectNum].SelectedOption := SelectsS[SelectNum].SelectOptInt; // refresh
-// SelectS[SelectNum].SetSelectOpt(Data);
-// SelectS[SelectNum].SelectedOption := 0;//Data;
-
-// Log.LogError(IntToStr(High(SelectsS[SelectNum].TextOptT)));
-// if 0 <= High(SelectsS[SelectNum].TextOptT) then
-
- SelectsS[SelectNum].PData := @Data;
- SelectsS[SelectNum].SelectedOption := Data;
-end;
-
-procedure TMenu.InteractInc;
-var
- Num: integer;
- Value: integer;
-begin
- case Interactions[Interaction].Typ of
- iSelectS: begin
- Num := Interactions[Interaction].Num;
- Value := SelectsS[Num].SelectedOption;
-// Value := (Value + 1) Mod (Length(SelectsS[Num].TextOptT));
-
- // limit
- Value := Value + 1;
- if Value <= High(SelectsS[Num].TextOptT) then
- SelectsS[Num].SelectedOption := Value;
- end;
- //Button Collection Mod
- iBCollectionChild:
- begin
-
- //Select Next Button in Collection
- For Num := 1 to High(Button) do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if Value = 0 then
- begin
- InteractNext;
- Break;
- end;
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- //interact Next if there is Nothing to Change
- else InteractNext;
- end;
-end;
-
-procedure TMenu.InteractDec;
-var
- Num: integer;
- Value: integer;
-begin
- case Interactions[Interaction].Typ of
- iSelectS: begin
- Num := Interactions[Interaction].Num;
- Value := SelectsS[Num].SelectedOption;
- Value := Value - 1;
-// if Value = -1 then
-// Value := High(SelectsS[Num].TextOptT);
-
- if Value >= 0 then
- SelectsS[Num].SelectedOption := Value;
- end;
- //Button Collection Mod
- iBCollectionChild:
- begin
- //Select Prev Button in Collection
- For Num := High(Button) downto 1 do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if Value = High(Button) then
- begin
- InteractPrev;
- Break;
- end;
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- //interact Prev if there is Nothing to Change
- else
- begin
- InteractPrev;
- //If ButtonCollection with more than 1 Entry then Select Last Entry
- if (Button[Interactions[Interaction].Num].Parent <> 0) AND (ButtonCollection[Button[Interactions[Interaction].Num].Parent-1].CountChilds > 1) then
- begin
- //Select Last Child
- For Num := High(Button) downto 1 do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- end;
- end;
-end;
-
-procedure TMenu.AddBox(X, Y, W, H: real);
-begin
- AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
- AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
-end;
-
-procedure TMenu.onShow;
-begin
- // FIXME: this needs some work. First, there should be a variable like
- // VideoBackground so we can check whether a video-background is enabled or not.
- // Second, a video should be stopped if the screen is hidden, but the Video.Stop()
- // method is not implemented by now. This is necessary for theme-switching too.
- // At the moment videos cannot be turned off without restarting USDX.
-
- // check if a background texture was found
- if (BackImg.TexNum = 0) then
- begin
- // try to open an animated background
- // Note: newer versions of ffmpeg are able to open images like jpeg
- // so do not pass an image's filename to VideoPlayback.Open()
- if fileexists( fFileName ) then
- begin
- if VideoPlayback.Open( fFileName ) then
- begin
- VideoBGTimer.SetTime(0);
- VideoPlayback.Play;
- end;
- end;
- end;
-end;
-
-procedure TMenu.onShowFinish;
-begin
- // nothing
-end;
-
-(*
- * Wrapper for WideUpperCase. Needed because some plattforms have problems with
- * unicode support.
- *)
-function TMenu.WideCharUpperCase(wchar: WideChar) : WideString;
-begin
- // On Linux and MacOSX the cwstring unit is necessary for Unicode function-calls.
- // Otherwise you will get an EIntOverflow exception (thrown by unimplementedwidestring()).
- // The Unicode manager cwstring does not work with MacOSX at the moment because
- // of missing references to iconv. So we have to use Ansi... for the moment.
-
- {$IFNDEF DARWIN}
- // The FPC implementation of WideUpperCase returns nil if wchar is #0 (e.g. if an arrow key is pressed)
- if (wchar <> #0) then
- Result := WideUpperCase(wchar)
- else
- Result := #0;
- {$ELSE}
- Result := AnsiUpperCase(wchar)
- {$ENDIF}
-end;
-
-(*
- * Wrapper for WideUpperCase. Needed because some plattforms have problems with
- * unicode support.
- *)
-function TMenu.WideStringUpperCase(wstring: WideString) : WideString;
-begin
- {$IFNDEF DARWIN}
- Result := WideUpperCase(wstring)
- {$ELSE}
- Result := AnsiUpperCase(wstring);
- {$ENDIF}
-end;
-
-procedure TMenu.onHide;
-begin
- // nothing
-end;
-
-function TMenu.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- // nothing
- Result := true;
-end;
-
-procedure TMenu.SetAnimationProgress(Progress: real);
-begin
- // nothing
-end;
-
-end.
-
diff --git a/Game/Code/Menu/UMenuButton.pas b/Game/Code/Menu/UMenuButton.pas
deleted file mode 100644
index 60b92b9f..00000000
--- a/Game/Code/Menu/UMenuButton.pas
+++ /dev/null
@@ -1,564 +0,0 @@
-unit UMenuButton;
-
-interface
-
-{$I switches.inc}
-
-uses TextGL, UTexture, gl, UMenuText,SDL;
-
-type
- CButton = class of TButton;
-
- TButton = class
- protected
- SelectBool: Boolean;
-
- FadeProgress: Real;
- FadeLastTick: Cardinal;
-
- DeSelectW,
- DeSelectH,
- PosX,
- PosY: Real;
-
- constructor Create(); overload;
-
- public
- Text: Array of TText;
- Texture: TTexture; // Button Screen position and size
- Texture2: TTexture; // second texture only used for fading full resolution covers
-
- Colorized: Boolean;
- DeSelectTexture: TTexture; // texture for colorized hack
-
- FadeTex: TTexture; //Texture for beautiful fading
- FadeTexPos: byte; //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right)
-
- DeselectType: integer; // not used yet
- Visible: boolean;
-
- Reflection: boolean;
- Reflectionspacing,
- DeSelectReflectionspacing: Real;
-
- Fade,
- FadeText: Boolean;
-
- Selectable: boolean;
-
- //Number of the Parent Collection, 0 if in no Collection
- Parent: Byte;
-
- SelectColR,
- SelectColG,
- SelectColB,
- SelectInt,
- SelectTInt: real;
- //Fade Mod
- SelectW: real;
- SelectH: real;
-
- DeselectColR,
- DeselectColG,
- DeselectColB,
- DeselectInt,
- DeselectTInt: real;
-
- procedure SetY(Value: real);
- procedure SetX(Value: real);
- procedure SetW(Value: real);
- procedure SetH(Value: real);
-
- procedure SetSelect(Value: Boolean); virtual;
- property X: real read PosX write SetX;
- property Y: real read PosY write SetY;
- property Z: real read Texture.z write Texture.z;
- property W: real read DeSelectW write SetW;
- property H: real read DeSelectH write SetH;
- property Selected: Boolean read SelectBool write SetSelect;
-
- procedure Draw; virtual;
-
- constructor Create(Textura: TTexture); overload;
- constructor Create(Textura, DSTexture: TTexture); overload;
- destructor Destroy; override;
- end;
-
-implementation
-
-uses SysUtils,
- UDrawTexture;
-
-procedure TButton.SetX(Value: real);
-{var
- dx: real;
- T: integer; // text}
-begin
- {dY := Value - Texture.y;
-
- Texture.X := Value;
-
- for T := 0 to High(Text) do
- Text[T].X := Text[T].X + dY;}
-
- PosX := Value;
- if (FadeTex.TexNum = 0) then
- Texture.X := Value;
-
-end;
-
-procedure TButton.SetY(Value: real);
-{var
- dY: real;
- T: integer; // text}
-begin
- {dY := Value - PosY;
-
-
- for T := 0 to High(Text) do
- Text[T].Y := Text[T].Y + dY;}
-
- PosY := Value;
- if (FadeTex.TexNum = 0) then
- Texture.y := Value;
-end;
-
-procedure TButton.SetW(Value: real);
-begin
- if SelectW = DeSelectW then
- SelectW := Value;
-
- DeSelectW := Value;
-
- if Not Fade then
- begin
- if SelectBool then
- Texture.W := SelectW
- else
- Texture.W := DeSelectW;
- end;
-end;
-
-procedure TButton.SetH(Value: real);
-begin
- if SelectH = DeSelectH then
- SelectH := Value;
-
- DeSelectH := Value;
-
- if Not Fade then
- begin
- if SelectBool then
- Texture.H := SelectH
- else
- Texture.H := DeSelectH;
- end;
-end;
-
-procedure TButton.SetSelect(Value : Boolean);
-var
- T: integer;
-begin
- SelectBool := Value;
-
- if (Value) then
- begin
- Texture.ColR := SelectColR;
- Texture.ColG := SelectColG;
- Texture.ColB := SelectColB;
- Texture.Int := SelectInt;
-
- Texture2.ColR := SelectColR;
- Texture2.ColG := SelectColG;
- Texture2.ColB := SelectColB;
- Texture2.Int := SelectInt;
-
- for T := 0 to High(Text) do
- Text[T].Int := SelectTInt;
-
- //Fade Mod
- if Fade then
- begin
- if (FadeProgress <= 0) then
- FadeProgress := 0.125;
- end
- else
- begin
- Texture.W := SelectW;
- Texture.H := SelectH;
- end;
- end
- else
- begin
- Texture.ColR := DeselectColR;
- Texture.ColG := DeselectColG;
- Texture.ColB := DeselectColB;
- Texture.Int := DeselectInt;
-
- Texture2.ColR := DeselectColR;
- Texture2.ColG := DeselectColG;
- Texture2.ColB := DeselectColB;
- Texture2.Int := DeselectInt;
-
- for T := 0 to High(Text) do
- Text[T].Int := DeselectTInt;
-
- //Fade Mod
- if Fade then
- begin
- if (FadeProgress >= 1) then
- FadeProgress := 0.875;
- end
- else
- begin
- Texture.W := DeSelectW;
- Texture.H := DeSelectH;
- end;
- end;
-end;
-
-constructor TButton.Create();
-begin
- inherited Create;
- // We initialize all to 0, nil or false
- Visible := true;
- SelectBool := false;
- DeselectType := 0;
- Selectable := true;
- Reflection := false;
- Colorized := false;
-
- SelectColR := 1;
- SelectColG := 1;
- SelectColB := 1;
- SelectInt := 1;
- SelectTInt := 1;
-
- DeselectColR := 1;
- DeselectColG := 1;
- DeselectColB := 1;
- DeselectInt := 0.5;
- DeselectTInt := 1;
-
- Fade := false;
- FadeTex.TexNum := 0;
- FadeProgress := 0;
- FadeText := false;
- SelectW := DeSelectW;
- SelectH := DeSelectH;
-
- PosX := 0;
- PosY := 0;
-
- Parent := 0;
-end;
-
-// ***** Public methods ****** //
-
-procedure TButton.Draw;
-var
- T: integer;
- Tick: Cardinal;
- Spacing: Real;
-begin
- if Visible then
- begin
- //Fade Mod
- T:=0;
- if Fade then
- begin
- if (FadeProgress < 1) and (FadeProgress > 0) then
- begin
- Tick := SDL_GetTicks() div 16;
- if (Tick <> FadeLastTick) then
- begin
- FadeLastTick := Tick;
-
- if SelectBool then
- FadeProgress := FadeProgress + 0.125
- else
- FadeProgress := FadeProgress - 0.125;
-
- if (FadeText) then
- begin
- For T := 0 to high(Text) do
- begin
- Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress;
- Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress;
- end;
- end;
-
- end;
- end;
-
- //Method without Fade Texture
- if (FadeTex.TexNum = 0) then
- begin
- Texture.W := DeSelectW + (SelectW - DeSelectW) * FadeProgress;
- Texture.H := DeSelectH + (SelectH - DeSelectH) * FadeProgress;
- DeSelectTexture.W := Texture.W;
- DeSelectTexture.H := Texture.H;
- end
- else //method with Fade Texture
- begin
- Texture.W := DeSelectW;
- Texture.H := DeSelectH;
- DeSelectTexture.W := Texture.W;
- DeSelectTexture.H := Texture.H;
-
- FadeTex.ColR := Texture.ColR;
- FadeTex.ColG := Texture.ColG;
- FadeTex.ColB := Texture.ColB;
- FadeTex.Int := Texture.Int;
-
- FadeTex.Z := Texture.Z;
-
- FadeTex.Alpha := Texture.Alpha;
- FadeTex.TexX1 := 0;
- FadeTex.TexX2 := 1;
- FadeTex.TexY1 := 0;
- FadeTex.TexY2 := 1;
-
- Case FadeTexPos of
- 0: //FadeTex on Top
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress;
- DeSelectTexture.X := Texture.X;
- DeSelectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY;
- FadeTex.W := Texture.W;
- FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
- FadeTex.ScaleW := Texture.ScaleW;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexY2 := 0.9;
- end;
- 1: //FadeTex on Left
- begin
- //Standard Texture
- Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress;
- Texture.Y := PosY;
- DeSelectTexture.X := Texture.X;
- DeSelectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY;
- FadeTex.H := Texture.H;
- FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
- FadeTex.ScaleH := Texture.ScaleH;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexX2 := 0.9;
- end;
- 2: //FadeTex on Bottom
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY;
- DeSelectTexture.X := Texture.X;
- DeSelectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY + (SelectH - DeSelectH) * FadeProgress;;
- FadeTex.W := Texture.W;
- FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
- FadeTex.ScaleW := Texture.ScaleW;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexY1 := 0.1;
- end;
- 3: //FadeTex on Right
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY;
- DeSelectTexture.X := Texture.X;
- DeSelectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress;
- FadeTex.Y := PosY;
- FadeTex.H := Texture.H;
- FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
- FadeTex.ScaleH := Texture.ScaleH;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexX1 := 0.1;
- end;
- end;
- end;
- end
- else if (FadeText) then
- begin
- Text[T].MoveX := (SelectW - DeSelectW);
- Text[T].MoveY := (SelectH - DeSelectH);
- end;
-
- if SelectBool or (FadeProgress > 0) or not Colorized then
- DrawTexture(Texture)
- else
- begin
- DeSelectTexture.X := Texture.X;
- DeSelectTexture.Y := Texture.Y;
- DeSelectTexture.H := Texture.H;
- DeSelectTexture.W := Texture.W;
- DrawTexture(DeSelectTexture);
- end;
-
- //Draw FadeTex
- if (FadeTex.TexNum > 0) then
- DrawTexture(FadeTex);
-
- if Texture2.Alpha > 0 then
- begin
- Texture2.ScaleW := Texture.ScaleW;
- Texture2.ScaleH := Texture.ScaleH;
-
- Texture2.X := Texture.X;
- Texture2.Y := Texture.Y;
- Texture2.W := Texture.W;
- Texture2.H := Texture.H;
-
- Texture2.ColR := Texture.ColR;
- Texture2.ColG := Texture.ColG;
- Texture2.ColB := Texture.ColB;
- Texture2.Int := Texture.Int;
-
- Texture2.Z := Texture.Z;
-
- DrawTexture(Texture2);
- end;
-
- //Reflection Mod
- if (Reflection) then // Draw Reflections
- begin
- if (FadeProgress <> 0) AND (FadeProgress <> 1) then
- begin
- Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress;
- end
- else if SelectBool then
- Spacing := Reflectionspacing
- else
- Spacing := DeSelectReflectionspacing;
-
- if SelectBool or not Colorized then
- with Texture do
- begin
- //Bind Tex and GL Attributes
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- //Draw
- glBegin(GL_QUADS);//Top Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX1*TexW, TexY2*TexH);
- glVertex3f(x, y+h*scaleH+ Spacing, z);
-
- //Bottom Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
- glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
-
- //Bottom Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
- glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
- //Top Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX2*TexW, TexY2*TexH);
- glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- end else
- with DeSelectTexture do
- begin
- //Bind Tex and GL Attributes
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- //Draw
- glBegin(GL_QUADS);//Top Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX1*TexW, TexY2*TexH);
- glVertex3f(x, y+h*scaleH+ Spacing, z);
-
- //Bottom Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
- glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
- //Bottom Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
- glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
- //Top Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX2*TexW, TexY2*TexH);
- glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- end;
- end;
-
- for T := 0 to High(Text) do begin
- Text[T].Draw;
- end;
- end;
-end;
-
-
-destructor TButton.Destroy;
-begin
- inherited;
-end;
-
-constructor TButton.Create(Textura: TTexture);
-begin
- Create();
- Texture := Textura;
- DeSelectTexture := Textura;
- Texture.ColR := 0;
- Texture.ColG := 0.5;
- Texture.ColB := 0;
- Texture.Int := 1;
- Colorized := False;
-end;
-
-// Button has the texture-type "colorized"
-// Two textures are generated, one with Col the other one with DCol
-// Check UMenu.pas line 680 to see the call ( AddButton() )
-constructor TButton.Create(Textura, DSTexture: TTexture);
-begin
- Create();
- Texture := Textura;
- DeSelectTexture := DSTexture;
- Texture.ColR := 1;
- Texture.ColG := 1;
- Texture.ColB := 1;
- Texture.Int := 1;
- Colorized := True;
-end;
-
-end.
diff --git a/Game/Code/Menu/UMenuButtonCollection.pas b/Game/Code/Menu/UMenuButtonCollection.pas
deleted file mode 100644
index c700c812..00000000
--- a/Game/Code/Menu/UMenuButtonCollection.pas
+++ /dev/null
@@ -1,71 +0,0 @@
-unit UMenuButtonCollection;
-
-interface
-
-{$I switches.inc}
-
-uses UMenuButton;
-
-type
- //----------------
- //TButtonCollection
- //No Extra Attributes or Functions ATM
- //----------------
- AButton = Array of TButton;
- PAButton = ^AButton;
- TButtonCollection = class(TButton)
- //num of the First Button, that can be Selected
- FirstChild: Byte;
- CountChilds: Byte;
-
- ScreenButton: PAButton;
-
- procedure SetSelect(Value : Boolean); override;
- procedure Draw; override;
- end;
-
-implementation
-
-procedure TButtonCollection.SetSelect(Value : Boolean);
-var I: Integer;
-begin
- inherited;
-
- //Set Visible for Every Button that is a Child of this ButtonCollection
- if (Not Fade) then
- For I := 0 to High(ScreenButton^) do
- if (ScreenButton^[I].Parent = Parent) then
- ScreenButton^[I].Visible := Value;
-end;
-
-procedure TButtonCollection.Draw;
-var I, J: Integer;
-begin
- inherited;
- //If fading is activated, Fade Child Buttons
- if (Fade) then
- begin
- For I := 0 to High(ScreenButton^) do
- if (ScreenButton^[I].Parent = Parent) then
- begin
- if (FadeProgress < 0.5) then
- begin
- ScreenButton^[I].Visible := SelectBool;
-
- For J := 0 to High(ScreenButton^[I].Text) do
- ScreenButton^[I].Text[J].Visible := SelectBool;
- end
- else
- begin
- ScreenButton^[I].Texture.Alpha := (FadeProgress-0.666)*3;
-
- For J := 0 to High(ScreenButton^[I].Text) do
- ScreenButton^[I].Text[J].Alpha := (FadeProgress-0.666)*3;
- end;
- end;
- end;
-end;
-
-
-
-end.
diff --git a/Game/Code/Menu/UMenuInteract.pas b/Game/Code/Menu/UMenuInteract.pas
deleted file mode 100644
index e0b4fa11..00000000
--- a/Game/Code/Menu/UMenuInteract.pas
+++ /dev/null
@@ -1,16 +0,0 @@
-unit UMenuInteract;
-
-interface
-
-{$I switches.inc}
-
-type
- TInteract = record // for moving thru menu
- Typ: integer; // 0 - button, 1 - select, 2 - Text, 3 - Select SLide, 5 - ButtonCollection Child
- Num: integer; // number of this item in proper list like buttons, selects
- end;
-
-implementation
-
-end.
-
\ No newline at end of file
diff --git a/Game/Code/Menu/UMenuSelectSlide.pas b/Game/Code/Menu/UMenuSelectSlide.pas
deleted file mode 100644
index 76299e80..00000000
--- a/Game/Code/Menu/UMenuSelectSlide.pas
+++ /dev/null
@@ -1,355 +0,0 @@
-unit UMenuSelectSlide;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses TextGL,
- UTexture,
- gl,
- UMenuText;
-
-type
- PSelectSlide = ^TSelectSlide;
- TSelectSlide = class
- private
- SelectBool: boolean;
- public
- // objects
- Text: TText; // Main text describing option
- TextOpt: array of TText; // 3 texts in the position of possible options
- TextOptT: array of string; // array of names for possible options
-
- Texture: TTexture; // Select Texture
- TextureSBG: TTexture; // Background Selections Texture
-// TextureS: array of TTexture; // Selections Texture (not used)
-
-// TextureArrowL: TTexture; // Texture for left arrow (not used yet)
-// TextureArrowR: TTexture; // Texture for right arrow (not used yet)
-
- SelectOptInt: integer;
- PData: ^integer;
-
- //For automatically Setting LineCount
- Lines: Byte;
-
- //Visibility
- Visible: Boolean;
-
- // for selection and deselection
- // main static
- ColR: real;
- ColG: real;
- ColB: real;
- Int: real;
- DColR: real;
- DColG: real;
- DColB: real;
- DInt: real;
-
- // main text
- TColR: real;
- TColG: real;
- TColB: real;
- TInt: real;
- TDColR: real;
- TDColG: real;
- TDColB: real;
- TDInt: real;
-
- // selection background static
- SBGColR: real;
- SBGColG: real;
- SBGColB: real;
- SBGInt: real;
- SBGDColR: real;
- SBGDColG: real;
- SBGDColB: real;
- SBGDInt: real;
-
- // selection text
- STColR: real;
- STColG: real;
- STColB: real;
- STInt: real;
- STDColR: real;
- STDColG: real;
- STDColB: real;
- STDInt: real;
-
- // position and size
- property X: real read Texture.x write Texture.x;
- property Y: real read Texture.y write Texture.y;
- property W: real read Texture.w write Texture.w;
- property H: real read Texture.h write Texture.h;
-// property X2: real read Texture2.x write Texture2.x;
-// property Y2: real read Texture2.y write Texture2.y;
-// property W2: real read Texture2.w write Texture2.w;
-// property H2: real read Texture2.h write Texture2.h;
-
- property SBGW: real read TextureSBG.w write TextureSBG.w;
-
- // procedures
- procedure SetSelect(Value: boolean);
- property Selected: Boolean read SelectBool write SetSelect;
- procedure SetSelectOpt(Value: integer);
- property SelectedOption: integer read SelectOptInt write SetSelectOpt;
- procedure Draw;
- constructor Create;
-
- //Automatically Generate Lines (Texts)
- procedure genLines;
- end;
-
-implementation
-uses UDrawTexture, math, ULog, SysUtils;
-
-// ------------ Select
-constructor TSelectSlide.Create;
-begin
- inherited Create;
- Text := TText.Create;
- SetLength(TextOpt, 1);
- TextOpt[0] := TText.Create;
-
- //Set Standard Width for Selections Background
- SBGW := 450;
-
- Visible := True;
- {SetLength(TextOpt, 3);
- TextOpt[0] := TText.Create;
- TextOpt[1] := TText.Create;
- TextOpt[2] := TText.Create;}
-end;
-
-procedure TSelectSlide.SetSelect(Value: boolean);
-{var
- SO: integer;
- I: integer;}
-begin
- SelectBool := Value;
- if Value then begin
- Texture.ColR := ColR;
- Texture.ColG := ColG;
- Texture.ColB := ColB;
- Texture.Int := Int;
-
- Text.ColR := TColR;
- Text.ColG := TColG;
- Text.ColB := TColB;
- Text.Int := TInt;
-
- TextureSBG.ColR := SBGColR;
- TextureSBG.ColG := SBGColG;
- TextureSBG.ColB := SBGColB;
- TextureSBG.Int := SBGInt;
-
-{ for I := 0 to High(TextOpt) do begin
- TextOpt[I].ColR := STColR;
- TextOpt[I].ColG := STColG;
- TextOpt[I].ColB := STColB;
- TextOpt[I].Int := STInt;
- end;}
-
- end else begin
- Texture.ColR := DColR;
- Texture.ColG := DColG;
- Texture.ColB := DColB;
- Texture.Int := DInt;
-
- Text.ColR := TDColR;
- Text.ColG := TDColG;
- Text.ColB := TDColB;
- Text.Int := TDInt;
-
- TextureSBG.ColR := SBGDColR;
- TextureSBG.ColG := SBGDColG;
- TextureSBG.ColB := SBGDColB;
- TextureSBG.Int := SBGDInt;
-
-{ for I := 0 to High(TextOpt) do begin
- TextOpt[I].ColR := STDColR;
- TextOpt[I].ColG := STDColG;
- TextOpt[I].ColB := STDColB;
- TextOpt[I].Int := STDInt;
- end;}
- end;
-end;
-
-procedure TSelectSlide.SetSelectOpt(Value: integer);
-var
- SO: integer;
- Sel: integer;
- HalfL: integer;
- HalfR: integer;
-
-procedure DoSelection(Sel: Cardinal);
- var I: Integer;
- begin
- for I := low(TextOpt) to high(TextOpt) do
- begin
- TextOpt[I].ColR := STDColR;
- TextOpt[I].ColG := STDColG;
- TextOpt[I].ColB := STDColB;
- TextOpt[I].Int := STDInt;
- end;
- if (integer(Sel) <= high(TextOpt)) then
- begin
- TextOpt[Sel].ColR := STColR;
- TextOpt[Sel].ColG := STColG;
- TextOpt[Sel].ColB := STColB;
- TextOpt[Sel].Int := STInt;
- end;
- end;
-begin
- SelectOptInt := Value;
- PData^ := Value;
-// SetSelect(true); // reset all colors
-
- if (Length(TextOpt)>0) AND (Length(TextOptT)>0) then
- begin
-
- if (Value <= 0) then
- begin //First Option Selected
- Value := 0;
-
- for SO := low (TextOpt) to high(TextOpt) do
- begin
- TextOpt[SO].Text := TextOptT[SO];
- end;
-
- DoSelection(0);
- end
- else if (Value >= high(TextOptT)) then
- begin //Last Option Selected
- Value := high(TextOptT);
-
- for SO := high(TextOpt) downto low (TextOpt) do
- begin
- TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
- end;
- DoSelection(Lines-1);
- end
- else
- begin
- HalfL := Ceil((Lines-1)/2);
- HalfR := Lines-1-HalfL;
-
- if (Value <= HalfL) then
- begin //Selected Option is near to the left side
- {HalfL := Value;
- HalfR := Lines-1-HalfL;}
- //Change Texts
- for SO := low (TextOpt) to high(TextOpt) do
- begin
- TextOpt[SO].Text := TextOptT[SO];
- end;
-
- DoSelection(Value);
- end
- else if (Value > High(TextOptT)-HalfR) then
- begin //Selected is too near to the right border
- HalfR := high(TextOptT) - Value;
- HalfL := Lines-1-HalfR;
- //Change Texts
- for SO := high(TextOpt) downto low (TextOpt) do
- begin
- TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
- end;
-
- DoSelection (HalfL);
- end
- else
- begin
- //Change Texts
- for SO := low (TextOpt) to high(TextOpt) do
- begin
- TextOpt[SO].Text := TextOptT[Value - HalfL + SO];
- end;
-
- DoSelection(HalfL);
- end;
-
- end;
-
- end;
-
-end;
-
-procedure TSelectSlide.Draw;
-var
- SO: integer;
-begin
- if Visible then
- begin
- DrawTexture(Texture);
- DrawTexture(TextureSBG);
-
- Text.Draw;
-
- for SO := low(TextOpt) to high(TextOpt) do
- TextOpt[SO].Draw;
- end;
-end;
-
-procedure TSelectSlide.GenLines;
-var
-maxlength: Real;
-I: Integer;
-begin
- SetFontStyle(0{Text.Style});
- SetFontSize(Text.Size);
- maxlength := 0;
-
- for I := low(TextOptT) to high (TextOptT) do
- begin
- if (glTextWidth(PChar(TextOptT[I])) > maxlength) then
- maxlength := glTextWidth(PChar(TextOptT[I]));
- end;
-
- Lines := floor((TextureSBG.W-40) / (maxlength+7));
- if (Lines > Length(TextOptT)) then
- Lines := Length(TextOptT);
-
- if (Lines <= 0) then
- Lines := 1;
-
- //Free old Space used by Texts
- For I := low(TextOpt) to high(TextOpt) do
- TextOpt[I].Free;
-
- setLength (TextOpt, Lines);
-
- for I := low(TextOpt) to high(TextOpt) do
- begin
- TextOpt[I] := TText.Create;
- TextOpt[I].Size := Text.Size;
- //TextOpt[I].Align := 1;
- TextOpt[I].Align := 0;
- TextOpt[I].Visible := True;
-
- TextOpt[I].ColR := STDColR;
- TextOpt[I].ColG := STDColG;
- TextOpt[I].ColB := STDColB;
- TextOpt[I].Int := STDInt;
-
- //Generate Positions
- //TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * (I + 0.5);
- if (I <> High(TextOpt)) OR (High(TextOpt) = 0) OR (Length(TextOptT) = Lines) then
- TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * I
- else
- TextOpt[I].X := TextureSBG.X + TextureSBG.W - maxlength;
-
- TextOpt[I].Y := TextureSBG.Y + (TextureSBG.H / 2) - 1.5 * Text.Size{20};
-
- //Better Look with 2 Options
- if (Lines=2) AND (Length(TextOptT)= 2) then
- TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W -40 - glTextWidth(PChar(TextOptT[1]))) * I;
- end;
-end;
-
-end.
diff --git a/Game/Code/Menu/UMenuStatic.pas b/Game/Code/Menu/UMenuStatic.pas
deleted file mode 100644
index ac8fa2dc..00000000
--- a/Game/Code/Menu/UMenuStatic.pas
+++ /dev/null
@@ -1,85 +0,0 @@
-unit UMenuStatic;
-
-interface
-
-{$I switches.inc}
-
-uses UTexture, gl;
-
-type
- TStatic = class
- public
- Texture: TTexture; // Button Screen position and size
- Visible: boolean;
-
- //Reflection Mod
- Reflection: boolean;
- Reflectionspacing: Real;
-
- procedure Draw;
- constructor Create(Textura: TTexture); overload;
- end;
-
-implementation
-uses UDrawTexture;
-
-procedure TStatic.Draw;
-begin
- if Visible then
- begin
- DrawTexture(Texture);
-
- //Reflection Mod
- if (Reflection) then // Draw Reflections
- begin
- with Texture do
- begin
- //Bind Tex and GL Attributes
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- //Draw
- glBegin(GL_QUADS);//Top Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX1*TexW, TexY2*TexH);
- glVertex3f(x, y+h*scaleH+ Reflectionspacing, z);
-
- //Bottom Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX1*TexW, 0.5*TexH+TexY1);
- glVertex3f(x, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z);
-
-
- //Bottom Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX2*TexW, 0.5*TexH+TexY1);
- glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z);
-
- //Top Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX2*TexW, TexY2*TexH);
- glVertex3f(x+w*scaleW, y+h*scaleH + Reflectionspacing, z);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- end;
- end;
- end;
-end;
-
-constructor TStatic.Create(Textura: TTexture);
-begin
- inherited Create;
- Texture := Textura;
-end;
-
-end.
diff --git a/Game/Code/Menu/UMenuText.pas b/Game/Code/Menu/UMenuText.pas
deleted file mode 100644
index fecf936e..00000000
--- a/Game/Code/Menu/UMenuText.pas
+++ /dev/null
@@ -1,350 +0,0 @@
-unit UMenuText;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses TextGL,
- UTexture,
- gl,
- math,
- SysUtils,
- SDL;
-
-type
- TText = class
- private
- SelectBool: boolean;
- TextString: string;
- TextTiles: array of string;
-
- STicks: Cardinal;
- SelectBlink: boolean;
- public
- X: real;
- Y: real;
- Z: real;
- MoveX: real; //Some Modifier for X - Position that don't affect the real Y
- MoveY: real; //Some Modifier for Y - Position that don't affect the real Y
- W: real; //text wider than W is broken
-// H: real;
- Size: real;
- ColR: real;
- ColG: real;
- ColB: real;
- Alpha: real;
- Int: real;
- Style: integer;
- Visible: boolean;
- Align: integer; // 0 = left, 1 = center, 2 = right
-
- //Reflection
- Reflection: boolean;
- ReflectionSpacing: real;
-
- procedure SetSelect(Value: boolean);
- property Selected: boolean read SelectBool write SetSelect;
-
- procedure SetText(Value: string);
- property Text: string read TextString write SetText;
-
- procedure DeleteLastL; //Procedure to Delete Last Letter
-
- procedure Draw;
- constructor Create; overload;
- constructor Create(X, Y: real; Tekst: string); overload;
- constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ: real); overload;
- end;
-
-implementation
-
-uses UGraphic,
- StrUtils;
-
-procedure TText.SetSelect(Value: boolean);
-begin
- SelectBool := Value;
-
- //Set Cursor Visible
- SelectBlink := True;
- STicks := SDL_GetTicks() div 550;
-end;
-
-procedure TText.SetText(Value: string);
-var
- NextPos: Cardinal; //NextPos of a Space etc.
- LastPos: Cardinal; //LastPos "
- LastBreak: Cardinal; //Last Break
- isBreak: boolean; //True if the Break is not Caused because the Text is out of the area
- FirstWord: Word; //Is First Word after Break?
- Len: Word; //Length of the Tiles Array
-
- function GetNextPos: boolean;
- var
- T1, T2, T3: Cardinal;
- begin
- LastPos := NextPos;
-
- //Next Space (If Width is given)
- if (W > 0) then
- T1 := PosEx(' ', Value, LastPos + 1)
- else T1 := Length(Value);
-
- {//Next -
- T2 := PosEx('-', Value, LastPos + 1);}
-
- //Next Break
- T3 := PosEx('\n', Value, LastPos + 1);
-
- if T1 = 0 then
- T1 := Length(Value);
- {if T2 = 0 then
- T2 := Length(Value); }
- if T3 = 0 then
- T3 := Length(Value);
-
- //Get Nearest Pos
- NextPos := min(T1, T3{min(T2, T3)});
-
- if (LastPos = Length(Value)) then
- NextPos := 0;
-
- isBreak := (NextPos = T3) AND (NextPos <> Length(Value));
- Result := (NextPos <> 0);
- end;
-
- procedure AddBreak(const From, bTo: Cardinal);
- begin
- if (isBreak) OR (bTo - From >= 1) then
- begin
- Inc(Len);
- SetLength (TextTiles, Len);
- TextTiles[Len-1] := Trim(Copy(Value, From, bTo - From));
-
- if isBreak then
- LastBreak := bTo + 2
- else
- LastBreak := bTo + 1;
- FirstWord := 0;
- end;
- end;
-
-begin
- //Set TExtstring
- TextString := Value;
-
- //Set Cursor Visible
- SelectBlink := True;
- STicks := SDL_GetTicks() div 550;
-
- //Exit if there is no Need to Create Tiles
- if (W <= 0) and (Pos('\n', Value) = 0) then
- begin
- SetLength (TextTiles, 1);
- TextTiles[0] := Value;
- Exit;
- end;
-
- //Create Tiles
- //Reset Text Array
- SetLength (TextTiles, 0);
- Len := 0;
-
- //Reset Counter Vars
- LastPos := 1;
- NextPos := 1;
- LastBreak := 1;
- FirstWord := 1;
-
- if (W > 0) then
- begin
- //Set Font Properties
- SetFontStyle(Style);
- SetFontSize(Size);
- end;
-
- //go Through Text
- while (GetNextPos) do
- begin
- //Break in Text
- if isBreak then
- begin
- //Look for Break before the Break
- if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) AND (NextPos-LastPos > 1) then
- begin
- isBreak := False;
- //Not the First word after Break, so we don't have to break within a word
- if (FirstWord > 1) then
- begin
- //Add Break before actual Position, because there the Text fits the Area
- AddBreak(LastBreak, LastPos);
- end
- else //First Word after Break Break within the Word
- begin
- //ToDo
- //AddBreak(LastBreak, LastBreak + 155);
- end;
- end;
-
- isBreak := True;
- //Add Break from Text
- AddBreak(LastBreak, NextPos);
- end
- //Text comes out of the Text Area -> CreateBreak
- else if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) then
- begin
- //Not the First word after Break, so we don't have to break within a word
- if (FirstWord > 1) then
- begin
- //Add Break before actual Position, because there the Text fits the Area
- AddBreak(LastBreak, LastPos);
- end
- else //First Word after Break -> Break within the Word
- begin
- //ToDo
- //AddBreak(LastBreak, LastBreak + 155);
- end;
- end;
- //end;
- Inc(FirstWord)
- end;
- //Add Ending
- AddBreak(LastBreak, Length(Value)+1);
-end;
-
-procedure TText.DeleteLastL;
-var
- S: string;
- L: integer;
-begin
- S := TextString;
- L := Length(S);
- if (L > 0) then
- SetLength(S, L-1);
-
- SetText(S);
-end;
-
-procedure TText.Draw;
-var
- X2, Y2: real;
- Text2: string;
- I: integer;
-begin
- if Visible then
- begin
- SetFontStyle(Style);
- SetFontSize(Size);
- SetFontItalic(False);
-
- glColor4f(ColR*Int, ColG*Int, ColB*Int, Alpha);
-
- //Reflection
- if Reflection = true then
- SetFontReflection(true, ReflectionSpacing)
- else
- SetFontReflection(false,0);
-
- //if selected set blink...
- if SelectBool then
- begin
- I := SDL_GetTicks() div 550;
- if I <> STicks then
- begin //Change Visability
- STicks := I;
- SelectBlink := Not SelectBlink;
- end;
- end;
-
- {if (False) then //no width set draw as one long string
- begin
- if not (SelectBool AND SelectBlink) then
- Text2 := Text
- else
- Text2 := Text + '|';
-
- case Align of
- 0: X2 := X;
- 1: X2 := X - glTextWidth(pchar(Text2))/2;
- 2: X2 := X - glTextWidth(pchar(Text2));
- end;
-
- SetFontPos(X2, Y);
- glPrint(PChar(Text2));
- SetFontStyle(0); // reset to default
- end
- else
- begin}
- //now use allways:
- //draw text as many strings
- Y2 := Y + MoveY;
- for I := 0 to high(TextTiles) do
- begin
- if (not (SelectBool and SelectBlink)) or (I <> high(TextTiles)) then
- Text2 := TextTiles[I]
- else
- Text2 := TextTiles[I] + '|';
-
- case Align of
- 0: X2 := X + MoveX;
- 1: X2 := X + MoveX - glTextWidth(pchar(Text2))/2;
- 2: X2 := X + MoveX - glTextWidth(pchar(Text2));
- end;
-
- SetFontPos(X2, Y2);
-
- SetFontZ(Z);
-
- glPrint(PChar(Text2));
-
- {if Size >= 10 then
- Y2 := Y2 + Size * 2.8
- else}
- if (Style = 1) then
- Y2 := Y2 + Size * 2.8
- else
- Y2 := Y2 + Size * 2.15;
- end;
- SetFontStyle(0); // reset to default
-
- //end;
- end;
-end;
-
-constructor TText.Create;
-begin
- Create(0, 0, '');
-end;
-
-constructor TText.Create(X, Y: real; Tekst: string);
-begin
- Create(X, Y, 0, 0, 10, 0, 0, 0, 0, Tekst, false, 0, 0);
-end;
-
-constructor TText.Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ:real);
-begin
- inherited Create;
- Alpha := 1;
- X := ParX;
- Y := ParY;
- W := ParW;
- Z := ParZ;
- Style := ParStyle;
- Size := ParSize;
- Text := ParTekst;
- ColR := ParColR;
- ColG := ParColG;
- ColB := ParColB;
- Int := 1;
- Align := ParAlign;
- SelectBool := false;
- Visible := true;
- Reflection:= ParReflection;
- ReflectionSpacing:= ParReflectionSpacing;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenCredits.pas b/Game/Code/Screens/UScreenCredits.pas
deleted file mode 100644
index f7f1fca7..00000000
--- a/Game/Code/Screens/UScreenCredits.pas
+++ /dev/null
@@ -1,1398 +0,0 @@
-unit UScreenCredits;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- UMenu,
- SDL,
- SDL_Image,
- UDisplay,
- UTexture,
- gl,
- UMusic,
- UFiles,
- SysUtils,
- UThemes,
- //ULCD,
- //ULight,
- UGraphicClasses;
-
-type
- TCreditsStages=(InitialDelay,Intro,MainPart,Outro);
-
- TScreenCredits = class(TMenu)
- public
-
- Credits_X: Real;
- Credits_Time: Cardinal;
- Credits_Alpha: Cardinal;
- CTime: Cardinal;
- CTime_hold: Cardinal;
- ESC_Alpha: Integer;
-
- credits_entry_tex: TTexture;
- credits_entry_dx_tex: TTexture;
- credits_bg_tex: TTexture;
- credits_bg_ovl: TTexture;
-// credits_bg_logo: TTexture;
- credits_bg_scrollbox_left: TTexture;
- credits_blindguard: TTexture;
- credits_blindy: TTexture;
- credits_canni: TTexture;
- credits_commandio: TTexture;
- credits_lazyjoker: TTexture;
- credits_mog: TTexture;
- credits_mota: TTexture;
- credits_skillmaster: TTexture;
- credits_whiteshark: TTexture;
- intro_layer01: TTexture;
- intro_layer02: TTexture;
- intro_layer03: TTexture;
- intro_layer04: TTexture;
- intro_layer05: TTexture;
- intro_layer06: TTexture;
- intro_layer07: TTexture;
- intro_layer08: TTexture;
- intro_layer09: TTexture;
- outro_bg: TTexture;
- outro_esc: TTexture;
- outro_exd: TTexture;
-
- deluxe_slidein: cardinal;
-
- CurrentScrollText: String;
- NextScrollUpdate: Real;
- EndofLastScrollingPart: Cardinal;
- CurrentScrollStart, CurrentScrollEnd: Integer;
-
- CRDTS_Stage: TCreditsStages;
-
- myTex: glUint;
- mysdlimage,myconvertedsdlimage: PSDL_Surface;
-
- Fadeout: boolean;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- procedure DrawCredits;
- procedure Draw_FunkyText;
- end;
-
-const
- Funky_Text: AnsiString =
- 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+
- 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+
- 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+
- 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..';
-
-
- Timings: array[0..21] of Cardinal=(
- 20, // 0 Delay vor Start
-
- 149, // 1 Ende erster Intro Zoom
- 155, // 2 Start 2. Action im Intro
- 170, // 3 Ende Separation im Intro
- 271, // 4 Anfang Zoomout im Intro
- 0, // 5 unused
- 261, // 6 Start fade-to-white im Intro
-
- 271, // 7 Start Main Part
- 280, // 8 Start On-Beat-Sternchen Main Part
-
- 396, // 9 Start BlindGuard
- 666, // 10 Start blindy
- 936, // 11 Start Canni
- 1206, // 12 Start Commandio
- 1476, // 13 Start LazyJoker
- 1746, // 14 Start Mog
- 2016, // 15 Start Mota
- 2286, // 16 Start SkillMaster
- 2556, // 17 Start WhiteShark
- 2826, // 18 Ende Whiteshark
- 3096, // 19 Start FadeOut Mainscreen
- 3366, // 20 Ende Credits Tune
- 60); // 21 start flare im intro
-
-
- sdl32bpprgba: TSDL_Pixelformat=(palette: nil;
- BitsPerPixel: 32;
- BytesPerPixel: 4;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 0;
- Gshift: 8;
- Bshift: 16;
- Ashift: 24;
- Rmask: $000000ff;
- Gmask: $0000ff00;
- Bmask: $00ff0000;
- Amask: $ff000000;
- colorkey: 0;
- alpha: 255 );
-
-
-implementation
-
-uses
- ULog,
- UGraphic,
- UMain,
- UIni,
- USongs,
- Textgl,
- ULanguage,
- UCommon,
- Math;
-
-
-function TScreenCredits.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- FadeTo(@ScreenMain);
- AudioPlayback.PlaySound(SoundLib.Back);
- end;
-{ SDLK_SPACE:
- begin
- setlength(CTime_hold,length(CTime_hold)+1);
- CTime_hold[high(CTime_hold)]:=CTime;
- end;
-}
- end;//esac
- end; //fi
-end;
-
-constructor TScreenCredits.Create;
-begin
- inherited Create;
-
- credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', TEXTURE_TYPE_PLAIN, 0);
- credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', TEXTURE_TYPE_TRANSPARENT, 0);
-
- credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', TEXTURE_TYPE_TRANSPARENT, 0);
- credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', TEXTURE_TYPE_TRANSPARENT, 0);
-
- intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', TEXTURE_TYPE_TRANSPARENT, 0);
- intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', TEXTURE_TYPE_TRANSPARENT, 0);
-
- outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', TEXTURE_TYPE_PLAIN, 0);
- outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', TEXTURE_TYPE_TRANSPARENT, 0);
- outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', TEXTURE_TYPE_TRANSPARENT, 0);
-
- CRDTS_Stage:=InitialDelay;
-end;
-
-function TScreenCredits.Draw: boolean;
-begin
- DrawCredits;
- Draw:=true;
-end;
-
-function pixfmt_eq(fmt1,fmt2: TSDL_Pixelformat): boolean;
-begin
- if (fmt1.BitsPerPixel = fmt2.BitsPerPixel) and
- (fmt1.BytesPerPixel = fmt2.BytesPerPixel) and
- (fmt1.Rloss = fmt2.Rloss) and
- (fmt1.Gloss = fmt2.Gloss) and
- (fmt1.Bloss = fmt2.Bloss) and
- (fmt1.Rmask = fmt2.Rmask) and
- (fmt1.Gmask = fmt2.Gmask) and
- (fmt1.Bmask = fmt2.Bmask) and
- (fmt1.Rshift = fmt2.Rshift) and
- (fmt1.Gshift = fmt2.Gshift) and
- (fmt1.Bshift = fmt2.Bshift)
- then
- pixfmt_eq:=True
- else
- pixfmt_eq:=False;
-end;
-
-function inttohexstr(i: cardinal):pchar;
-var helper, i2, c:cardinal;
- tmpstr: string;
-begin
- helper:=0;
- i2:=i;
- tmpstr:='';
- for c:=1 to 8 do
- begin
- helper:=(helper shl 4) or (i2 and $f);
- i2:=i2 shr 4;
- end;
- for c:=1 to 8 do
- begin
- i2:=helper and $f;
- helper := helper shr 4;
- case i2 of
- 0: tmpstr:=tmpstr+'0';
- 1: tmpstr:=tmpstr+'1';
- 2: tmpstr:=tmpstr+'2';
- 3: tmpstr:=tmpstr+'3';
- 4: tmpstr:=tmpstr+'4';
- 5: tmpstr:=tmpstr+'5';
- 6: tmpstr:=tmpstr+'6';
- 7: tmpstr:=tmpstr+'7';
- 8: tmpstr:=tmpstr+'8';
- 9: tmpstr:=tmpstr+'9';
- 10: tmpstr:=tmpstr+'a';
- 11: tmpstr:=tmpstr+'b';
- 12: tmpstr:=tmpstr+'c';
- 13: tmpstr:=tmpstr+'d';
- 14: tmpstr:=tmpstr+'e';
- 15: tmpstr:=tmpstr+'f';
- end;
- end;
- inttohexstr:=pchar(tmpstr);
-end;
-
-procedure TScreenCredits.onShow;
-begin
- inherited;
-
- CRDTS_Stage:=InitialDelay;
- Credits_X := 580;
- deluxe_slidein := 0;
- Credits_Alpha := 0;
- //Music.SetLoop(true); Loop looped ned, so ne scheisse - loop loops not, shit
- AudioPlayback.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!! - thank you wetü
-// Music.Play;
- CTime:=0;
-// setlength(CTime_hold,0);
-
- mysdlimage:=IMG_Load('test.png');
- if assigned(mysdlimage) then
- begin
- showmessage('opened image via SDL_Image'+#13#10+
- 'Width: '+inttostr(mysdlimage^.w)+#13#10+
- 'Height: '+inttostr(mysdlimage^.h)+#13#10+
- 'BitsPP: '+inttostr(mysdlimage^.format.BitsPerPixel)+#13#10+
- 'BytesPP: '+inttostr(mysdlimage^.format.BytesPerPixel)+#13#10+
- 'Rloss: '+inttostr(mysdlimage^.format.Rloss)+#13#10+
- 'Gloss: '+inttostr(mysdlimage^.format.Gloss)+#13#10+
- 'Bloss: '+inttostr(mysdlimage^.format.Bloss)+#13#10+
- 'Aloss: '+inttostr(mysdlimage^.format.Aloss)+#13#10+
- 'Rshift: '+inttostr(mysdlimage^.format.Rshift)+#13#10+
- 'Gshift: '+inttostr(mysdlimage^.format.Gshift)+#13#10+
- 'Bshift: '+inttostr(mysdlimage^.format.Bshift)+#13#10+
- 'Ashift: '+inttostr(mysdlimage^.format.Ashift)+#13#10+
- 'Rmask: '+inttohexstr(mysdlimage^.format.Rmask)+#13#10+
- 'Gmask: '+inttohexstr(mysdlimage^.format.Gmask)+#13#10+
- 'Bmask: '+inttohexstr(mysdlimage^.format.Bmask)+#13#10+
- 'Amask: '+inttohexstr(mysdlimage^.format.Amask)+#13#10+
- 'ColKey: '+inttostr(mysdlimage^.format.Colorkey)+#13#10+
- 'Alpha: '+inttostr(mysdlimage^.format.Alpha));
-
- if pixfmt_eq(mysdlimage^.format^,sdl32bpprgba) then
- showmessage('equal pixelformats')
- else
- showmessage('different pixelformats');
-
- myconvertedsdlimage:=SDL_ConvertSurface(mysdlimage,@sdl32bpprgba,SDL_SWSURFACE);
- glGenTextures(1,@myTex);
- glBindTexture(GL_TEXTURE_2D, myTex);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexImage2D( GL_TEXTURE_2D, 0, 4, myconvertedsdlimage^.w, myconvertedsdlimage^.h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, myconvertedsdlimage^.pixels );
- SDL_FreeSurface(mysdlimage);
- SDL_FreeSurface(myconvertedsdlimage);
- end
- else
- showmessage('could not open file - test.png');
-
-end;
-
-procedure TScreenCredits.onHide;
-begin
- AudioPlayback.Stop;
-end;
-
-Procedure TScreenCredits.Draw_FunkyText;
-var
- S: Integer;
- X,Y,A: Real;
- visibleText: PChar;
-begin
- SetFontSize(10);
- //Init ScrollingText
- if (CTime = Timings[7]) then
- begin
- //Set Position of Text
- Credits_X := 600;
- CurrentScrollStart:=1;
- CurrentScrollEnd:=1;
- end;
-
- if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then
- begin
- X:=0;
- visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
- for S := 0 to length(visibleText)-1 do begin
- Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi));
- SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000);
- A:=0;
- if (Credits_X+X < 15) then A:=0;
- if (Credits_X+X >=15) then A:=Credits_X+X-15;
- if Credits_X+X > 32 then A:=17;
- glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17);
- glPrintLetter(visibleText[S]);
- X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- end;
- if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin
- Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- inc(CurrentScrollStart);
- end;
- visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
- if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin
- inc(CurrentScrollEnd);
- end;
- end;
-{ // timing hack
- X:=5;
- SetFontStyle (2);
- SetFontItalic(False);
- SetFontSize(9);
- glColor4f(1, 1, 1, 1);
- for S:=0 to high(CTime_hold) do begin
- visibleText:=pchar(inttostr(CTime_hold[S]));
- SetFontPos (500, X);
- glPrint (Addr(visibleText[0]));
- X:=X+20;
- end;}
-end;
-
-procedure Start3D;
-begin
- glMatrixMode(GL_PROJECTION);
- glPushMatrix;
- glLoadIdentity;
- glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity;
-end;
-procedure End3D;
-begin
- glMatrixMode(GL_PROJECTION);
- glPopMatrix;
- glMatrixMode(GL_MODELVIEW);
-end;
-
-procedure TScreenCredits.DrawCredits;
-var
-T{*, I*}: Cardinal; // Auto Removed, Unused Variable (I) // Auto Removed, Unused Variable (I)
-// X: Real; // Auto Removed, Unused Variable
-// Ver: PChar; // Auto Removed, Unused Variable
-// RuntimeStr: AnsiString; // Auto Removed, Unused Variable
- Data: TFFTData;
- j,k,l:cardinal;
-f,g{*, h*}: Real; // Auto Removed, Unused Variable (h) // Auto Removed, Unused Variable (h)
- STime:cardinal;
- Delay:cardinal;
-
-// myPixel: longword; // Auto Removed, Unused Variable
-// myColor: Cardinal; // Auto Removed, Unused Variable
- myScale: Real;
- myAngle: Real;
-
-
-const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24),
- (154,31),(156,58),(168,32),(203,36),
- (258,34),(251,50),(274,93),(294,84),
- (232,54),(278,62),(319,34),(336,92),
- (347,23),(374,32),(377,58),(361,83),
- (385,91),(405,91),(429,35),(423,51),
- (450,32),(485,34),(444,91),(486,93));
-
-begin
- //dis does teh muiwk y0r
- AudioPlayback.GetFFTData(Data);
-
- Log.LogStatus('',' JB-1');
-
- T := SDL_GetTicks() div 33;
- if T <> Credits_Time then
- begin
- Credits_Time := T;
- inc(CTime);
- inc(CTime_hold);
- Credits_X := Credits_X-2;
-
- Log.LogStatus('',' JB-2');
- if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then
- begin
-// CTime:=Timings[20];
-// CRDTS_Stage:=Outro;
-
- CRDTS_Stage:=Intro;
- CTime:=0;
- AudioPlayback.Play;
-
- end;
- if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then
- begin
- CRDTS_Stage:=MainPart;
- end;
- if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then
- begin
- CRDTS_Stage:=Outro;
- end;
- end;
-
- Log.LogStatus('',' JB-3');
-
- //draw background
- if CRDTS_Stage=InitialDelay then
- begin
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end
- else
- if CRDTS_Stage=Intro then
- begin
- Start3D;
- glPushMatrix;
-
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- if CTime < Timings[1] then begin
- myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together
- myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera
- end else begin // this is the part when the logo stands still
- myScale:=0.5;
- myAngle:=0;
- end;
- if CTime > Timings[2] then begin
- myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers
- myAngle:=0;
- end;
-// if CTime > Timings[3] then myScale:=1; // keep the space between layers
- glTranslatef(0,0,-5+0.5*myScale);
- if CTime > Timings[3] then myScale:=1; // keep the space between layers
- if CTime > Timings[3] then begin // make logo rotate left and grow
-// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]);
- glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1);
- glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1);
- end;
- if CTime < Timings[2] then
- glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0);
-// glScalef(0.5,0.5,0.5);
- glScalef(4/3,-1,1);
- glColor4f(1, 1, 1, 1);
-
- glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale);
- glEnd;
- gldisable(gl_texture_2d);
- glDisable(GL_BLEND);
-
- glPopMatrix;
- End3D;
-
- // do some sparkling effects
- if (CTime < Timings[1]) and (CTime > Timings[21]) then
- begin
- for k:=1 to 3 do begin
- l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5);
- j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301);
- GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0);
- end;
- end;
-
- // fade to white at end
- if Ctime > Timings[6] then
- begin
- glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6]));
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glVertex2f(0,0);
- glVertex2f(0,600);
- glVertex2f(800,600);
- glVertex2f(800,0);
- glEnd;
- glDisable(GL_BLEND);
- end;
-
- end;
- if (CRDTS_Stage=MainPart) then
- // main credits screen background, scroller, logo and girl
- begin
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,600/1024);glVertex2f(0, 600);
- glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
- glTexCoord2f(800/1024,0);glVertex2f(800, 0);
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // draw scroller
- Draw_FunkyText;
-
-//#########################################################################
-// draw credits names
-
-
-Log.LogStatus('',' JB-4');
-
-// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen) - (rotate in from upper left, rotate out to lower right)
- STime:=Timings[9]-10;
- Delay:=Timings[10]-Timings[9];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(0,329,0);
- if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end;
- gltranslatef(223,0,0);
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- gltranslatef(223,0,0);
- glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1);
- gltranslatef(-223,0,0);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben) - (zoom from 0 to full size and rotation, zoom zo doubble size and shift to upper right)
- STime:=Timings[10]-10;
- Delay:=Timings[11]-Timings[10]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+20) and (CTime<=STime+22) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+20 then begin
- j:=CTime-Stime;
- glscalef(j*j/400,j*j/400,j*j/400);
- glrotatef(j*18.0,0,0,1);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- f:=j*10.0;
- gltranslatef(f*3,-f,0);
- glscalef(1+j/10,1+j/10,1+j/10);
- glrotatef(j*9.0,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Canni (von links reinschieben, nach rechts oben rausschieben) - (shift in from left, shift out to upper right)
- STime:=Timings[11]-10;
- Delay:=Timings[12]-Timings[11]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- gltranslatef(((CTime-STime)*21.0)-210,0,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=(CTime-(STime+Delay-10))*21;
- gltranslatef(j,-j/2,0);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Commandio (von unten reinklappen, nach rechts oben rausklappen) - (flip in from down, flip out to upper right)
- STime:=Timings[12]-10;
- Delay:=Timings[13]-Timings[12];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=258.0-25.8*(CTime-STime)
- else
- f:=0;
- g:=0;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end;
- glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2);
- glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326));
- glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4);
- glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing)
- STime:=Timings[13]-35;
- Delay:=Timings[14]-Timings[13]+5;
- if CTime > STime then
- begin
- k:=0;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20;
- ESC_Alpha:=10;
- f:=CTime-STime;
- if CTime <=STime+40 then j:=CTime-STime else j:=40;
- if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600);
-
- glPushMatrix;
- gltranslatef(180+(f-70),329,0);
- glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Mog (von links reinklappen, nach rechts unten rausklappen) - (flip in from right, flip out to lower right)
- STime:=Timings[14]-10;
- Delay:=Timings[15]-Timings[14]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=326.0-32.6*(CTime-STime)
- else
- f:=0;
-
- g:=0;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end;
- glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5);
- glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g);
- glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4);
- glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen) - (rotate in from upper right, shift out to lower left while shrinking and rotateing)
- STime:=Timings[15]-10;
- Delay:=Timings[16]-Timings[15]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- gltranslatef(223,0,0);
- glrotatef((10-(CTime-STime))*9,0,0,1);
- gltranslatef(-223,0,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- f:=j*10.0;
- gltranslatef(-f*2,-f,0);
- glscalef(1-j/10,1-j/10,1-j/10);
- glrotatef(-j*9.0,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen) - (shift in from lower right, rotate out to upper right)
- STime:=Timings[16]-10;
- Delay:=Timings[17]-Timings[16]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- j:=STime+10-CTime;
- f:=j*10.0;
- gltranslatef(+f*2,+f/2,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- gltranslatef(0,-223,0);
- glrotatef(integer(j)*-9,0,0,1);
- gltranslatef(0,223,0);
- glrotatef(j*9,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen) - (flip in from lower left, flip out to upper right)
- STime:=Timings[17]-10;
- Delay:=Timings[18]-Timings[17];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
-
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=326.0-32.6*(CTime-STime)
- else
- f:=0;
-
- if (CTime >= STime+Delay-10) and (CTime <= STime+Delay) then
- begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end
- else
- begin
- g:=0;
- end;
-
- glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2);
- glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4);
- glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4);
- glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-
- Log.LogStatus('',' JB-103');
-
-// ####################################################################
-// do some twinkle stuff (kinda on beat)
- if (CTime > Timings[8] ) and
- (CTime < Timings[19] ) then
- begin
- k := 0;
-
- try
- for j:=0 to 40 do
- begin
- if ( j < length( Data ) ) AND
- ( k < length( Data ) ) then
- begin
- if Data[j] >= Data[k] then
- k:=j;
- end;
- end;
- except
- end;
-
- if Data[k]>0.2 then
- begin
- l := RandomRange(6,16);
- j := RandomRange(0,27);
-
- GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0);
- end;
- end;
-
-//#################################################
-// draw the rest of the main screen (girl and logo
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(800-393, 0);
- glTexCoord2f(0,600/1024);glVertex2f(800-393, 600);
- glTexCoord2f(393/512,600/1024); glVertex2f(800, 600);
- glTexCoord2f(393/512,0);glVertex2f(800, 0);
- glEnd;
-{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,112/128);glVertex2f(0, 112);
- glTexCoord2f(497/512,112/128); glVertex2f(497, 112);
- glTexCoord2f(497/512,0);glVertex2f(497, 0);
- glEnd;
-}
- gldisable(gl_texture_2d);
- glDisable(GL_BLEND);
-
- // fade out at end of main part
- if Ctime > Timings[19] then
- begin
- glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19]));
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glVertex2f(0,0);
- glVertex2f(0,600);
- glVertex2f(800,600);
- glVertex2f(800,0);
- glEnd;
- glDisable(GL_BLEND);
- end;
- end
- else
- if (CRDTS_Stage=Outro) then
- begin
- if CTime=Timings[20] then begin
- CTime_hold:=0;
- AudioPlayback.Stop;
- AudioPlayback.Open(soundpath + 'credits-outro-tune.mp3');
- AudioPlayback.SetVolume(0.2);
- AudioPlayback.SetLoop(True);
- AudioPlayback.Play;
- end;
- if CTime_hold > 231 then begin
- AudioPlayback.Play;
- Ctime_hold:=0;
- end;
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- // do something useful
- // outro background
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,600/1024);glVertex2f(0, 600);
- glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
- glTexCoord2f(800/1024,0);glVertex2f(800, 0);
- glEnd;
-
- //outro overlays
- glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3);
- glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,223/256);glVertex2f(0, 223);
- glTexCoord2f(487/512,223/256); glVertex2f(487, 223);
- glTexCoord2f(487/512,0);glVertex2f(487, 0);
- glEnd;
-
- ESC_Alpha:=20;
- if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then
- ESC_Alpha:=0
- else inc(ESC_Alpha);
- if ESC_Alpha > 20 then ESC_Alpha:=20;
- glColor4f(1, 1, 1, ESC_Alpha/20);
- glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(800-310, 600-247);
- glTexCoord2f(0,247/256);glVertex2f(800-310, 600);
- glTexCoord2f(310/512,247/256); glVertex2f(800, 600);
- glTexCoord2f(310/512,0);glVertex2f(800, 600-247);
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // outro scrollers?
- // ...
- end;
-
-{ // draw credits runtime counter
- SetFontStyle (2);
- SetFontItalic(False);
- SetFontSize(9);
- SetFontPos (5, 5);
- glColor4f(1, 1, 1, 1);
-// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10);
- RuntimeStr:='CTime: '+inttostr(CTime);
- glPrint (Addr(RuntimeStr[1]));
-}
-
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, myTex);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(100, 100);
- glTexCoord2f(0,1);glVertex2f(100, 200);
- glTexCoord2f(1,1); glVertex2f(200, 200);
- glTexCoord2f(1,0);glVertex2f(200, 100);
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
-
- // make the stars shine
- GoldenRec.Draw;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenEdit.pas b/Game/Code/Screens/UScreenEdit.pas
deleted file mode 100644
index bf664eb1..00000000
--- a/Game/Code/Screens/UScreenEdit.pas
+++ /dev/null
@@ -1,121 +0,0 @@
-unit UScreenEdit;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu, SDL, UThemes;
-
-type
- TScreenEdit = class(TMenu)
- public
-{ Tex_Background: TTexture;
- FadeOut: boolean;
- Path: string;
- FileName: string;}
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-{ function Draw: boolean; override;
- procedure Finish;}
- end;
-
-implementation
-
-uses UGraphic, UMusic, USkins, SysUtils;
-
-function TScreenEdit.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
-// Result := false;
- end;
- SDLK_RETURN:
- begin
- if Interaction = 0 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenEditConvert);
- end;
-// if Interaction = 1 then begin
-// Music.PlayStart;
-// FadeTo(@ScreenEditHeader);
-// end;
-
- if Interaction = 1 then
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
- end;
-
- SDLK_DOWN:
- begin
- InteractNext;
- end;
- SDLK_UP:
- begin
- InteractPrev;
- end;
- end;
- end;
-end;
-
-constructor TScreenEdit.Create;
-begin
- inherited Create;
- AddButton(400-200, 100 + 0*70, 400, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Convert Midi to Txt');
-// Button[High(Button)].Text[0].Size := 11;
-
-// AddButton(400-200, 100 + 1*60, 400, 40, 'ButtonF');
-// AddButtonText(10, 5, 0, 0, 0, 'Edit Headers');
-
-// AddButton(400-200, 100 + 2*60, 400, 40, 'ButtonF');
-// AddButtonText(10, 5, 0, 0, 0, 'Set GAP');
-
- AddButton(400-200, 100 + 3*60, 400, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Exit');
-
-end;
-
-procedure TScreenEdit.onShow;
-begin
- inherited;
-
-// Interaction := 0;
-end;
-
-(*function TScreenEdit.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-end;
-
-procedure TScreenEdit.Finish;
-begin
-//
-end;*)
-
-end.
diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas
deleted file mode 100644
index dfde696e..00000000
--- a/Game/Code/Screens/UScreenEditConvert.pas
+++ /dev/null
@@ -1,584 +0,0 @@
-unit UScreenEditConvert;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses UMenu,
- SDL,
- {$IFDEF UseMIDIPort}
- MidiFile,
- MidiOut,
- {$ENDIF}
- ULog,
- USongs,
- USong,
- UMusic,
- UThemes;
-
-type
- TNote = record
- Event: integer;
- EventType: integer;
- Channel: integer;
- Start: real;
- Len: real;
- Data1: integer;
- Data2: integer;
- Str: string;
- end;
-
- TTrack = record
- Note: array of TNote;
- Name: string;
- Hear: boolean;
- Status: byte; // 0 - none, 1 - notes, 2 - lyrics, 3 - notes + lyrics
- end;
-
- TNuta = record
- Start: integer;
- Len: integer;
- Tone: integer;
- Lyric: string;
- NewSentence: boolean;
- end;
-
- TArrayTrack = array of TTrack;
-
- TScreenEditConvert = class(TMenu)
- public
- ATrack: TArrayTrack; // actual track
-// Track: TArrayTrack;
- Channel: TArrayTrack;
- ColR: array[0..100] of real;
- ColG: array[0..100] of real;
- ColB: array[0..100] of real;
- Len: real;
- Sel: integer;
- Selected: boolean;
-// FileName: string;
-
- {$IFDEF UseMIDIPort}
- MidiFile: TMidiFile;
- MidiTrack: TMidiTrack;
- MidiEvent: pMidiEvent;
- MidiOut: TMidiOutput;
- {$ENDIF}
-
- Song: TSong;
- Lines: TLines;
- BPM: real;
- Ticks: real;
- Note: array of TNuta;
-
- procedure AddLyric(Start: integer; Text: string);
- procedure Extract;
-
- {$IFDEF UseMIDIPort}
- procedure MidiFile1MidiEvent(event: PMidiEvent);
- {$ENDIF}
-
- function SelectedNumber: integer;
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onHide; override;
- end;
-
-implementation
-uses UGraphic,
- SysUtils,
- UDrawTexture,
- TextGL,
- UFiles,
- UMain,
- UIni,
- gl,
- USkins;
-
-function TScreenEditConvert.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- T: integer;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- {$IFDEF UseMIDIPort}
- MidiFile.StopPlaying;
- {$ENDIF}
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenEdit);
- end;
-
- SDLK_RETURN:
- begin
- if Interaction = 0 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- ScreenOpen.BackScreen := @ScreenEditConvert;
- FadeTo(@ScreenOpen);
- end;
-
- if Interaction = 1 then
- begin
- Selected := false;
- {$IFDEF UseMIDIPort}
- MidiFile.OnMidiEvent := MidiFile1MidiEvent;
-// MidiFile.GoToTime(MidiFile.GetTrackLength div 2);
- MidiFile.StartPlaying;
- {$ENDIF}
- end;
-
- if Interaction = 2 then begin
- Selected := true;
- {$IFDEF UseMIDIPort}
- MidiFile.OnMidiEvent := nil;
- {$ENDIF}
- {for T := 0 to High(ATrack) do begin
- if ATrack[T].Hear then begin
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
- end;
- end;
- MidiFile.StartPlaying;//}
- end;
-
- if Interaction = 3 then begin
- if SelectedNumber > 0 then begin
- Extract;
- SaveSong(Song, Lines, ChangeFileExt(ConversionFileName, '.txt'), false);
- end;
- end;
-
- end;
-
- SDLK_SPACE:
- begin
-// ATrack[Sel].Hear := not ATrack[Sel].Hear;
- ATrack[Sel].Status := (ATrack[Sel].Status + 1) mod 4;
-
-{ if Selected then begin
- MidiTrack := MidiFile.GetTrack(Sel);
- if Track[Sel].Hear then
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent
- else
- MidiTrack.OnMidiEvent := nil;
- end;}
- end;
-
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
-
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
-
- SDLK_DOWN:
- begin
- Inc(Sel);
- if Sel > High(ATrack) then Sel := 0;
- end;
- SDLK_UP:
- begin
- Dec(Sel);
- if Sel < 0 then Sel := High(ATrack);
- end;
- end;
- end;
-end;
-
-procedure TScreenEditConvert.AddLyric(Start: integer; Text: string);
-var
- N: integer;
-begin
- for N := 0 to High(Note) do begin
- if Note[N].Start = Start then begin
- // check for new sentece
- if Copy(Text, 1, 1) = '\' then Delete(Text, 1, 1);
- if Copy(Text, 1, 1) = '/' then begin
- Delete(Text, 1, 1);
- Note[N].NewSentence := true;
- end;
-
- // overwrite lyric od append
- if Note[N].Lyric = '-' then
- Note[N].Lyric := Text
- else
- Note[N].Lyric := Note[N].Lyric + Text;
- end;
- end;
-end;
-
-procedure TScreenEditConvert.Extract;
-var
- T: integer;
- C: integer;
- N: integer;
- Nu: integer;
- NoteTemp: TNuta;
- Move: integer;
- Max, Min: integer;
-begin
- // song info
- Song.Title := '';
- Song.Artist := '';
- Song.Mp3 := '';
- Song.Resolution := 4;
- SetLength(Song.BPM, 1);
- Song.BPM[0].BPM := BPM*4;
-
- SetLength(Note, 0);
-
- // extract notes
- for T := 0 to High(ATrack) do begin
-// if ATrack[T].Hear then begin
- if ((ATrack[T].Status div 1) and 1) = 1 then begin
- for N := 0 to High(ATrack[T].Note) do begin
- if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then begin
- Nu := Length(Note);
- SetLength(Note, Nu + 1);
- Note[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks);
- Note[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks);
- Note[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5;
- Note[Nu].Lyric := '-';
- end;
- end;
- end;
- end;
-
- // extract lyrics
- for T := 0 to High(ATrack) do begin
-// if ATrack[T].Hear then begin
- if ((ATrack[T].Status div 2) and 1) = 1 then begin
- for N := 0 to High(ATrack[T].Note) do begin
- if (ATrack[T].Note[N].EventType = 15) then begin
-// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI');
- AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str);
- end;
- end;
- end;
- end;
-
- // sort notes
- for N := 0 to High(Note) do
- for Nu := 0 to High(Note)-1 do
- if Note[Nu].Start > Note[Nu+1].Start then begin
- NoteTemp := Note[Nu];
- Note[Nu] := Note[Nu+1];
- Note[Nu+1] := NoteTemp;
- end;
-
- // move to 0 at beginning
- Move := Note[0].Start;
- for N := 0 to High(Note) do
- Note[N].Start := Note[N].Start - Move;
-
- // copy notes
- SetLength(Lines.Line, 1);
- Lines.Number := 1;
- Lines.High := 0;
-
- C := 0;
- N := 0;
- Lines.Line[C].HighNote := -1;
-
- for Nu := 0 to High(Note) do begin
- if Note[Nu].NewSentence then begin // nowa linijka
- SetLength(Lines.Line, Length(Lines.Line)+1);
- Lines.Number := Lines.Number + 1;
- Lines.High := Lines.High + 1;
- C := C + 1;
- N := 0;
- SetLength(Lines.Line[C].Note, 0);
- Lines.Line[C].HighNote := -1;
-
- //Calculate Start of the Last Sentence
- if (C > 0) and (Nu > 0) then
- begin
- Max := Note[Nu].Start;
- Min := Note[Nu-1].Start + Note[Nu-1].Len;
-
- case (Max - Min) of
- 0: Lines.Line[C].Start := Max;
- 1: Lines.Line[C].Start := Max;
- 2: Lines.Line[C].Start := Max - 1;
- 3: Lines.Line[C].Start := Max - 2;
- else
- if ((Max - Min) > 4) then
- Lines.Line[C].Start := Min + 2
- else
- Lines.Line[C].Start := Max;
-
- end; // case
-
- end;
- end;
-
- // tworzy miejsce na nowa nute
- SetLength(Lines.Line[C].Note, Length(Lines.Line[C].Note)+1);
-
- // dopisuje
- Lines.Line[C].Note[N].Start := Note[Nu].Start;
- Lines.Line[C].Note[N].Length := Note[Nu].Len;
- Lines.Line[C].Note[N].Tone := Note[Nu].Tone;
- Lines.Line[C].Note[N].Text := Note[Nu].Lyric;
- //All Notes are Freestyle when Converted Fix:
- Lines.Line[C].Note[N].NoteType := ntNormal;
- Inc(N);
- end;
-end;
-
-function TScreenEditConvert.SelectedNumber: integer;
-var
- T: integer; // track
-begin
- Result := 0;
- for T := 0 to High(ATrack) do
-// if ATrack[T].Hear then Inc(Result);
- if ((ATrack[T].Status div 1) and 1) = 1 then Inc(Result);
-end;
-
-{$IFDEF UseMIDIPort}
-procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent);
-begin
-// Log.LogStatus(IntToStr(event.event), 'MIDI');
- MidiOut.PutShort(event.event, event.data1, event.data2);
-end;
-{$ENDIF}
-
-constructor TScreenEditConvert.Create;
-var
- P: integer;
-begin
- inherited Create;
- AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(15, 5, 0, 0, 0, 'Open');
-// Button[High(Button)].Text[0].Size := 11;
-
- AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play');
-
- AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play Selected');
-
- AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(20, 5, 0, 0, 0, 'Save');
-
-
-{ MidiOut := TMidiOutput.Create(nil);
-// MidiOut.Close;
-// MidiOut.DeviceID := 0;
- if Ini.Debug = 1 then
- MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
- Log.LogStatus(MidiOut.ProductName, 'MIDI');
- MidiOut.Open;
-// MidiOut.SetVolume(100, 100); // temporary}
-
- ConversionFileName := GamePath + 'file.mid';
- {$IFDEF UseMIDIPort}
- MidiFile := TMidiFile.Create(nil);
- {$ENDIF}
-
- for P := 0 to 100 do begin
- ColR[P] := Random(10)/10;
- ColG[P] := Random(10)/10;
- ColB[P] := Random(10)/10;
- end;
-
-end;
-
-procedure TScreenEditConvert.onShow;
-var
- T: integer; // track
- N: integer; // note
- C: integer; // channel
- CN: integer; // channel note
-begin
- inherited;
-
-{$IFDEF UseMIDIPort}
- MidiOut := TMidiOutput.Create(nil);
- if Ini.Debug = 1 then
- MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
- Log.LogStatus(MidiOut.ProductName, 'MIDI');
- MidiOut.Open;
-
-
- if FileExists(ConversionFileName) then
- begin
- MidiFile.Filename := ConversionFileName;
- MidiFile.ReadFile;
-
-
- Len := 0;
- Sel := 0;
- BPM := MidiFile.Bpm;
- Ticks := MidiFile.TicksPerQuarter / 4;
-
-{ for T := 0 to MidiFile.NumberOfTracks-1 do begin
- SetLength(Track, Length(Track)+1);
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
- Track[T].Name := MidiTrack.getName;
-
- for N := 0 to MidiTrack.getEventCount-1 do begin
- SetLength(Track[T].Note, Length(Track[T].Note)+1);
- MidiEvent := MidiTrack.GetEvent(N);
- Track[T].Note[N].Start := MidiEvent.time;
- Track[T].Note[N].Len := MidiEvent.len;
- Track[T].Note[N].Event := MidiEvent.event;
- Track[T].Note[N].EventType := MidiEvent.event div 16;
- Track[T].Note[N].Channel := MidiEvent.event and 15;
- Track[T].Note[N].Data1 := MidiEvent.data1;
- Track[T].Note[N].Data2 := MidiEvent.data2;
- Track[T].Note[N].Str := MidiEvent.str;
-
- if Track[T].Note[N].Start + Track[T].Note[N].Len > Len then
- Len := Track[T].Note[N].Start + Track[T].Note[N].Len;
- end;
- end;}
-
-
- SetLength(Channel, 16);
- for T := 0 to 15 do
- begin
- Channel[T].Name := IntToStr(T+1);
- SetLength(Channel[T].Note, 0);
- Channel[T].Status := 0;
- end;
-
- for T := 0 to MidiFile.NumberOfTracks-1 do begin
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
-
- for N := 0 to MidiTrack.getEventCount-1 do begin
- MidiEvent := MidiTrack.GetEvent(N);
- C := MidiEvent.event and 15;
-
- CN := Length(Channel[C].Note);
- SetLength(Channel[C].Note, CN+1);
-
- Channel[C].Note[CN].Start := MidiEvent.time;
- Channel[C].Note[CN].Len := MidiEvent.len;
- Channel[C].Note[CN].Event := MidiEvent.event;
- Channel[C].Note[CN].EventType := MidiEvent.event div 16;
- Channel[C].Note[CN].Channel := MidiEvent.event and 15;
- Channel[C].Note[CN].Data1 := MidiEvent.data1;
- Channel[C].Note[CN].Data2 := MidiEvent.data2;
- Channel[C].Note[CN].Str := MidiEvent.str;
-
- if Channel[C].Note[CN].Start + Channel[C].Note[CN].Len > Len then
- Len := Channel[C].Note[CN].Start + Channel[C].Note[CN].Len;
- end;
- end;
- ATrack := Channel;
-
- end;
-
- Interaction := 0;
-{$ENDIF}
-end;
-
-function TScreenEditConvert.Draw: boolean;
-var
- Pet: integer;
- Pet2: integer;
- Bottom: real;
- X: real;
- Y: real;
- H: real;
- YSkip: real;
-begin
- // draw static menu
- inherited Draw;
-
- Y := 100;
-
- H := Length(ATrack)*40;
- if H > 480 then H := 480;
- Bottom := Y + H;
-
- YSkip := H / Length(ATrack);
-
- // select
- DrawQuad(10, Y+Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8);
-
- // selected - now me use Status System
- for Pet := 0 to High(ATrack) do
- if ATrack[Pet].Hear then
- DrawQuad(10, Y+Pet*YSkip, 50, YSkip, 0.8, 0.3, 0.3);
- glColor3f(0, 0, 0);
- for Pet := 0 to High(ATrack) do begin
- if ((ATrack[Pet].Status div 1) and 1) = 1 then begin
- SetFontPos(25, Y + Pet*YSkip + 10);
- SetFontSize(5);
- glPrint('N');
- end;
- if ((ATrack[Pet].Status div 2) and 1) = 1 then begin
- SetFontPos(40, Y + Pet*YSkip + 10);
- SetFontSize(5);
- glPrint('L');
- end;
- end;
-
- DrawLine(10, Y, 10, Bottom, 0, 0, 0);
- DrawLine(60, Y, 60, Bottom, 0, 0, 0);
- DrawLine(790, Y, 790, Bottom, 0, 0, 0);
-
- for Pet := 0 to Length(ATrack) do
- DrawLine(10, Y+Pet*YSkip, 790, Y+Pet*YSkip, 0, 0, 0);
-
- for Pet := 0 to High(ATrack) do begin
- SetFontPos(11, Y + 10 + Pet*YSkip);
- SetFontSize(5);
- glPrint(pchar(ATrack[Pet].Name));
- end;
-
- for Pet := 0 to High(ATrack) do
- for Pet2 := 0 to High(ATrack[Pet].Note) do begin
- if ATrack[Pet].Note[Pet2].EventType = 9 then
- DrawQuad(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + (Pet+1)*YSkip - ATrack[Pet].Note[Pet2].Data1*35/127, 3, 3, ColR[Pet], ColG[Pet], ColB[Pet]);
- if ATrack[Pet].Note[Pet2].EventType = 15 then
- DrawLine(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + 0.75 * YSkip + Pet*YSkip, 60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + YSkip + Pet*YSkip, ColR[Pet], ColG[Pet], ColB[Pet]);
- end;
-
- // playing line
- {$IFDEF UseMIDIPort}
- X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730;
- {$ENDIF}
- DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3);
-
- Result := true;
-end;
-
-procedure TScreenEditConvert.onHide;
-begin
-{$IFDEF UseMIDIPort}
- MidiOut.Close;
- MidiOut.Free;
-{$ENDIF}
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas
deleted file mode 100644
index 28bf7682..00000000
--- a/Game/Code/Screens/UScreenEditHeader.pas
+++ /dev/null
@@ -1,380 +0,0 @@
-unit UScreenEditHeader;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu,
- SDL,
- USongs,
- USong,
- UThemes;
-
-type
- TScreenEditHeader = class(TMenu)
- public
- CurrentSong: TSong;
- TextTitle: integer;
- TextArtist: integer;
- TextMp3: integer;
- TextBackground: integer;
- TextVideo: integer;
- TextVideoGAP: integer;
- TextRelative: integer;
- TextResolution: integer;
- TextNotesGAP: integer;
- TextStart: integer;
- TextGAP: integer;
- TextBPM: integer;
- StaticTitle: integer;
- StaticArtist: integer;
- StaticMp3: integer;
- StaticBackground: integer;
- StaticVideo: integer;
- StaticVideoGAP: integer;
- StaticRelative: integer;
- StaticResolution: integer;
- StaticNotesGAP: integer;
- StaticStart: integer;
- StaticGAP: integer;
- StaticBPM: integer;
- Sel: array[0..11] of boolean;
- procedure SetRoundButtons;
-
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-{ function Draw: boolean; override;
- procedure Finish;}
- end;
-
-implementation
-
-uses UGraphic, UMusic, SysUtils, UFiles, USkins, UTexture;
-
-function TScreenEditHeader.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- T: integer;
-begin
- Result := true;
- If (PressedDown) Then begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE :
- begin
-// Music.PlayBack;
-// FadeTo(@MainScreen);
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- if Interaction = 1 then begin
-// Save;
- end;
- end;
-
- SDLK_RIGHT:
- begin
- case Interaction of
- 0..0: InteractNext;
- 1: Interaction := 0;
- end;
- end;
-
- SDLK_LEFT:
- begin
- case Interaction of
- 0: Interaction := 1;
- 1..1: InteractPrev;
- end;
- end;
-
- SDLK_DOWN:
- begin
- case Interaction of
- 0..1: Interaction := 2;
- 2..12: InteractNext;
- 13: Interaction := 0;
- end;
- end;
-
- SDLK_UP:
- begin
- case Interaction of
- 0..1: Interaction := 13;
- 2: Interaction := 0;
- 3..13: InteractPrev;
- end;
- end;
-
- SDLK_BACKSPACE:
- begin
- T := Interaction - 2 + TextTitle;
- if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin
- Text[T].DeleteLastL;
- SetRoundButtons;
- end;
- end;
-
- end;
- case CharCode of
- #32..#255:
- begin
- if (Interaction >= 2) and (Interaction <= 13) then begin
- Text[Interaction - 2 + TextTitle].Text :=
- Text[Interaction - 2 + TextTitle].Text + CharCode;
- SetRoundButtons;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenEditHeader.Create;
-begin
- inherited Create;
-
- AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(15, 5, 'Open');
-
- AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(20, 5, 'Save');
-
- AddBox(80, 60, 640, 550);
-
- AddText(160, 110 + 0*30, 0, 10, 0, 0, 0, 'Title:');
- AddText(160, 110 + 1*30, 0, 10, 0, 0, 0, 'Artist:');
- AddText(160, 110 + 2*30, 0, 10, 0, 0, 0, 'MP3:');
-
- AddText(160, 110 + 4*30, 0, 10, 0, 0, 0, 'Background:');
- AddText(160, 110 + 5*30, 0, 10, 0, 0, 0, 'Video:');
- AddText(160, 110 + 6*30, 0, 10, 0, 0, 0, 'VideoGAP:');
-
- AddText(160, 110 + 8*30, 0, 10, 0, 0, 0, 'Relative:');
- AddText(160, 110 + 9*30, 0, 10, 0, 0, 0, 'Resolution:');
- AddText(160, 110 + 10*30, 0, 10, 0, 0, 0, 'NotesGAP:');
-
- AddText(160, 110 + 12*30, 0, 10, 0, 0, 0, 'Start:');
- AddText(160, 110 + 13*30, 0, 10, 0, 0, 0, 'GAP:');
- AddText(160, 110 + 14*30, 0, 10, 0, 0, 0, 'BPM:');
-
- TextTitle := AddText(340, 110 + 0*30, 0, 10, 0, 0, 0, '');
- TextArtist := AddText(340, 110 + 1*30, 0, 10, 0, 0, 0, '');
- TextMp3 := AddText(340, 110 + 2*30, 0, 10, 0, 0, 0, '');
-
- TextBackground := AddText(340, 110 + 4*30, 0, 10, 0, 0, 0, '');
- TextVideo := AddText(340, 110 + 5*30, 0, 10, 0, 0, 0, '');
- TextVideoGAP := AddText(340, 110 + 6*30, 0, 10, 0, 0, 0, '');
-
- TextRelative := AddText(340, 110 + 8*30, 0, 10, 0, 0, 0, '');
- TextResolution := AddText(340, 110 + 9*30, 0, 10, 0, 0, 0, '');
- TextNotesGAP := AddText(340, 110 + 10*30, 0, 10, 0, 0, 0, '');
-
- TextStart := AddText(340, 110 + 12*30, 0, 10, 0, 0, 0, '');
- TextGAP := AddText(340, 110 + 13*30, 0, 10, 0, 0, 0, '');
- TextBPM := AddText(340, 110 + 14*30, 0, 10, 0, 0, 0, '');
-
- StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
-
- AddInteraction(iText, TextTitle);
- AddInteraction(iText, TextArtist);
- AddInteraction(iText, TextMp3);
- AddInteraction(iText, TextBackground);
- AddInteraction(iText, TextVideo);
- AddInteraction(iText, TextVideoGAP);
- AddInteraction(iText, TextRelative);
- AddInteraction(iText, TextResolution);
- AddInteraction(iText, TextNotesGAP);
- AddInteraction(iText, TextStart);
- AddInteraction(iText, TextGAP);
- AddInteraction(iText, TextBPM);
-end;
-
-procedure TScreenEditHeader.onShow;
-begin
- inherited;
-
-{ if FileExists(FileName) then begin // load file
- CurrentSong.FileName := FileName;
- SkanujPlik(CurrentSong);
-
- SetLength(TrueBoolStrs, 1);
- TrueBoolStrs[0] := 'yes';
- SetLength(FalseBoolStrs, 1);
- FalseBoolStrs[0] := 'no';
-
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextMP3].Text := CurrentSong.Mp3;
- Text[TextBackground].Text := CurrentSong.Background;
- Text[TextVideo].Text := CurrentSong.Video;
- Text[TextVideoGAP].Text := FloatToStr(CurrentSong.VideoGAP);
- Text[TextRelative].Text := BoolToStr(CurrentSong.Relative, true);
- Text[TextResolution].Text := IntToStr(CurrentSong.Resolution);
- Text[TextNotesGAP].Text := IntToStr(CurrentSong.NotesGAP);
- Text[TextStart].Text := FloatToStr(CurrentSong.Start);
- Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
- Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM);
- SetRoundButtons;
- end;}
-
- Interaction := 0;
-end;
-
-(*function TScreenEdit.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-{ glClearColor(1,1,1,1);
-
- // control music
- if PlaySentence then begin
- // stop the music
- if (Music.Position > PlayStopTime) then begin
- Music.Stop;
- PlaySentence := false;
- end;
-
- // click
- if (Click) and (PlaySentence) then begin
- AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
- Text[TextDebug].Text := IntToStr(AktBeat);
- if AktBeat <> LastClick then begin
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
- Music.PlayClick;
- LastClick := AktBeat;
- end;
- end;
- end; // click
- end; // if PlaySentence
-
- Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
- Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].LengthNote);
-
- // Song info
- Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
- Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
-
- // Note info
- Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
- Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
-
- // draw static menu
- inherited Draw;
-
- // draw notes
- SingDrawNoteLines(20, 300, 780, 15);
- SingDrawBeatDelimeters(40, 300, 760, 0);
- SingDrawCzesc(40, 405, 760, 0);
-
- // draw text
- Lyric.Draw;}
-
-end;*)
-
-procedure TScreenEditHeader.SetRoundButtons;
-begin
- if Length(Text[TextTitle].Text) > 0 then Static[StaticTitle].Visible := true
- else Static[StaticTitle].Visible := false;
-
- if Length(Text[TextArtist].Text) > 0 then Static[StaticArtist].Visible := true
- else Static[StaticArtist].Visible := false;
-
- if Length(Text[TextMp3].Text) > 0 then Static[StaticMp3].Visible := true
- else Static[StaticMp3].Visible := false;
-
- if Length(Text[TextBackground].Text) > 0 then Static[StaticBackground].Visible := true
- else Static[StaticBackground].Visible := false;
-
- if Length(Text[TextVideo].Text) > 0 then Static[StaticVideo].Visible := true
- else Static[StaticVideo].Visible := false;
-
- try
- StrToFloat(Text[TextVideoGAP].Text);
- if StrToFloat(Text[TextVideoGAP].Text)<> 0 then Static[StaticVideoGAP].Visible := true
- else Static[StaticVideoGAP].Visible := false;
- except
- Static[StaticVideoGAP].Visible := false;
- end;
-
- if LowerCase(Text[TextRelative].Text) = 'yes' then Static[StaticRelative].Visible := true
- else Static[StaticRelative].Visible := false;
-
- try
- StrToInt(Text[TextResolution].Text);
- if (StrToInt(Text[TextResolution].Text) <> 0) and (StrToInt(Text[TextResolution].Text) >= 1)
- then Static[StaticResolution].Visible := true
- else Static[StaticResolution].Visible := false;
- except
- Static[StaticResolution].Visible := false;
- end;
-
- try
- StrToInt(Text[TextNotesGAP].Text);
- Static[StaticNotesGAP].Visible := true;
- except
- Static[StaticNotesGAP].Visible := false;
- end;
-
- // start
- try
- StrToFloat(Text[TextStart].Text);
- if (StrToFloat(Text[TextStart].Text) > 0) then Static[StaticStart].Visible := true
- else Static[StaticStart].Visible := false;
- except
- Static[StaticStart].Visible := false;
- end;
-
- // GAP
- try
- StrToFloat(Text[TextGAP].Text);
- Static[StaticGAP].Visible := true;
- except
- Static[StaticGAP].Visible := false;
- end;
-
- // BPM
- try
- StrToFloat(Text[TextBPM].Text);
- if (StrToFloat(Text[TextBPM].Text) > 0) then Static[StaticBPM].Visible := true
- else Static[StaticBPM].Visible := false;
- except
- Static[StaticBPM].Visible := false;
- end;
-
-end;
-
-(*procedure TScreenEdit.Finish;
-begin
-//
-end;*)
-
-end.
diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas
deleted file mode 100644
index 2d98f6bc..00000000
--- a/Game/Code/Screens/UScreenEditSub.pas
+++ /dev/null
@@ -1,1368 +0,0 @@
-unit UScreenEditSub;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-{$I switches.inc}
-
-uses
- UMenu,
- UMusic,
- SDL,
- SysUtils,
- UFiles,
- UTime,
- USongs,
- USong,
- UIni,
- ULog,
- UTexture,
- UMenuText,
- UEditorLyrics,
- Math,
- gl,
- {$IFDEF UseMIDIPort}
- MidiOut,
- {$ENDIF}
- UThemes;
-
-type
- TScreenEditSub = class(TMenu)
- private
- //Variable is True if no Song is loaded
- Error: Boolean;
-
- TextNote: integer;
- TextSentence: integer;
- TextTitle: integer;
- TextArtist: integer;
- TextMp3: integer;
- TextBPM: integer;
- TextGAP: integer;
- TextDebug: integer;
- TextNStart: integer;
- TextNLength: integer;
- TextNTon: integer;
- TextNText: integer;
- CurrentNote: integer;
- PlaySentence: boolean;
- PlaySentenceMidi: boolean;
- PlayStopTime: real;
- LastClick: integer;
- Click: boolean;
- CopySrc: integer;
-
- {$IFDEF UseMIDIPort}
- MidiOut: TMidiOutput;
- {$endif}
-
- MidiStart: real;
- MidiStop: real;
- MidiTime: real;
- MidiPos: real;
- MidiLastNote: integer;
-
- TextEditMode: boolean;
-
- Lyric: TEditorLyrics;
-
- procedure NewBeat;
- procedure DivideBPM;
- procedure MultiplyBPM;
- procedure LyricsCapitalize;
- procedure LyricsCorrectSpaces;
- procedure FixTimings;
- procedure DivideSentence;
- procedure JoinSentence;
- procedure DivideNote;
- procedure DeleteNote;
- procedure TransposeNote(Transpose: integer);
- procedure ChangeWholeTone(Tone: integer);
- procedure MoveAllToEnd(Move: integer);
- procedure MoveTextToRight;
- procedure MarkSrc;
- procedure PasteText;
- procedure CopySentence(Src, Dst: integer);
- procedure CopySentences(Src, Dst, Num: integer);
- //Note Name Mod
- function GetNoteName(Note: Integer): String;
- public
- Tex_Background: TTexture;
- FadeOut: boolean;
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function ParseInputEditText(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
- function Draw: boolean; override;
- procedure onHide; override;
- end;
-
-implementation
-
-uses
- UGraphic,
- UDraw,
- UMain,
- USkins,
- ULanguage;
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenEditSub.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- SDL_ModState: Word;
- R: real;
-begin
- Result := true;
-
- if TextEditMode then begin
- Result := ParseInputEditText(PressedKey, CharCode, PressedDown);
- end else begin
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
-
- If (PressedDown) then begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- 'S':
- begin
- // Save Song
- if SDL_ModState = KMOD_LSHIFT then
- SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, true)
- else
- SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, false);
-
- {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
- // Save Song
- SaveSongDebug(CurrentSong, Lines[0], 'C:\song.asm', false);}
-
- Exit;
- end;
- 'D':
- begin
- // Divide lengths by 2
- DivideBPM;
- Exit;
- end;
- 'M':
- begin
- // Multiply lengths by 2
- MultiplyBPM;
- Exit;
- end;
- 'C':
- begin
- // Capitalize letter at the beginning of line
- if SDL_ModState = 0 then
- LyricsCapitalize;
-
- // Correct spaces
- if SDL_ModState = KMOD_LSHIFT then
- LyricsCorrectSpaces;
-
- // Copy sentence
- if SDL_ModState = KMOD_LCTRL then
- MarkSrc;
-
- Exit;
- end;
- 'V':
- begin
- // Paste text
- if SDL_ModState = KMOD_LCTRL then begin
- if Lines[0].Line[Lines[0].Current].HighNote >= Lines[0].Line[CopySrc].HighNote then
- PasteText
- else
- Log.LogStatus('PasteText: invalid range', 'TScreenEditSub.ParseInput');
- end;
-
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
- CopySentence(CopySrc, Lines[0].Current);
- end;
- end;
- 'T':
- begin
- // Fixes timings between sentences
- FixTimings;
- Exit;
- end;
- 'P':
- begin
- if SDL_ModState = 0 then
- begin
- // Play Sentence
- Click := true;
- AudioPlayback.Stop;
- R := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
- if R <= AudioPlayback.Length then
- begin
- AudioPlayback.Position := R;
- PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
- PlaySentence := true;
- AudioPlayback.Play;
- LastClick := -100;
- end;
- end
- else if SDL_ModState = KMOD_LSHIFT then
- begin
- PlaySentenceMidi := true;
-
- MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
- MidiStop := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
-
- LastClick := -100;
- end
- else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then
- begin
- PlaySentenceMidi := true;
- MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
- MidiStop := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
- LastClick := -100;
-
- PlaySentence := true;
- Click := true;
- AudioPlayback.Stop;
- AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start)+0{-0.10};
- PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_)+0;
- AudioPlayback.Play;
- LastClick := -100;
- end;
- Exit;
- end;
-
- // Golden Note Patch
- 'G':
- begin
- if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntGolden) then
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
- else
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntGolden;
-
- Exit;
- end;
-
- // Freestyle Note Patch
- 'F':
- begin
- if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntFreestyle) then
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
- else
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntFreestyle;
-
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- FadeTo(@ScreenSong);
- end;
-
- SDLK_BACKQUOTE:
- begin
- // Increase Note Length (same as Alt + Right)
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
- Inc(Lines[0].Line[Lines[0].Current].End_);
- end;
-
- SDLK_EQUALS:
- begin
- // Increase BPM
- if SDL_ModState = 0 then
- CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
- if SDL_ModState = KMOD_LSHIFT then
- CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM + 4; // (1/1)
- if SDL_ModState = KMOD_LCTRL then
- CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
- end;
-
- SDLK_MINUS:
- begin
- // Decrease BPM
- if SDL_ModState = 0 then
- CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) - 1) / 5;
- if SDL_ModState = KMOD_LSHIFT then
- CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM - 4;
- if SDL_ModState = KMOD_LCTRL then
- CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) - 1) / 25;
- end;
-
- SDLK_4:
- begin
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
- CopySentence(CopySrc, Lines[0].Current);
- CopySentence(CopySrc+1, Lines[0].Current+1);
- CopySentence(CopySrc+2, Lines[0].Current+2);
- CopySentence(CopySrc+3, Lines[0].Current+3);
- end;
-
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
- CopySentences(CopySrc, Lines[0].Current, 4);
- end;
- end;
- SDLK_5:
- begin
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
- CopySentence(CopySrc, Lines[0].Current);
- CopySentence(CopySrc+1, Lines[0].Current+1);
- CopySentence(CopySrc+2, Lines[0].Current+2);
- CopySentence(CopySrc+3, Lines[0].Current+3);
- CopySentence(CopySrc+4, Lines[0].Current+4);
- end;
-
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
- CopySentences(CopySrc, Lines[0].Current, 5);
- end;
- end;
-
- SDLK_9:
- begin
- // Decrease GAP
- if SDL_ModState = 0 then
- CurrentSong.GAP := CurrentSong.GAP - 10;
- if SDL_ModState = KMOD_LSHIFT then
- CurrentSong.GAP := CurrentSong.GAP - 1000;
- end;
- SDLK_0:
- begin
- // Increase GAP
- if SDL_ModState = 0 then
- CurrentSong.GAP := CurrentSong.GAP + 10;
- if SDL_ModState = KMOD_LSHIFT then
- CurrentSong.GAP := CurrentSong.GAP + 1000;
- end;
-
- SDLK_KP_PLUS:
- begin
- // Increase tone of all notes
- if SDL_ModState = 0 then
- ChangeWholeTone(1);
- if SDL_ModState = KMOD_LSHIFT then
- ChangeWholeTone(12);
- end;
-
- SDLK_KP_MINUS:
- begin
- // Decrease tone of all notes
- if SDL_ModState = 0 then
- ChangeWholeTone(-1);
- if SDL_ModState = KMOD_LSHIFT then
- ChangeWholeTone(-12);
- end;
-
- SDLK_SLASH:
- begin
- if SDL_ModState = 0 then begin
- // Insert start of sentece
- if CurrentNote > 0 then
- DivideSentence;
- end;
-
- if SDL_ModState = KMOD_LSHIFT then begin
- // Join next sentence with current
- if Lines[0].Current < Lines[0].High then
- JoinSentence;
- end;
-
- if SDL_ModState = KMOD_LCTRL then begin
- // divide note
- DivideNote;
- end;
-
- end;
-
- SDLK_F4:
- begin
- // Enter Text Edit Mode
- TextEditMode := true;
- end;
-
- SDLK_SPACE:
- begin
- // Play Sentence
- PlaySentenceMidi := false; // stop midi
- PlaySentence := true;
- Click := false;
- AudioPlayback.Stop;
- AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
- PlayStopTime := (GetTimeFromBeat(
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start +
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length));
- AudioPlayback.Play;
- LastClick := -100;
- end;
-
- SDLK_RETURN:
- begin
- end;
-
- SDLK_LCTRL:
- begin
- end;
-
- SDLK_DELETE:
- begin
- if SDL_ModState = KMOD_LCTRL then begin
- // moves text to right in current sentence
- DeleteNote;
- end;
- end;
-
- SDLK_PERIOD:
- begin
- // moves text to right in current sentence
- MoveTextToRight;
- end;
-
- SDLK_RIGHT:
- begin
- // right
- if SDL_ModState = 0 then begin
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Inc(CurrentNote);
- if CurrentNote > Lines[0].Line[Lines[0].Current].HighNote then CurrentNote := 0;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- Lyric.Selected := CurrentNote;
- end;
-
- // ctrl + right
- if SDL_ModState = KMOD_LCTRL then begin
- if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then begin
- Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
- if CurrentNote = 0 then begin
- Inc(Lines[0].Line[Lines[0].Current].Start);
- end;
- end;
- end;
-
- // shift + right
- if SDL_ModState = KMOD_LSHIFT then begin
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
- if CurrentNote = 0 then begin
- Inc(Lines[0].Line[Lines[0].Current].Start);
- end;
- if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
- Inc(Lines[0].Line[Lines[0].Current].End_);
- end;
-
- // alt + right
- if SDL_ModState = KMOD_LALT then begin
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
- Inc(Lines[0].Line[Lines[0].Current].End_);
- end;
-
- // alt + ctrl + shift + right = move all from cursor to right
- if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
- MoveAllToEnd(1);
- end;
-
- end;
-
- SDLK_LEFT:
- begin
- // left
- if SDL_ModState = 0 then begin
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Dec(CurrentNote);
- if CurrentNote = -1 then CurrentNote := Lines[0].Line[Lines[0].Current].HighNote;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- Lyric.Selected := CurrentNote;
- end;
-
- // ctrl + left
- if SDL_ModState = KMOD_LCTRL then begin
- Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- if CurrentNote = 0 then begin
- Dec(Lines[0].Line[Lines[0].Current].Start);
- end;
- end;
-
- // shift + left
- if SDL_ModState = KMOD_LSHIFT then begin
- Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
-
- // resizing sentences
- if CurrentNote = 0 then begin
- Dec(Lines[0].Line[Lines[0].Current].Start);
- end;
-
- if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
- Dec(Lines[0].Line[Lines[0].Current].End_);
-
- end;
-
- // alt + left
- if SDL_ModState = KMOD_LALT then begin
- if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then begin
- Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
- Dec(Lines[0].Line[Lines[0].Current].End_);
- end;
- end;
-
- // alt + ctrl + shift + right = move all from cursor to left
- if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
- MoveAllToEnd(-1);
- end;
-
- end;
-
- SDLK_DOWN:
- begin
-
- // skip to next sentence
- if SDL_ModState = 0 then begin {$IFDEF UseMIDIPort}
- MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
- PlaySentenceMidi := false;
- {$endif}
-
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Inc(Lines[0].Current);
- CurrentNote := 0;
- if Lines[0].Current > Lines[0].High then Lines[0].Current := 0;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
-
- Lyric.AddLine(Lines[0].Current);
- Lyric.Selected := 0;
- AudioPlayback.Stop;
- PlaySentence := false;
- end;
-
- // decrease tone
- if SDL_ModState = KMOD_LCTRL then begin
- TransposeNote(-1);
- end;
-
- end;
-
- SDLK_UP:
- begin
-
- // skip to previous sentence
- if SDL_ModState = 0 then begin
- {$IFDEF UseMIDIPort}
- MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
- PlaySentenceMidi := false;
- {$endif}
-
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Dec(Lines[0].Current);
- CurrentNote := 0;
- if Lines[0].Current = -1 then Lines[0].Current := Lines[0].High;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
-
- Lyric.AddLine(Lines[0].Current);
- Lyric.Selected := 0;
- AudioPlayback.Stop;
- PlaySentence := false;
- end;
-
- // increase tone
- if SDL_ModState = KMOD_LCTRL then begin
- TransposeNote(1);
- end;
- end;
-
- end; // case
- end;
- end; // if
-end;
-
-function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- SDL_ModState: Word;
-begin
- // used when in Text Edit Mode
- Result := true;
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
-
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
-
- SDLK_ESCAPE:
- begin
- FadeTo(@ScreenSong);
- end;
- SDLK_F4, SDLK_RETURN:
- begin
- // Exit Text Edit Mode
- TextEditMode := false;
- end;
- SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL:
- begin
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text :=
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text + CharCode;
- end;
- SDLK_BACKSPACE:
- begin
- Delete(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text,
- Length(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text), 1);
- end;
- SDLK_RIGHT:
- begin
- // right
- if SDL_ModState = 0 then begin
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Inc(CurrentNote);
- if CurrentNote > Lines[0].Line[Lines[0].Current].HighNote then CurrentNote := 0;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- Lyric.Selected := CurrentNote;
- end;
- end;
- SDLK_LEFT:
- begin
- // left
- if SDL_ModState = 0 then begin
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
- Dec(CurrentNote);
- if CurrentNote = -1 then CurrentNote := Lines[0].Line[Lines[0].Current].HighNote;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- Lyric.Selected := CurrentNote;
- end;
- end;
- end;
- end;
-end;
-
-procedure TScreenEditSub.NewBeat;
-begin
- // click
-{ for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNut do
- if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = Czas.AktBeat) then begin
- // old}
-// Music.PlayClick;
-end;
-
-procedure TScreenEditSub.DivideBPM;
-var
- C: integer;
- N: integer;
-begin
- CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM / 2;
- for C := 0 to Lines[0].High do begin
- Lines[0].Line[C].Start := Lines[0].Line[C].Start div 2;
- Lines[0].Line[C].End_ := Lines[0].Line[C].End_ div 2;
- for N := 0 to Lines[0].Line[C].HighNote do begin
- Lines[0].Line[C].Note[N].Start := Lines[0].Line[C].Note[N].Start div 2;
- Lines[0].Line[C].Note[N].Length := Round(Lines[0].Line[C].Note[N].Length / 2);
- end; // N
- end; // C
-end;
-
-procedure TScreenEditSub.MultiplyBPM;
-var
- C: integer;
- N: integer;
-begin
- CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM * 2;
- for C := 0 to Lines[0].High do begin
- Lines[0].Line[C].Start := Lines[0].Line[C].Start * 2;
- Lines[0].Line[C].End_ := Lines[0].Line[C].End_ * 2;
- for N := 0 to Lines[0].Line[C].HighNote do begin
- Lines[0].Line[C].Note[N].Start := Lines[0].Line[C].Note[N].Start * 2;
- Lines[0].Line[C].Note[N].Length := Lines[0].Line[C].Note[N].Length * 2;
- end; // N
- end; // C
-end;
-
-procedure TScreenEditSub.LyricsCapitalize;
-var
- C: integer;
- N: integer; // temporary
- S: string;
-begin
- // temporary
-{ for C := 0 to Lines[0].High do
- for N := 0 to Lines[0].Line[C].HighNut do
- Lines[0].Line[C].Note[N].Text := AnsiLowerCase(Lines[0].Line[C].Note[N].Text);}
-
- for C := 0 to Lines[0].High do begin
- S := AnsiUpperCase(Copy(Lines[0].Line[C].Note[0].Text, 1, 1));
- S := S + Copy(Lines[0].Line[C].Note[0].Text, 2, Length(Lines[0].Line[C].Note[0].Text)-1);
- Lines[0].Line[C].Note[0].Text := S;
- end; // C
-end;
-
-procedure TScreenEditSub.LyricsCorrectSpaces;
-var
- C: integer;
- N: integer;
-begin
- for C := 0 to Lines[0].High do begin
- // correct starting spaces in the first word
- while Copy(Lines[0].Line[C].Note[0].Text, 1, 1) = ' ' do
- Lines[0].Line[C].Note[0].Text := Copy(Lines[0].Line[C].Note[0].Text, 2, 100);
-
- // move spaces on the start to the end of the previous note
- for N := 1 to Lines[0].Line[C].HighNote do begin
- while (Copy(Lines[0].Line[C].Note[N].Text, 1, 1) = ' ') do begin
- Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 2, 100);
- Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
- end;
- end; // N
-
- // correct '-' to '- '
- for N := 0 to Lines[0].Line[C].HighNote do begin
- if Lines[0].Line[C].Note[N].Text = '-' then
- Lines[0].Line[C].Note[N].Text := '- ';
- end; // N
-
- // add space to the previous note when the current word is '- '
- for N := 1 to Lines[0].Line[C].HighNote do begin
- if Lines[0].Line[C].Note[N].Text = '- ' then
- Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
- end; // N
-
- // correct too many spaces at the end of note
- for N := 0 to Lines[0].Line[C].HighNote do begin
- while Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text)-1, 2) = ' ' do
- Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 1, Length(Lines[0].Line[C].Note[N].Text)-1);
- end; // N
-
- // and correct if there is no space at the end of sentence
- N := Lines[0].Line[C].HighNote;
- if Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text), 1) <> ' ' then
- Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N].Text + ' ';
-
- end; // C
-end;
-
-procedure TScreenEditSub.FixTimings;
-var
- C: integer;
- S: integer;
- Min: integer;
- Max: integer;
-begin
- for C := 1 to Lines[0].High do begin
- with Lines[0].Line[C-1] do begin
- Min := Note[HighNote].Start + Note[HighNote].Length;
- Max := Lines[0].Line[C].Note[0].Start;
- case (Max - Min) of
- 0: S := Max;
- 1: S := Max;
- 2: S := Max - 1;
- 3: S := Max - 2;
- else
- if ((Max - Min) > 4) then
- S := Min + 2
- else
- S := Max;
- end; // case
-
- Lines[0].Line[C].Start := S;
- end; // with
- end; // for
-end;
-
-procedure TScreenEditSub.DivideSentence;
-var
- C: integer;
- CStart: integer;
- CNew: integer;
- CLen: integer;
- N: integer;
- NStart: integer;
- NHigh: integer;
-begin
- // increase sentence length by 1
- CLen := Length(Lines[0].Line);
- SetLength(Lines[0].Line, CLen + 1);
- Inc(Lines[0].Number);
- Inc(Lines[0].High);
-
- // move needed sentences to one forward. newly has the copy of divided sentence
- CStart := Lines[0].Current;
- for C := CLen-1 downto CStart do
- Lines[0].Line[C+1] := Lines[0].Line[C];
-
- // clear and set new sentence
- CNew := CStart + 1;
- NStart := CurrentNote;
- Lines[0].Line[CNew].Start := Lines[0].Line[CStart].Note[NStart].Start;
- Lines[0].Line[CNew].Lyric := '';
- Lines[0].Line[CNew].LyricWidth := 0;
- Lines[0].Line[CNew].End_ := 0;
- Lines[0].Line[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
- Lines[0].Line[CNew].HighNote := -1;
- SetLength(Lines[0].Line[CNew].Note, 0);
-
- // move right notes to new sentences
- NHigh := Lines[0].Line[CStart].HighNote;
- for N := NStart to NHigh do begin
- // increase sentence counters
- with Lines[0].Line[CNew] do
- begin
- Inc(HighNote);
- SetLength(Note, HighNote + 1);
- Note[HighNote] := Note[N];
- End_ := Note[HighNote].Start + Note[HighNote].Length;
-
- if Note[HighNote].Tone < BaseNote then
- BaseNote := Note[HighNote].Tone;
- end;
- end;
-
- // clear old notes and set sentence counters
- Lines[0].Line[CStart].HighNote := NStart - 1;
- Lines[0].Line[CStart].End_ := Lines[0].Line[CStart].Note[NStart-1].Start +
- Lines[0].Line[CStart].Note[NStart-1].Length;
- SetLength(Lines[0].Line[CStart].Note, Lines[0].Line[CStart].HighNote + 1);
-
- Lines[0].Current := Lines[0].Current + 1;
- CurrentNote := 0;
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- Lyric.AddLine(Lines[0].Current);
-end;
-
-procedure TScreenEditSub.JoinSentence;
-var
- C: integer;
- N: integer;
- NStart: integer;
- NDst: integer;
-begin
- C := Lines[0].Current;
-
- // set new sentence
- NStart := Lines[0].Line[C].HighNote + 1;
- Lines[0].Line[C].HighNote := Lines[0].Line[C].HighNote + Lines[0].Line[C+1].HighNote + 1;
- SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);
-
- // move right notes to new sentences
- for N := 0 to Lines[0].Line[C+1].HighNote do begin
- NDst := NStart + N;
- Lines[0].Line[C].Note[NDst] := Lines[0].Line[C+1].Note[N];
- end;
-
- // increase sentence counters
- NDst := Lines[0].Line[C].HighNote;
- Lines[0].Line[C].End_ := Lines[0].Line[C].Note[NDst].Start +
- Lines[0].Line[C].Note[NDst].Length;
-
- // move needed sentences to one backward.
- for C := Lines[0].Current + 1 to Lines[0].High - 1 do
- Lines[0].Line[C] := Lines[0].Line[C+1];
-
- // increase sentence length by 1
- SetLength(Lines[0].Line, Length(Lines[0].Line) - 1);
- Dec(Lines[0].Number);
- Dec(Lines[0].High);
-end;
-
-procedure TScreenEditSub.DivideNote;
-var
- C: integer;
- N: integer;
-begin
- C := Lines[0].Current;
-
- with Lines[0].Line[C] do
- begin
- Inc(HighNote);
- SetLength(Note, HighNote + 1);
-
- // we copy all notes including selected one
- for N := HighNote downto CurrentNote+1 do begin
- Note[N] := Note[N-1];
- end;
-
- // me slightly modify new note
- Note[CurrentNote].Length := 1;
- Inc(Note[CurrentNote+1].Start);
- Dec(Note[CurrentNote+1].Length);
- Note[CurrentNote+1].Text := '- ';
- Note[CurrentNote+1].Color := 0;
- end;
-end;
-
-procedure TScreenEditSub.DeleteNote;
-var
- C: integer;
- N: integer;
- NLen: integer;
-begin
- C := Lines[0].Current;
-
- //Do Not delete Last Note
- if (Lines[0].High > 0) OR (Lines[0].Line[C].HighNote > 0) then
- begin
-
- // we copy all notes from the next to the selected one
- for N := CurrentNote+1 to Lines[0].Line[C].HighNote do begin
- Lines[0].Line[C].Note[N-1] := Lines[0].Line[C].Note[N];
- end;
-
- Dec(Lines[0].Line[C].HighNote);
- if (Lines[0].Line[C].HighNote >= 0) then
- begin
- SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);
-
- // me slightly modify new note
- if CurrentNote > Lines[0].Line[C].HighNote then
- Dec(CurrentNote);
-
- Lines[0].Line[C].Note[CurrentNote].Color := 1;
- end
- //Last Note of current Sentence Deleted - > Delete Sentence
- else
- begin
- //Move all Sentences after the current to the Left
- for N := C+1 to Lines[0].High do
- Lines[0].Line[N-1] := Lines[0].Line[N];
-
- //Delete Last Sentence
- SetLength(Lines[0].Line, Lines[0].High);
- Lines[0].High := High(Lines[0].Line);
- Lines[0].Number := Length(Lines[0].Line);
-
- CurrentNote := 0;
- if (C > 0) then
- Lines[0].Current := C - 1
- else
- Lines[0].Current := 0;
-
- Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
- end;
- end;
-end;
-
-procedure TScreenEditSub.TransposeNote(Transpose: integer);
-begin
- Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone, Transpose);
-end;
-
-procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
-var
- C: integer;
- N: integer;
-begin
- for C := 0 to Lines[0].High do begin
- Lines[0].Line[C].BaseNote := Lines[0].Line[C].BaseNote + Tone;
- for N := 0 to Lines[0].Line[C].HighNote do
- Lines[0].Line[C].Note[N].Tone := Lines[0].Line[C].Note[N].Tone + Tone;
- end;
-end;
-
-procedure TScreenEditSub.MoveAllToEnd(Move: integer);
-var
- C: integer;
- N: integer;
- NStart: integer;
-begin
- for C := Lines[0].Current to Lines[0].High do begin
- NStart := 0;
- if C = Lines[0].Current then NStart := CurrentNote;
- for N := NStart to Lines[0].Line[C].HighNote do begin
- Inc(Lines[0].Line[C].Note[N].Start, Move); // move note start
-
- if N = 0 then begin // fix beginning
- Inc(Lines[0].Line[C].Start, Move);
- end;
-
- if N = Lines[0].Line[C].HighNote then // fix ending
- Inc(Lines[0].Line[C].End_, Move);
-
- end; // for
- end; // for
-end;
-
-procedure TScreenEditSub.MoveTextToRight;
-var
- C: integer;
- N: integer;
- NHigh: integer;
-begin
-{ C := Lines[0].Current;
-
- for N := Lines[0].Line[C].HighNut downto 1 do begin
- Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
- end; // for
-
- Lines[0].Line[C].Note[0].Text := '- ';}
-
- C := Lines[0].Current;
- NHigh := Lines[0].Line[C].HighNote;
-
- // last word
- Lines[0].Line[C].Note[NHigh].Text := Lines[0].Line[C].Note[NHigh-1].Text + Lines[0].Line[C].Note[NHigh].Text;
-
- // other words
- for N := NHigh - 1 downto CurrentNote + 1 do begin
- Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
- end; // for
- Lines[0].Line[C].Note[CurrentNote].Text := '- ';
-end;
-
-procedure TScreenEditSub.MarkSrc;
-begin
- CopySrc := Lines[0].Current;
-end;
-
-procedure TScreenEditSub.PasteText;
-var
- C: integer;
- N: integer;
-begin
- C := Lines[0].Current;
-
- for N := 0 to Lines[0].Line[CopySrc].HighNote do
- Lines[0].Line[C].Note[N].Text := Lines[0].Line[CopySrc].Note[N].Text;
-end;
-
-procedure TScreenEditSub.CopySentence(Src, Dst: integer);
-var
- N: integer;
- Time1: integer;
- Time2: integer;
- TD: integer;
-begin
- Time1 := Lines[0].Line[Src].Note[0].Start;
- Time2 := Lines[0].Line[Dst].Note[0].Start;
- TD := Time2-Time1;
-
- SetLength(Lines[0].Line[Dst].Note, Lines[0].Line[Src].HighNote + 1);
- Lines[0].Line[Dst].HighNote := Lines[0].Line[Src].HighNote;
- for N := 0 to Lines[0].Line[Src].HighNote do begin
- Lines[0].Line[Dst].Note[N].Text := Lines[0].Line[Src].Note[N].Text;
- Lines[0].Line[Dst].Note[N].Length := Lines[0].Line[Src].Note[N].Length;
- Lines[0].Line[Dst].Note[N].Tone := Lines[0].Line[Src].Note[N].Tone;
- Lines[0].Line[Dst].Note[N].Start := Lines[0].Line[Src].Note[N].Start + TD;
- end;
- N := Lines[0].Line[Src].HighNote;
- Lines[0].Line[Dst].End_ := Lines[0].Line[Dst].Note[N].Start + Lines[0].Line[Dst].Note[N].Length;
-end;
-
-procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
-var
- C: integer;
-begin
- // create place for new sentences
- SetLength(Lines[0].Line, Lines[0].Number + Num - 1);
-
- // moves sentences next to the destination
- for C := Lines[0].High downto Dst + 1 do begin
- Lines[0].Line[C + Num - 1] := Lines[0].Line[C];
- end;
-
- // prepares new sentences: sets sentence start and create first note
- for C := 1 to Num-1 do begin
- Lines[0].Line[Dst + C].Start := Lines[0].Line[Dst + C - 1].Note[0].Start +
- (Lines[0].Line[Src + C].Note[0].Start - Lines[0].Line[Src + C - 1].Note[0].Start);
- SetLength(Lines[0].Line[Dst + C].Note, 1);
- Lines[0].Line[Dst + C].HighNote := 0;
- Lines[0].Line[Dst + C].Note[0].Start := Lines[0].Line[Dst + C].Start;
- Lines[0].Line[Dst + C].Note[0].Length := 1;
- Lines[0].Line[Dst + C].End_ := Lines[0].Line[Dst + C].Start + 1;
- end;
-
- // increase counters
- Lines[0].Number := Lines[0].Number + Num - 1;
- Lines[0].High := Lines[0].High + Num - 1;
-
- for C := 0 to Num-1 do
- CopySentence(Src + C, Dst + C);
-end;
-
-
-constructor TScreenEditSub.Create;
-begin
- inherited Create;
- SetLength(Player, 1);
-
- // linijka
- AddStatic(20, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), TEXTURE_TYPE_COLORIZED);
- AddText(40, 17, 1, 6, 1, 1, 1, 'Line');
- TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');
-
- // Note
- AddStatic(220, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), TEXTURE_TYPE_COLORIZED);
- AddText(242, 17, 1, 6, 1, 1, 1, 'Note');
- TextNote := AddText(320, 14, 1, 8, 0, 0, 0, '0 / 0');
-
- // file info
- AddStatic(150, 50, 500, 150, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
- AddStatic(151, 52, 498, 146, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
- AddText(180, 65, 0, 8, 0, 0, 0, 'Title:');
- AddText(180, 90, 0, 8, 0, 0, 0, 'Artist:');
- AddText(180, 115, 0, 8, 0, 0, 0, 'Mp3:');
- AddText(180, 140, 0, 8, 0, 0, 0, 'BPM:');
- AddText(180, 165, 0, 8, 0, 0, 0, 'GAP:');
-
- TextTitle := AddText(250, 65, 0, 8, 0, 0, 0, 'a');
- TextArtist := AddText(250, 90, 0, 8, 0, 0, 0, 'b');
- TextMp3 := AddText(250, 115, 0, 8, 0, 0, 0, 'c');
- TextBPM := AddText(250, 140, 0, 8, 0, 0, 0, 'd');
- TextGAP := AddText(250, 165, 0, 8, 0, 0, 0, 'e');
-
-{ AddInteraction(2, TextTitle);
- AddInteraction(2, TextArtist);
- AddInteraction(2, TextMp3);
- AddInteraction(2, TextBPM);
- AddInteraction(2, TextGAP);}
-
- // note info
- AddText(20, 190, 0, 8, 0, 0, 0, 'Start:');
- AddText(20, 215, 0, 8, 0, 0, 0, 'Duration:');
- AddText(20, 240, 0, 8, 0, 0, 0, 'Tone:');
- AddText(20, 265, 0, 8, 0, 0, 0, 'Text:');
-
- TextNStart := AddText(120, 190, 0, 8, 0, 0, 0, 'a');
- TextNLength := AddText(120, 215, 0, 8, 0, 0, 0, 'b');
- TextNTon := AddText(120, 240, 0, 8, 0, 0, 0, 'c');
- TextNText := AddText(120, 265, 0, 8, 0, 0, 0, 'd');
-
- // debug
- TextDebug := AddText(30, 550, 0, 8, 0, 0, 0, '');
-
-end;
-
-procedure TScreenEditSub.onShow;
-begin
- inherited;
-
- Log.LogStatus('Initializing', 'TEditScreen.onShow');
- Lyric := TEditorLyrics.Create;
-
- ResetSingTemp;
-
- try
- //Check if File is XML
- if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml'
- then Error := not CurrentSong.LoadXMLSong()
- else Error := not CurrentSong.LoadSong();
- except
- Error := True;
- end;
-
- if Error then
- begin
- //Error Loading Song -> Go back to Song Screen and Show some Error Message
- FadeTo(@ScreenSong);
- ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
- Exit;
- end
- else begin
- {$IFDEF UseMIDIPort}
- MidiOut := TMidiOutput.Create(nil);
- if Ini.Debug = 1 then
- MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
- MidiOut.Open;
- {$ENDIF}
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextMp3].Text := CurrentSong.Mp3;
-
- Lines[0].Current := 0;
- CurrentNote := 0;
- Lines[0].Line[0].Note[0].Color := 1;
- AudioPlayback.Open(CurrentSong.Path + CurrentSong.Mp3);
- //Set Down Music Volume for Better hearability of Midi Sounds
- //Music.SetVolume(0.4);
-
- Lyric.Clear;
- Lyric.X := 400;
- Lyric.Y := 500;
- Lyric.Align := 1;
- Lyric.Size := 14;
- Lyric.ColR := 0;
- Lyric.ColG := 0;
- Lyric.ColB := 0;
- Lyric.ColSR := Skin_FontHighlightR;
- Lyric.ColSG := Skin_FontHighlightG;
- Lyric.ColSB := Skin_FontHighlightB;
- Lyric.AddLine(0);
- Lyric.Selected := 0;
-
- NotesH := 7;
- NotesW := 4;
-
- end;
-
-// Interaction := 0;
- TextEditMode := false;
-end;
-
-function TScreenEditSub.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
- glClearColor(1,1,1,1);
-
- // midi music
- if PlaySentenceMidi then begin
- {$IFDEF UseMIDIPort}
- MidiPos := USTime.GetTime - MidiTime + MidiStart;
-
-
- // stop the music
- if (MidiPos > MidiStop) then begin
- MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
- PlaySentenceMidi := false;
- end;
- {$ENDIF}
-
- // click
- AktBeat := Floor(GetMidBeat(MidiPos - CurrentSong.GAP / 1000));
- Text[TextDebug].Text := IntToStr(AktBeat);
-
- if AktBeat <> LastClick then begin
- for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNote do
- if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = AktBeat) then
- begin
-
-
- LastClick := AktBeat;
- {$IFDEF UseMIDIPort}
- if Pet > 0 then
- MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[Pet-1].Tone + 60, 127);
- MidiOut.PutShort($91, Lines[0].Line[Lines[0].Current].Note[Pet].Tone + 60, 127);
- MidiLastNote := Pet;
- {$ENDIF}
-
- end;
- end;
- end; // if PlaySentenceMidi
-
- // mp3 music
- if PlaySentence then begin
- // stop the music
- if (AudioPlayback.Position > PlayStopTime) then
- begin
- AudioPlayback.Stop;
- PlaySentence := false;
- end;
-
- // click
- if (Click) and (PlaySentence) then begin
-// AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
- AktBeat := Floor(GetMidBeat(AudioPlayback.Position - CurrentSong.GAP / 1000));
- Text[TextDebug].Text := IntToStr(AktBeat);
- if AktBeat <> LastClick then begin
- for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNote do
- if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = AktBeat) then
- begin
- AudioPlayback.PlaySound( SoundLib.Click );
- LastClick := AktBeat;
- end;
- end;
- end; // click
- end; // if PlaySentence
-
-
- Text[TextSentence].Text := IntToStr(Lines[0].Current + 1) + ' / ' + IntToStr(Lines[0].Number);
- Text[TextNote].Text := IntToStr(CurrentNote + 1) + ' / ' + IntToStr(Lines[0].Line[Lines[0].Current].HighNote + 1);
-
- // Song info
- Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
- Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
-
- //Error reading Variables when no Song is loaded
- if not Error then
- begin
- // Note info
- Text[TextNStart].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
- Text[TextNLength].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
- Text[TextNTon].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' ( ' + GetNoteName(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' )';
- Text[TextNText].Text := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
- end;
-
- // Text Edit Mode
- if TextEditMode then
- Text[TextNText].Text := Text[TextNText].Text + '|';
-
- // draw static menu
- inherited Draw;
-
- // draw notes
- SingDrawNoteLines(20, 300, 780, 15);
- //Error Drawing when no Song is loaded
- if not Error then
- begin
- SingDrawBeatDelimeters(40, 300, 760, 0);
- EditDrawLine(40, 405, 760, 0, 15);
- end;
-
- // draw text
- Lyric.Draw;
-
- Result := true;
-end;
-
-procedure TScreenEditSub.onHide;
-begin
- {$IFDEF UseMIDIPort}
- MidiOut.Close;
- MidiOut.Free;
- {$ENDIF}
- Lyric.Free;
- //Music.SetVolume(1.0);
-end;
-
-function TScreenEditSub.GetNoteName(Note: Integer): String;
-var N1, N2: Integer;
-begin
- if (Note > 0) then
- begin
- N1 := Note mod 12;
- N2 := Note div 12;
- end
- else
- begin
- N1 := (Note + (-Trunc(Note/12)+1)*12) mod 12;
- N2 := -1;
- end;
-
-
-
- case N1 of
- 0: Result := 'c';
- 1: Result := 'c#';
- 2: Result := 'd';
- 3: Result := 'd#';
- 4: Result := 'e';
- 5: Result := 'f';
- 6: Result := 'f#';
- 7: Result := 'g';
- 8: Result := 'g#';
- 9: Result := 'a';
- 10: Result := 'b';
- 11: Result := 'h';
- end;
-
- case N2 of
- 0: Result := UpperCase(Result); //Normal Uppercase Note, 1: Normal lowercase Note
- 2: Result := Result + ''''; //One Striped
- 3: Result := Result + ''''''; //Two Striped
- 4: Result := Result + ''''''''; //etc.
- 5: Result := Result + '''''''''';
- 6: Result := Result + '''''''''''';
- 7: Result := Result + '''''''''''''';
- end;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenLevel.pas b/Game/Code/Screens/UScreenLevel.pas
deleted file mode 100644
index 1ea79e7f..00000000
--- a/Game/Code/Screens/UScreenLevel.pas
+++ /dev/null
@@ -1,103 +0,0 @@
-unit UScreenLevel;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenLevel = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic,
- UMain,
- UIni,
- USong,
- UTexture;
-
-function TScreenLevel.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenName);
- end;
-
- SDLK_RETURN:
- begin
- Ini.Difficulty := Interaction;
- Ini.SaveLevel;
- AudioPlayback.PlaySound(SoundLib.Start);
- //Set Standard Mode
- ScreenSong.Mode := smNormal;
- FadeTo(@ScreenSong);
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenLevel.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Level);
-
- AddButton(Theme.Level.ButtonEasy);
- AddButton(Theme.Level.ButtonMedium);
- AddButton(Theme.Level.ButtonHard);
-
- Interaction := 0;
-end;
-
-procedure TScreenLevel.onShow;
-begin
- inherited;
-
- Interaction := Ini.Difficulty;
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenLevel.SetAnimationProgress(Progress: real);
-begin
- Button[0].Texture.ScaleW := Progress;
- Button[1].Texture.ScaleW := Progress;
- Button[2].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenLoading.pas b/Game/Code/Screens/UScreenLoading.pas
deleted file mode 100644
index ee3c6f7f..00000000
--- a/Game/Code/Screens/UScreenLoading.pas
+++ /dev/null
@@ -1,57 +0,0 @@
-unit UScreenLoading;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UThemes,
- gl;
-
-type
- TScreenLoading = class(TMenu)
- public
- Fadeout: boolean;
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function GetBGTexNum: GLUInt;
- end;
-
-implementation
-
-uses UGraphic,
- UTime;
-
-function TScreenLoading.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
-end;
-
-constructor TScreenLoading.Create;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Loading);
-
- Fadeout := false;
-end;
-
-procedure TScreenLoading.onShow;
-begin
- inherited;
-end;
-
-function TScreenLoading.GetBGTexNum: GLUInt;
-begin
- Result := Self.BackImg.TexNum;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
deleted file mode 100644
index 4dbdaaa1..00000000
--- a/Game/Code/Screens/UScreenMain.pas
+++ /dev/null
@@ -1,256 +0,0 @@
-unit UScreenMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- UDisplay,
- UMusic,
- UFiles,
- SysUtils,
- UThemes;
-
-type
- TScreenMain = class(TMenu)
- public
- TextDescription: integer;
- TextDescriptionLong: integer;
-
- constructor Create; override;
- function ParseInput(PressedKey: cardinal; CharCode: widechar;
- PressedDown: boolean): boolean; override;
- procedure onShow; override;
- procedure InteractNext; override;
- procedure InteractPrev; override;
- procedure InteractInc; override;
- procedure InteractDec; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses
- UGraphic,
- UMain,
- UIni,
- UTexture,
- USongs,
- Textgl,
- ULanguage,
- UParty,
- UDLLManager,
- UScreenCredits,
- USkins;
-
-function TScreenMain.ParseInput(PressedKey: cardinal; CharCode: widechar;
- PressedDown: boolean): boolean;
-var
- SDL_ModState: word;
-begin
- Result := True;
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT +
- KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- if (PressedDown) then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := False;
- Exit;
- end;
- 'C':
- begin
- if (SDL_ModState = KMOD_LALT) then
- begin
- FadeTo(@ScreenCredits, SoundLib.Start);
- Exit;
- end;
- end;
- 'M':
- begin
- if (Ini.Players >= 1) and (Length(DLLMan.Plugins) >= 1) then
- begin
- FadeTo(@ScreenPartyOptions, SoundLib.Start);
- Exit;
- end;
- end;
-
- 'S':
- begin
- FadeTo(@ScreenStatMain, SoundLib.Start);
- Exit;
- end;
-
- 'E':
- begin
- FadeTo(@ScreenEdit, SoundLib.Start);
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE:
- begin
- Result := False;
- end;
-
- SDLK_RETURN:
- begin
- //Solo
- if (Interaction = 0) then
- begin
- if (Songs.SongList.Count >= 1) then
- begin
- if (Ini.Players >= 0) and (Ini.Players <= 3) then
- PlayersPlay := Ini.Players + 1;
- if (Ini.Players = 4) then
- PlayersPlay := 6;
-
- ScreenName.Goto_SingScreen := False;
- FadeTo(@ScreenName, SoundLib.Start);
- end
- else //show error message
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
- end;
-
- //Multi
- if Interaction = 1 then
- begin
- if (Songs.SongList.Count >= 1) then
- begin
- if (Length(DLLMan.Plugins) >= 1) then
- begin
- FadeTo(@ScreenPartyOptions, SoundLib.Start);
- end
- else //show error message, No Plugins Loaded
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS'));
- end
- else //show error message, No Songs Loaded
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
- end;
-
- //Stats
- if Interaction = 2 then
- begin
- FadeTo(@ScreenStatMain, SoundLib.Start);
- end;
-
- //Editor
- if Interaction = 3 then
- begin
- FadeTo(@ScreenEdit, SoundLib.Start);
- end;
-
- //Options
- if Interaction = 4 then
- begin
- FadeTo(@ScreenOptions, SoundLib.Start);
- end;
-
- //Exit
- if Interaction = 5 then
- begin
- Result := False;
- end;
- end;
- {**
- * Up and Down could be done at the same time,
- * but I don't want to declare variables inside
- * functions like this one, called so many times
- *}
- SDLK_DOWN: InteractInc;
- SDLK_UP: InteractDec;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end
- else // Key Up
- case PressedKey of
- SDLK_RETURN:
- begin
- end;
- end;
-end;
-
-constructor TScreenMain.Create;
-begin
- inherited Create;
-{**
- * Attention ^^:
- * New Creation Order needed because of LoadFromTheme
- * and Button Collections.
- * At First Custom Texts and Statics
- * Then LoadFromTheme
- * after LoadFromTheme the Buttons and Selects
- *}
- TextDescription := AddText(Theme.Main.TextDescription);
- TextDescriptionLong := AddText(Theme.Main.TextDescriptionLong);
-
- LoadFromTheme(Theme.Main);
-
- AddButton(Theme.Main.ButtonSolo);
- AddButton(Theme.Main.ButtonMulti);
- AddButton(Theme.Main.ButtonStat);
- AddButton(Theme.Main.ButtonEditor);
- AddButton(Theme.Main.ButtonOptions);
- AddButton(Theme.Main.ButtonExit);
-
- Interaction := 0;
-end;
-
-procedure TScreenMain.onShow;
-begin
- inherited;
-{**
- * Start background music
- *}
- SoundLib.StartBgMusic;
-end;
-
-procedure TScreenMain.InteractNext;
-begin
- inherited InteractNext;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
-end;
-
-procedure TScreenMain.InteractPrev;
-begin
- inherited InteractPrev;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
-end;
-
-procedure TScreenMain.InteractDec;
-begin
- inherited InteractDec;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
-end;
-
-procedure TScreenMain.InteractInc;
-begin
- inherited InteractInc;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
-end;
-
-procedure TScreenMain.SetAnimationProgress(Progress: real);
-begin
- Static[0].Texture.ScaleW := Progress;
- Static[0].Texture.ScaleH := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenName.pas b/Game/Code/Screens/UScreenName.pas
deleted file mode 100644
index f2d59f05..00000000
--- a/Game/Code/Screens/UScreenName.pas
+++ /dev/null
@@ -1,243 +0,0 @@
-unit UScreenName;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenName = class(TMenu)
- public
- Goto_SingScreen: Boolean; //If True then next Screen in SingScreen
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, UCommon;
-
-
-function TScreenName.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- I: integer;
-SDL_ModState: Word;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- // check normal keys
- if (IsAlphaNumericChar(CharCode) or
- {(CharCode in [' ','-','_','!',',','<','/','*','?','''','"']))} IsPunctuationChar(CharCode)) then
- begin
- Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
- Exit;
- end;
-
- // check special keys
- case PressedKey of
- // Templates for Names Mod
- SDLK_F1:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
- end;
- SDLK_F2:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
- end;
- SDLK_F3:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
- end;
- SDLK_F4:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
- end;
- SDLK_F5:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
- end;
- SDLK_F6:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
- end;
- SDLK_F7:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
- end;
- SDLK_F8:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
- end;
- SDLK_F9:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
- end;
- SDLK_F10:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
- end;
- SDLK_F11:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
- end;
- SDLK_F12:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
- end;
-
-
- SDLK_BACKSPACE:
- begin
- Button[Interaction].Text[0].DeleteLastL;
- end;
-
- SDLK_ESCAPE :
- begin
- Ini.SaveNames;
- AudioPlayback.PlaySound(SoundLib.Back);
- if GoTo_SingScreen then
- FadeTo(@ScreenSong)
- else
- FadeTo(@ScreenMain);
- end;
-
- SDLK_RETURN:
- begin
- for I := 1 to 6 do
- Ini.Name[I-1] := Button[I-1].Text[0].Text;
- Ini.SaveNames;
- AudioPlayback.PlaySound(SoundLib.Start);
-
- if GoTo_SingScreen then
- FadeTo(@ScreenSing)
- else
- FadeTo(@ScreenLevel);
-
- GoTo_SingScreen := False;
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenName.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Name);
-
-
- for I := 1 to 6 do
- AddButton(Theme.Name.ButtonPlayer[I]);
-
- Interaction := 0;
-end;
-
-procedure TScreenName.onShow;
-var
- I: integer;
-begin
- inherited;
-
- for I := 1 to 6 do
- Button[I-1].Text[0].Text := Ini.Name[I-1];
-
- for I := 1 to PlayersPlay do begin
- Button[I-1].Visible := true;
- Button[I-1].Selectable := true;
- end;
-
- for I := PlayersPlay+1 to 6 do begin
- Button[I-1].Visible := false;
- Button[I-1].Selectable := false;
- end;
-
-end;
-
-procedure TScreenName.SetAnimationProgress(Progress: real);
-var
- I: integer;
-begin
- for I := 1 to 6 do
- Button[I-1].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas
deleted file mode 100644
index 186b9b47..00000000
--- a/Game/Code/Screens/UScreenOpen.pas
+++ /dev/null
@@ -1,173 +0,0 @@
-unit UScreenOpen;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText,
- ULyrics, Math, gl, UThemes;
-
-type
- TScreenOpen = class(TMenu)
- private
- TextF: array[0..1] of integer;
- TextN: integer;
- public
- Tex_Background: TTexture;
- FadeOut: boolean;
- Path: string;
- BackScreen: pointer;
- procedure AddBox(X, Y, W, H: real);
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-// function Draw: boolean; override;
-// procedure Finish;
- end;
-
-implementation
-uses UGraphic, UDraw, UMain, USkins;
-
-function TScreenOpen.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
-
- if (PressedDown) then begin // Key Down
- // check normal keys
- case CharCode of
- '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '.', ':', '\':
- begin
- if Interaction = 0 then begin
- Text[TextN].Text := Text[TextN].Text + CharCode;
- end;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
- 8: // del
- begin
- if Interaction = 0 then
- begin
- Text[TextN].DeleteLastL;
- end;
- end;
-
-
- SDLK_ESCAPE :
- begin
- //Empty Filename and go to last Screen
- ConversionFileName := '';
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end;
-
- SDLK_RETURN:
- begin
- if (Interaction = 2) then begin
- //Update Filename and go to last Screen
- ConversionFileName := Text[TextN].Text;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end
- else if (Interaction = 1) then
- begin
- //Empty Filename and go to last Screen
- ConversionFileName := '';
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end;
- end;
-
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
-
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
-
- SDLK_DOWN:
- begin
- end;
-
- SDLK_UP:
- begin
- end;
- end;
- end;
-end;
-
-procedure TScreenOpen.AddBox(X, Y, W, H: real);
-begin
- AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
- AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
-end;
-
-constructor TScreenOpen.Create;
-begin
- inherited Create;
-
- // linijka
-{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED);
- AddText(35, 17, 1, 6, 1, 1, 1, 'Linijka');
- TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');}
-
- // file list
-// AddBox(400, 100, 350, 450);
-
-// TextF[0] := AddText(430, 155, 0, 8, 0, 0, 0, 'a');
-// TextF[1] := AddText(430, 180, 0, 8, 0, 0, 0, 'a');
-
- // file name
- AddBox(20, 540, 500, 40);
- TextN := AddText(50, 548, 0, 8, 0, 0, 0, ConversionFileName);
- AddInteraction(iText, TextN);
-
- // buttons
- {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
- AddButtonText(10, 5, 0, 0, 0, 'Cancel');
-
- AddButton(670, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
- AddButtonText(30, 5, 0, 0, 0, 'OK');}
- // buttons
- AddButton(540, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Cancel');
-
- AddButton(670, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(30, 5, 0, 0, 0, 'OK');
-
-
-end;
-
-procedure TScreenOpen.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-(*function TScreenEditSub.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-
-end;
-
-procedure TScreenEditSub.Finish;
-begin
-//
-end;*)
-
-end.
-
diff --git a/Game/Code/Screens/UScreenOptions.pas b/Game/Code/Screens/UScreenOptions.pas
deleted file mode 100644
index 24633115..00000000
--- a/Game/Code/Screens/UScreenOptions.pas
+++ /dev/null
@@ -1,196 +0,0 @@
-unit UScreenOptions;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, SysUtils, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptions = class(TMenu)
- public
- TextDescription: integer;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure InteractNext; override;
- procedure InteractPrev; override;
- procedure InteractNextRow; override;
- procedure InteractPrevRow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic;
-
-function TScreenOptions.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
-// Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 0 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsGame);
- end;
-
- if SelInteraction = 1 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsGraphics);
- end;
-
- if SelInteraction = 2 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsSound);
- end;
-
- if SelInteraction = 3 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsLyrics);
- end;
-
- if SelInteraction = 4 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsThemes);
- end;
-
- if SelInteraction = 5 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsRecord);
- end;
-
- if SelInteraction = 6 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenOptionsAdvanced);
- end;
-
- if SelInteraction = 7 then
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
- end;
- SDLK_DOWN: InteractNextRow;
- SDLK_UP: InteractPrevRow;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenOptions.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- TextDescription := AddText(Theme.Options.TextDescription);
-
- LoadFromTheme(Theme.Options);
-
- AddButton(Theme.Options.ButtonGame);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[0]);
-
- AddButton(Theme.Options.ButtonGraphics);
- if (Length(Button[1].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[1]);
-
- AddButton(Theme.Options.ButtonSound);
- if (Length(Button[2].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[2]);
-
- AddButton(Theme.Options.ButtonLyrics);
- if (Length(Button[3].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[3]);
-
- AddButton(Theme.Options.ButtonThemes);
- if (Length(Button[4].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[4]);
-
- AddButton(Theme.Options.ButtonRecord);
- if (Length(Button[5].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[5]);
-
- AddButton(Theme.Options.ButtonAdvanced);
- if (Length(Button[6].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[6]);
-
- AddButton(Theme.Options.ButtonExit);
- if (Length(Button[7].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
- Interaction := 0;
-end;
-
-procedure TScreenOptions.onShow;
-begin
- inherited;
-end;
-
-procedure TScreenOptions.InteractNext;
-begin
- inherited InteractNext;
- Text[TextDescription].Text := Theme.Options.Description[Interaction];
-end;
-
-procedure TScreenOptions.InteractPrev;
-begin
- inherited InteractPrev;
- Text[TextDescription].Text := Theme.Options.Description[Interaction];
-end;
-
-procedure TScreenOptions.InteractNextRow;
-begin
- inherited InteractNextRow;
- Text[TextDescription].Text := Theme.Options.Description[Interaction];
-end;
-
-procedure TScreenOptions.InteractPrevRow;
-begin
- inherited InteractPrevRow;
- Text[TextDescription].Text := Theme.Options.Description[Interaction];
-end;
-
-procedure TScreenOptions.SetAnimationProgress(Progress: real);
-begin
- Button[0].Texture.ScaleW := Progress;
- Button[1].Texture.ScaleW := Progress;
- Button[2].Texture.ScaleW := Progress;
- Button[3].Texture.ScaleW := Progress;
- Button[4].Texture.ScaleW := Progress;
- Button[5].Texture.ScaleW := Progress;
- Button[6].Texture.ScaleW := Progress;
- Button[7].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsAdvanced.pas b/Game/Code/Screens/UScreenOptionsAdvanced.pas
deleted file mode 100644
index be8895e1..00000000
--- a/Game/Code/Screens/UScreenOptionsAdvanced.pas
+++ /dev/null
@@ -1,113 +0,0 @@
-unit UScreenOptionsAdvanced;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsAdvanced = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, SysUtils;
-
-function TScreenOptionsAdvanced.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- // Escape -> save nothing - just leave this screen
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- //SelectLoadAnimation Hidden because it is useless atm
- //if SelInteraction = 7 then begin
- if SelInteraction = 6 then begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- //SelectLoadAnimation Hidden because it is useless atm
- //if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
- if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- //SelectLoadAnimation Hidden because it is useless atm
- //if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
- if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsAdvanced.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsAdvanced);
-
- //SelectLoadAnimation Hidden because it is useless atm
- //AddSelect(Theme.OptionsAdvanced.SelectLoadAnimation, Ini.LoadAnimation, ILoadAnimation);
- AddSelectSlide(Theme.OptionsAdvanced.SelectScreenFade, Ini.ScreenFade, IScreenFade);
- AddSelectSlide(Theme.OptionsAdvanced.SelectEffectSing, Ini.EffectSing, IEffectSing);
- AddSelectSlide(Theme.OptionsAdvanced.SelectLineBonus, Ini.LineBonus, ILineBonus);
- AddSelectSlide(Theme.OptionsAdvanced.SelectOnSongClick, Ini.OnSongClick, IOnSongClick);
- AddSelectSlide(Theme.OptionsAdvanced.SelectAskbeforeDel, Ini.AskBeforeDel, IAskbeforeDel);
- AddSelectSlide(Theme.OptionsAdvanced.SelectPartyPopup, Ini.PartyPopup, IPartyPopup);
-
- AddButton(Theme.OptionsAdvanced.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
- Interaction := 0;
-end;
-
-procedure TScreenOptionsAdvanced.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas
deleted file mode 100644
index 2dc8dd7f..00000000
--- a/Game/Code/Screens/UScreenOptionsGame.pas
+++ /dev/null
@@ -1,117 +0,0 @@
-unit UScreenOptionsGame;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes, USongs;
-
-type
- TScreenOptionsGame = class(TMenu)
- public
- old_Tabs, old_Sorting: integer;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure RefreshSongs;
- end;
-
-implementation
-
-uses UGraphic, SysUtils;
-
-function TScreenOptionsGame.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- RefreshSongs;
-
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 6 then begin
- AudioPlayback.PlaySound(SoundLib.Back);
- RefreshSongs;
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 5) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 5) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsGame.Create;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsGame);
-
- //Refresh Songs Patch
- old_Sorting := Ini.Sorting;
- old_Tabs := Ini.Tabs;
-
- AddSelectSlide(Theme.OptionsGame.SelectPlayers, Ini.Players, IPlayers);
- AddSelectSlide(Theme.OptionsGame.SelectDifficulty, Ini.Difficulty, IDifficulty);
- AddSelectSlide(Theme.OptionsGame.SelectLanguage, Ini.Language, ILanguage);
- AddSelectSlide(Theme.OptionsGame.SelectTabs, Ini.Tabs, ITabs);
- AddSelectSlide(Theme.OptionsGame.SelectSorting, Ini.Sorting, ISorting);
- AddSelectSlide(Theme.OptionsGame.SelectDebug, Ini.Debug, IDebug);
-
- AddButton(Theme.OptionsGame.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
-end;
-
-//Refresh Songs Patch
-procedure TScreenOptionsGame.RefreshSongs;
-begin
-if (ini.Sorting <> old_Sorting) or (ini.Tabs <> old_Tabs) then
- ScreenSong.Refresh;
-end;
-
-procedure TScreenOptionsGame.onShow;
-begin
- inherited;
-
-// Interaction := 0;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas
deleted file mode 100644
index f2b6faa2..00000000
--- a/Game/Code/Screens/UScreenOptionsGraphics.pas
+++ /dev/null
@@ -1,113 +0,0 @@
-unit UScreenOptionsGraphics;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsGraphics = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, UMain, SysUtils, TypInfo;
-
-function TScreenOptionsGraphics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- // Escape -> save nothing - just leave this screen
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
-{ if SelInteraction <= 1 then begin
- Restart := true;
- end;}
- if SelInteraction = 6 then begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- // FIXME: changing the video mode does not work this way in windows
- // and MacOSX as all textures will be invalidated through this.
- // See the ALT+TAB code too.
- {$IFDEF Linux}
- Reinitialize3D();
- {$ENDIF}
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < 6) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < 6) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsGraphics.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
- LoadFromTheme(Theme.OptionsGraphics);
-
- AddSelectSlide(Theme.OptionsGraphics.SelectResolution, Ini.Resolution, IResolution);
- AddSelectSlide(Theme.OptionsGraphics.SelectFullscreen, Ini.Fullscreen, IFullscreen);
- AddSelectSlide(Theme.OptionsGraphics.SelectDepth, Ini.Depth, IDepth);
- AddSelectSlide(Theme.OptionsGraphics.SelectVisualizer, Ini.VisualizerOption, IVisualizer);
- AddSelectSlide(Theme.OptionsGraphics.SelectOscilloscope, Ini.Oscilloscope, IOscilloscope);
- AddSelectSlide(Theme.OptionsGraphics.SelectMovieSize, Ini.MovieSize, IMovieSize);
-
-
- AddButton(Theme.OptionsGraphics.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
-end;
-
-procedure TScreenOptionsGraphics.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas
deleted file mode 100644
index 42f1fadb..00000000
--- a/Game/Code/Screens/UScreenOptionsLyrics.pas
+++ /dev/null
@@ -1,103 +0,0 @@
-unit UScreenOptionsLyrics;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsLyrics = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, SysUtils;
-
-function TScreenOptionsLyrics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- // Escape -> save nothing - just leave this screen
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 3 then begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsLyrics.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsLyrics);
-
- AddSelectSlide(Theme.OptionsLyrics.SelectLyricsFont, Ini.LyricsFont, ILyricsFont);
- AddSelectSlide(Theme.OptionsLyrics.SelectLyricsEffect, Ini.LyricsEffect, ILyricsEffect);
- //AddSelect(Theme.OptionsLyrics.SelectSolmization, Ini.Solmization, ISolmization); GAH!!!!11 DIE!!!
- AddSelectSlide(Theme.OptionsLyrics.SelectNoteLines, Ini.NoteLines, INoteLines);
-
-
- AddButton(Theme.OptionsLyrics.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
-end;
-
-procedure TScreenOptionsLyrics.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas
deleted file mode 100644
index 885f7db5..00000000
--- a/Game/Code/Screens/UScreenOptionsRecord.pas
+++ /dev/null
@@ -1,785 +0,0 @@
-unit UScreenOptionsRecord;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UThemes,
- UMusic,
- URecord,
- UMenu;
-
-type
- TDrawState = record
- ChannelIndex: integer;
- R, G, B: real; // mapped player color (normal)
- RD, GD, BD: real; // mapped player color (dark)
- end;
-
- TPeakInfo = record
- Volume: single;
- Time: cardinal;
- end;
-
- TScreenOptionsRecord = class(TMenu)
- private
- // max. count of input-channels determined for all devices
- MaxChannelCount: integer;
-
- // current input device
- CurrentDeviceIndex: integer;
- PreviewDeviceIndex: integer;
-
- // string arrays for select-slide options
- InputSourceNames: array of string;
- InputDeviceNames: array of string;
-
- // dynamic generated themes for channel select-sliders
- SelectSlideChannelTheme: array of TThemeSelectSlide;
-
- // indices for widget-updates
- SelectInputSourceID: integer;
- SelectSlideChannelID: array of integer;
-
- // interaction IDs
- ExitButtonIID: integer;
-
- // dummy data for non-available channels
- ChannelToPlayerMapDummy: integer;
-
- // preview channel-buffers
- PreviewChannel: array of TCaptureBuffer;
- ChannelPeak: array of TPeakInfo;
-
- // Device source volume
- SourceVolume: single;
- NextVolumePollTime: cardinal;
-
- procedure StartPreview;
- procedure StopPreview;
- procedure UpdateInputDevice;
- procedure ChangeVolume(VolumeChange: single);
- procedure DrawVolume(x, y, Width, Height: single);
- procedure DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
- procedure DrawPitch(const State: TDrawState; x, y, Width, Height: single);
- public
- constructor Create; override;
- function Draw: boolean; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- end;
-
-const
- PeakDecay = 0.2; // strength of peak-decay (reduction after one sec)
-
-const
- BarHeight = 11; // height of each bar (volume/vu-meter/pitch)
- BarUpperSpacing = 1; // spacing between a bar-area and the previous widget
- BarLowerSpacing = 3; // spacing between a bar-area and the next widget
- SourceBarsTotalHeight = BarHeight + BarUpperSpacing + BarLowerSpacing;
- ChannelBarsTotalHeight = 2*BarHeight + BarUpperSpacing + BarLowerSpacing;
-
-implementation
-
-uses
- SysUtils,
- Math,
- SDL,
- gl,
- TextGL,
- UGraphic,
- UDraw,
- UMain,
- UMenuSelectSlide,
- UMenuText,
- UFiles,
- UDisplay,
- UIni,
- ULog;
-
-function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- '+':
- begin
- // FIXME: add a nice volume-slider instead
- // or at least provide visualization and acceleration if the user holds the key pressed.
- ChangeVolume(0.02);
- end;
- '-':
- begin
- // FIXME: add a nice volume-slider instead
- // or at least provide visualization and acceleration if the user holds the key pressed.
- ChangeVolume(-0.02);
- end;
- 'T':
- begin
- if ((SDL_GetModState() and KMOD_SHIFT) <> 0) then
- Ini.ThresholdIndex := (Ini.ThresholdIndex + Length(IThresholdVals) - 1) mod Length(IThresholdVals)
- else
- Ini.ThresholdIndex := (Ini.ThresholdIndex + 1) mod Length(IThresholdVals);
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE:
- begin
- // Escape -> save nothing - just leave this screen
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if (SelInteraction = ExitButtonIID) then
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- UpdateInputDevice;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- UpdateInputDevice;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsRecord.Create;
-var
- DeviceIndex: integer;
- SourceIndex: integer;
- ChannelIndex: integer;
- InputDevice: TAudioInputDevice;
- InputDeviceCfg: PInputDeviceConfig;
- ChannelTheme: ^TThemeSelectSlide;
- //ButtonTheme: TThemeButton;
- WidgetYPos: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsRecord);
-
- // set CurrentDeviceIndex to a valid device
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- CurrentDeviceIndex := 0
- else
- CurrentDeviceIndex := -1;
-
- PreviewDeviceIndex := -1;
-
- WidgetYPos := 0;
-
- // init sliders if at least one device was detected
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- begin
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
-
- // init device-selection slider
- SetLength(InputDeviceNames, Length(AudioInputProcessor.DeviceList));
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- InputDeviceNames[DeviceIndex] := AudioInputProcessor.DeviceList[DeviceIndex].Name;
- end;
- // add device-selection slider (InteractionID: 0)
- AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, CurrentDeviceIndex, InputDeviceNames);
-
- // init source-selection slider
- SetLength(InputSourceNames, Length(InputDevice.Source));
- for SourceIndex := 0 to High(InputDevice.Source) do
- begin
- InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
- end;
- // add source-selection slider (InteractionID: 1)
- SelectInputSourceID := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput,
- InputDeviceCfg.Input, InputSourceNames);
-
- // add space for source volume bar
- WidgetYPos := Theme.OptionsRecord.SelectSlideInput.Y +
- Theme.OptionsRecord.SelectSlideInput.H +
- SourceBarsTotalHeight;
-
- // find max. channel count of all devices
- MaxChannelCount := 0;
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- if (AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels > MaxChannelCount) then
- MaxChannelCount := AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels;
- end;
-
- // init channel-to-player mapping sliders
- SetLength(SelectSlideChannelID, MaxChannelCount);
- SetLength(SelectSlideChannelTheme, MaxChannelCount);
-
- for ChannelIndex := 0 to MaxChannelCount-1 do
- begin
- // copy reference slide
- SelectSlideChannelTheme[ChannelIndex] :=
- Theme.OptionsRecord.SelectSlideChannel;
- // set current channel-theme
- ChannelTheme := @SelectSlideChannelTheme[ChannelIndex];
- // adjust vertical position
- ChannelTheme.Y := WidgetYPos;
- // calc size of next slide (add space for bars)
- WidgetYPos := WidgetYPos + ChannelTheme.H + ChannelBarsTotalHeight;
- // append channel index to name
- ChannelTheme.Text := ChannelTheme.Text + IntToStr(ChannelIndex+1);
-
- // show/hide widgets depending on whether the channel exists
- if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
- begin
- // current device has this channel
-
- // add slider
- SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
- InputDeviceCfg.ChannelToPlayerMap[ChannelIndex], IChannelPlayer);
- end
- else
- begin
- // current device does not have that many channels
-
- // add slider but hide it and assign a dummy variable to it
- SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
- ChannelToPlayerMapDummy, IChannelPlayer);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
- end;
- end;
- end;
-
- // add Exit-button
- //ButtonTheme := Theme.OptionsRecord.ButtonExit;
- // adjust button position
- //if (WidgetYPos <> 0) then
- // ButtonTheme.Y := WidgetYPos;
- //AddButton(ButtonTheme);
- // I uncommented the stuff above, because it's not skinable :X
- AddButton(Theme.OptionsRecord.ButtonExit);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
- // store InteractionID
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- ExitButtonIID := MaxChannelCount + 2
- else
- ExitButtonIID := 0;
-
- // set focus
- Interaction := 0;
-end;
-
-procedure TScreenOptionsRecord.UpdateInputDevice;
-var
- SourceIndex: integer;
- InputDevice: TAudioInputDevice;
- InputDeviceCfg: PInputDeviceConfig;
- ChannelIndex: integer;
-begin
- //Log.LogStatus('Update input-device', 'TScreenOptionsRecord.UpdateCard') ;
-
- StopPreview();
-
- // set CurrentDeviceIndex to a valid device
- if (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList)) then
- CurrentDeviceIndex := 0;
-
- // update sliders if at least one device was detected
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- begin
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
-
- // update source-selection slider
- SetLength(InputSourceNames, Length(InputDevice.Source));
- for SourceIndex := 0 to High(InputDevice.Source) do
- begin
- InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
- end;
- UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectInputSourceID,
- InputSourceNames, InputDeviceCfg.Input);
-
- // update channel-to-player mapping sliders
- for ChannelIndex := 0 to MaxChannelCount-1 do
- begin
- // show/hide widgets depending on whether the channel exists
- if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
- begin
- // current device has this channel
-
- // show slider
- UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
- SelectSlideChannelID[ChannelIndex], IChannelPlayer,
- InputDeviceCfg.ChannelToPlayerMap[ChannelIndex]);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := true;
- end
- else
- begin
- // current device does not have that many channels
-
- // hide slider and assign a dummy variable to it
- UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
- SelectSlideChannelID[ChannelIndex], IChannelPlayer,
- ChannelToPlayerMapDummy);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
- end;
- end;
- end;
-
- StartPreview();
-end;
-
-procedure TScreenOptionsRecord.ChangeVolume(VolumeChange: single);
-var
- InputDevice: TAudioInputDevice;
- Volume: single;
-begin
- // validate CurrentDeviceIndex
- if ((CurrentDeviceIndex < 0) or
- (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList))) then
- begin
- Exit;
- end;
-
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- if not assigned(InputDevice) then
- Exit;
-
- // set new volume
- Volume := InputDevice.GetVolume() + VolumeChange;
- InputDevice.SetVolume(Volume);
- //DebugWriteln('Volume: ' + floattostr(InputDevice.GetVolume));
-
- // volume must be polled again
- NextVolumePollTime := 0;
-end;
-
-procedure TScreenOptionsRecord.onShow;
-var
- ChannelIndex: integer;
-begin
- inherited;
-
- Interaction := 0;
-
- // create preview sound-buffers
- SetLength(PreviewChannel, MaxChannelCount);
- for ChannelIndex := 0 to High(PreviewChannel) do
- PreviewChannel[ChannelIndex] := TCaptureBuffer.Create();
-
- SetLength(ChannelPeak, MaxChannelCount);
-
- StartPreview();
-end;
-
-procedure TScreenOptionsRecord.onHide;
-var
- ChannelIndex: integer;
-begin
- StopPreview();
-
- // free preview buffers
- for ChannelIndex := 0 to High(PreviewChannel) do
- PreviewChannel[ChannelIndex].Free;
- SetLength(PreviewChannel, 0);
- SetLength(ChannelPeak, 0);
-end;
-
-procedure TScreenOptionsRecord.StartPreview;
-var
- ChannelIndex: integer;
- Device: TAudioInputDevice;
-begin
- if ((CurrentDeviceIndex >= 0) and
- (CurrentDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- // set preview channel as active capture channel
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- begin
- PreviewChannel[ChannelIndex].Clear();
- Device.LinkCaptureBuffer(ChannelIndex, PreviewChannel[ChannelIndex]);
- FillChar(ChannelPeak[ChannelIndex], SizeOf(TPeakInfo), 0);
- end;
- Device.Start();
- PreviewDeviceIndex := CurrentDeviceIndex;
-
- // volume must be polled again
- NextVolumePollTime := 0;
- end;
-end;
-
-procedure TScreenOptionsRecord.StopPreview;
-var
- ChannelIndex: integer;
- Device: TAudioInputDevice;
-begin
- if ((PreviewDeviceIndex >= 0) and
- (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
- Device.Stop;
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- Device.LinkCaptureBuffer(ChannelIndex, nil);
- end;
- PreviewDeviceIndex := -1;
-end;
-
-
-procedure TScreenOptionsRecord.DrawVolume(x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- VolBarInnerWidth: integer;
- Volume: single;
-const
- VolBarInnerHSpacing = 2;
- VolBarInnerVSpacing = 1;
-begin
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x1 + Width;
- y2 := y1 + Height;
-
- // init blend mode
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
-
- // TODO: if no volume is available, show some info (a blue bar maybe)
- if (SourceVolume >= 0) then
- Volume := SourceVolume
- else
- Volume := 0;
-
- // coordinates for first half of the volume bar
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * Volume;
- y1 := y1 + VolBarInnerVSpacing;
- y2 := y2 - VolBarInnerVSpacing;
-
- // draw volume-bar
- glBegin(GL_QUADS);
- // draw volume bar
- glColor3f(0.4, 0.3, 0.3);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glColor3f(1, 0.1, 0.1);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
- glEnd();
-
- { not needed anymore
- // coordinates for separator
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth;
-
- // draw separator
- glBegin(GL_LINE_STRIP);
- glColor4f(0.1, 0.1, 0.1, 0.2);
- glVertex2f(x1, y2);
- glColor4f(0.4, 0.4, 0.4, 0.2);
- glVertex2f((x1+x2)/2, y2);
- glColor4f(0.1, 0.1, 0.1, 0.2);
- glVertex2f(x2, y2);
- glEnd();
- }
-
- glDisable(GL_BLEND);
-end;
-
-procedure TScreenOptionsRecord.DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- Volume, PeakVolume: single;
- Delta: single;
- VolBarInnerWidth: integer;
-const
- VolBarInnerHSpacing = 2;
- VolBarInnerVSpacing = 1;
-begin
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x1 + Width;
- y2 := y1 + Height;
-
- // init blend mode
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
-
- // vertical positions
- y1 := y1 + VolBarInnerVSpacing;
- y2 := y2 - VolBarInnerVSpacing;
-
- // coordinates for bevel
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth;
-
- glBegin(GL_QUADS);
- Volume := PreviewChannel[State.ChannelIndex].MaxSampleVolume();
-
- // coordinates for volume bar
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * Volume;
-
- // draw volume bar
- glColor3f(State.RD, State.GD, State.BD);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glColor3f(State.R, State.G, State.B);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
-
- Delta := (SDL_GetTicks() - ChannelPeak[State.ChannelIndex].Time)/1000;
- PeakVolume := ChannelPeak[State.ChannelIndex].Volume - Delta*Delta*PeakDecay;
-
- // determine new peak-volume
- if (Volume > PeakVolume) then
- begin
- PeakVolume := Volume;
- ChannelPeak[State.ChannelIndex].Volume := Volume;
- ChannelPeak[State.ChannelIndex].Time := SDL_GetTicks();
- end;
-
- x1 := x + VolBarInnerHSpacing + VolBarInnerWidth * PeakVolume;
- x2 := x1 + 2;
-
- // draw peak
- glColor3f(0.8, 0.8, 0.8);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
-
- // draw threshold
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * IThresholdVals[Ini.ThresholdIndex];
-
- glColor4f(0.3, 0.3, 0.3, 0.6);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
- glEnd();
-
- glDisable(GL_BLEND);
-end;
-
-procedure TScreenOptionsRecord.DrawPitch(const State: TDrawState; x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- i: integer;
- ToneBoxWidth: real;
- ToneString: PChar;
- ToneStringWidth, ToneStringHeight: real;
- ToneStringMaxWidth: real;
- ToneStringCenterXOffset: real;
-const
- PitchBarInnerHSpacing = 2;
- PitchBarInnerVSpacing = 1;
-begin
- // calc tone pitch
- PreviewChannel[State.ChannelIndex].AnalyzeBuffer();
-
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x + Width;
- y2 := y + Height;
-
- // init blend mode
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- // coordinates for tone boxes
- ToneBoxWidth := Width / NumHalftones;
- y1 := y1 + PitchBarInnerVSpacing;
- y2 := y2 - PitchBarInnerVSpacing;
-
- glBegin(GL_QUADS);
- // draw tone boxes
- for i := 0 to NumHalftones-1 do
- begin
- x1 := x + i * ToneBoxWidth + PitchBarInnerHSpacing;
- x2 := x1 + ToneBoxWidth - 2*PitchBarInnerHSpacing;
-
- if ((PreviewChannel[State.ChannelIndex].ToneValid) and
- (PreviewChannel[State.ChannelIndex].ToneAbs = i)) then
- begin
- // highlight current tone-pitch
- glColor3f(1, i / (NumHalftones-1), 0)
- end
- else
- begin
- // grey other tone-pitches
- glColor3f(0.3, i / (NumHalftones-1) * 0.3, 0);
- end;
-
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- end;
- glEnd();
-
- glDisable(GL_BLEND);
-
- ///
- // draw the name of the tone
- ///////
-
- ToneString := PChar(PreviewChannel[State.ChannelIndex].ToneString);
- ToneStringHeight := ChannelBarsTotalHeight;
-
- // initialize font
- // TODO: what about reflection, italic etc.?
- SetFontSize(ToneStringHeight/3);
-
- // center
- // Note: for centering let us assume that G#4 has the max. horizontal extent
- ToneStringWidth := glTextWidth(ToneString);
- ToneStringMaxWidth := glTextWidth('G#4');
- ToneStringCenterXOffset := (ToneStringMaxWidth-ToneStringWidth) / 2;
-
- // draw
- SetFontPos(x-ToneStringWidth-ToneStringCenterXOffset, y-ToneStringHeight/2);
- glColor3f(0, 0, 0);
- glPrint(ToneString);
-end;
-
-function TScreenOptionsRecord.Draw: boolean;
-var
- i: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
- SelectSlide: TSelectSlide;
- BarXOffset, BarYOffset, BarWidth: real;
- ChannelIndex: integer;
- State: TDrawState;
-begin
- DrawBG;
- DrawFG;
-
- if ((PreviewDeviceIndex >= 0) and
- (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
- DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
-
- // update source volume
- if (SDL_GetTicks() >= NextVolumePollTime) then
- begin
- NextVolumePollTime := SDL_GetTicks() + 500; // next poll in 500ms
- SourceVolume := Device.GetVolume();
- end;
-
- // get source select slide
- SelectSlide := SelectsS[SelectInputSourceID];
- BarXOffset := SelectSlide.TextureSBG.X;
- BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
- BarWidth := SelectSlide.TextureSBG.W;
- DrawVolume(SelectSlide.TextureSBG.X, BarYOffset, BarWidth, BarHeight);
-
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- begin
- // load player color mapped to current input channel
- if (DeviceCfg.ChannelToPlayerMap[ChannelIndex] > 0) then
- begin
- // set mapped channel to corresponding player-color
- LoadColor(State.R, State.G, State.B, 'P'+ IntToStr(DeviceCfg.ChannelToPlayerMap[ChannelIndex]) + 'Dark');
- end
- else
- begin
- // set non-mapped channel to white
- State.R := 1; State.G := 1; State.B := 1;
- end;
-
- // dark player colors
- State.RD := 0.2 * State.R;
- State.GD := 0.2 * State.G;
- State.BD := 0.2 * State.B;
-
- // channel select slide
- SelectSlide := SelectsS[SelectSlideChannelID[ChannelIndex]];
-
- BarXOffset := SelectSlide.TextureSBG.X;
- BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
- BarWidth := SelectSlide.TextureSBG.W;
-
- State.ChannelIndex := ChannelIndex;
-
- DrawVUMeter(State, BarXOffset, BarYOffset, BarWidth, BarHeight);
- DrawPitch(State, BarXOffset, BarYOffset+BarHeight, BarWidth, BarHeight);
- end;
- end;
-
- Result := True;
-end;
-
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas
deleted file mode 100644
index 9c602788..00000000
--- a/Game/Code/Screens/UScreenOptionsSound.pas
+++ /dev/null
@@ -1,133 +0,0 @@
-unit UScreenOptionsSound;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsSound = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: cardinal; CharCode: widechar;
- PressedDown: boolean): boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, SysUtils;
-
-function TScreenOptionsSound.ParseInput(PressedKey: cardinal;
- CharCode: widechar; PressedDown: boolean): boolean;
-begin
- Result := True;
- if (PressedDown) then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := False;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE:
- begin
- // Escape -> save nothing - just leave this screen
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 8 then
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP:
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < 8) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < 8) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-
-{**
- * Actually this one isn't pretty - but it does the trick of
- * turning the background music on/off in "real time"
- * bgm = background music
- * TODO: - Fetching the SelectInteraction via something more descriptive
- * - Obtaining the current value of a select is imho ugly
- *}
- if (SelInteraction = 1) then
- begin
- if TBackgroundMusicOption(SelectsS[1].SelectedOption) = bmoOn then
- SoundLib.StartBgMusic
- else
- SoundLib.PauseBgMusic;
- end;
-
-end;
-
-constructor TScreenOptionsSound.Create;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsSound);
-
- AddSelectSlide(Theme.OptionsSound.SelectSlideVoicePassthrough,
- Ini.VoicePassthrough, IVoicePassthrough);
- AddSelectSlide(Theme.OptionsSound.SelectBackgroundMusic,
- Ini.BackgroundMusicOption, IBackgroundMusic);
- AddSelectSlide(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost);
- // TODO: - MicBoost needs to be moved to ScreenOptionsRecord
- AddSelectSlide(Theme.OptionsSound.SelectClickAssist, Ini.ClickAssist, IClickAssist);
- AddSelectSlide(Theme.OptionsSound.SelectBeatClick, Ini.BeatClick, IBeatClick);
- AddSelectSlide(Theme.OptionsSound.SelectThreshold, Ini.ThresholdIndex, IThreshold);
- AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewVolume,
- Ini.PreviewVolume, IPreviewVolume);
- AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewFading,
- Ini.PreviewFading, IPreviewFading);
-
- AddButton(Theme.OptionsSound.ButtonExit);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
- Interaction := 0;
-end;
-
-procedure TScreenOptionsSound.onShow;
-begin
- inherited;
- Interaction := 0;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenOptionsThemes.pas b/Game/Code/Screens/UScreenOptionsThemes.pas
deleted file mode 100644
index a4f00b64..00000000
--- a/Game/Code/Screens/UScreenOptionsThemes.pas
+++ /dev/null
@@ -1,171 +0,0 @@
-unit UScreenOptionsThemes;
-
-interface
-
-{$I switches.inc}
-
-uses
- SDL,
- UMenu,
- UDisplay,
- UMusic,
- UFiles,
- UIni,
- UThemes;
-
-type
- TScreenOptionsThemes = class(TMenu)
- private
- procedure ReloadTheme;
- public
- SkinSelect: Integer;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure InteractInc; override;
- procedure InteractDec; override;
- end;
-
-implementation
-
-uses UMain,
- UGraphic,
- USkins,
- SysUtils;
-
-function TScreenOptionsThemes.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- // Escape -> save nothing - just leave this screen
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 3 then
- begin
- Ini.Save;
-
- // Reload all screens, after Theme changed
- // Todo : JB - Check if theme was actually changed
- UGraphic.UnLoadScreens();
- UGraphic.LoadScreens();
-
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 2) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 2) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-procedure TScreenOptionsThemes.InteractInc;
-begin
- inherited InteractInc;
-
- //Update Skins
- if (SelInteraction = 0) then
- begin
- Skin.OnThemeChange;
- UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
- end;
-
- ReloadTheme();
-end;
-
-procedure TScreenOptionsThemes.InteractDec;
-begin
- inherited InteractDec;
-
- //Update Skins
- if (SelInteraction = 0 ) then
- begin
- Skin.OnThemeChange;
- UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
- end;
-
- ReloadTheme();
-end;
-
-constructor TScreenOptionsThemes.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsThemes);
-
- AddSelectSlide(Theme.OptionsThemes.SelectTheme, Ini.Theme, ITheme);
-
- SkinSelect := AddSelectSlide(Theme.OptionsThemes.SelectSkin, Ini.SkinNo, ISkin);
-
- AddSelectSlide(Theme.OptionsThemes.SelectColor, Ini.Color, IColor);
-
- AddButton(Theme.OptionsThemes.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-end;
-
-procedure TScreenOptionsThemes.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-procedure TScreenOptionsThemes.ReloadTheme;
-begin
- Theme.LoadTheme(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color);
-
- ScreenOptionsThemes := TScreenOptionsThemes.create();
- ScreenOptionsThemes.onshow;
- Display.CurrentScreen := @ScreenOptionsThemes;
-
- ScreenOptionsThemes.Interaction := self.Interaction;
- ScreenOptionsThemes.Draw;
-
-
- Display.Draw;
- SwapBuffers;
-
- freeandnil( self );
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPartyNewRound.pas b/Game/Code/Screens/UScreenPartyNewRound.pas
deleted file mode 100644
index 057344dc..00000000
--- a/Game/Code/Screens/UScreenPartyNewRound.pas
+++ /dev/null
@@ -1,439 +0,0 @@
-unit UScreenPartyNewRound;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenPartyNewRound = class(TMenu)
- public
- //Texts:
- TextRound1: Cardinal;
- TextRound2: Cardinal;
- TextRound3: Cardinal;
- TextRound4: Cardinal;
- TextRound5: Cardinal;
- TextRound6: Cardinal;
- TextRound7: Cardinal;
-
- TextWinner1: Cardinal;
- TextWinner2: Cardinal;
- TextWinner3: Cardinal;
- TextWinner4: Cardinal;
- TextWinner5: Cardinal;
- TextWinner6: Cardinal;
- TextWinner7: Cardinal;
-
- TextNextRound: Cardinal;
- TextNextRoundNo: Cardinal;
- TextNextPlayer1: Cardinal;
- TextNextPlayer2: Cardinal;
- TextNextPlayer3: Cardinal;
-
- //Statics
- StaticRound1: Cardinal;
- StaticRound2: Cardinal;
- StaticRound3: Cardinal;
- StaticRound4: Cardinal;
- StaticRound5: Cardinal;
- StaticRound6: Cardinal;
- StaticRound7: Cardinal;
-
- //Scores
- TextScoreTeam1: Cardinal;
- TextScoreTeam2: Cardinal;
- TextScoreTeam3: Cardinal;
- TextNameTeam1: Cardinal;
- TextNameTeam2: Cardinal;
- TextNameTeam3: Cardinal;
-
- TextTeam1Players: Cardinal;
- TextTeam2Players: Cardinal;
- TextTeam3Players: Cardinal;
-
- StaticTeam1: Cardinal;
- StaticTeam2: Cardinal;
- StaticTeam3: Cardinal;
- StaticNextPlayer1: Cardinal;
- StaticNextPlayer2: Cardinal;
- StaticNextPlayer3: Cardinal;
-
-
-
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic,
- UMain,
- UIni,
- UTexture,
- UParty,
- UDLLManager,
- ULanguage,
- USong,
- ULog;
-
-function TScreenPartyNewRound.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
- end;
-
- SDLK_RETURN:
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- if DLLMan.Selected.LoadSong then
- begin
- //Select PartyMode ScreenSong
- ScreenSong.Mode := smPartyMode;
- FadeTo(@ScreenSong);
- end
- else
- begin
- FadeTo(@ScreenSingModi);
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenPartyNewRound.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- TextRound1 := AddText (Theme.PartyNewRound.TextRound1);
- TextRound2 := AddText (Theme.PartyNewRound.TextRound2);
- TextRound3 := AddText (Theme.PartyNewRound.TextRound3);
- TextRound4 := AddText (Theme.PartyNewRound.TextRound4);
- TextRound5 := AddText (Theme.PartyNewRound.TextRound5);
- TextRound6 := AddText (Theme.PartyNewRound.TextRound6);
- TextRound7 := AddText (Theme.PartyNewRound.TextRound7);
-
- TextWinner1 := AddText (Theme.PartyNewRound.TextWinner1);
- TextWinner2 := AddText (Theme.PartyNewRound.TextWinner2);
- TextWinner3 := AddText (Theme.PartyNewRound.TextWinner3);
- TextWinner4 := AddText (Theme.PartyNewRound.TextWinner4);
- TextWinner5 := AddText (Theme.PartyNewRound.TextWinner5);
- TextWinner6 := AddText (Theme.PartyNewRound.TextWinner6);
- TextWinner7 := AddText (Theme.PartyNewRound.TextWinner7);
-
- TextNextRound := AddText (Theme.PartyNewRound.TextNextRound);
- TextNextRoundNo := AddText (Theme.PartyNewRound.TextNextRoundNo);
- TextNextPlayer1 := AddText (Theme.PartyNewRound.TextNextPlayer1);
- TextNextPlayer2 := AddText (Theme.PartyNewRound.TextNextPlayer2);
- TextNextPlayer3 := AddText (Theme.PartyNewRound.TextNextPlayer3);
-
- StaticRound1 := AddStatic (Theme.PartyNewRound.StaticRound1);
- StaticRound2 := AddStatic (Theme.PartyNewRound.StaticRound2);
- StaticRound3 := AddStatic (Theme.PartyNewRound.StaticRound3);
- StaticRound4 := AddStatic (Theme.PartyNewRound.StaticRound4);
- StaticRound5 := AddStatic (Theme.PartyNewRound.StaticRound5);
- StaticRound6 := AddStatic (Theme.PartyNewRound.StaticRound6);
- StaticRound7 := AddStatic (Theme.PartyNewRound.StaticRound7);
-
- //Scores
- TextScoreTeam1 := AddText (Theme.PartyNewRound.TextScoreTeam1);
- TextScoreTeam2 := AddText (Theme.PartyNewRound.TextScoreTeam2);
- TextScoreTeam3 := AddText (Theme.PartyNewRound.TextScoreTeam3);
- TextNameTeam1 := AddText (Theme.PartyNewRound.TextNameTeam1);
- TextNameTeam2 := AddText (Theme.PartyNewRound.TextNameTeam2);
- TextNameTeam3 := AddText (Theme.PartyNewRound.TextNameTeam3);
-
- //Players
- TextTeam1Players := AddText (Theme.PartyNewRound.TextTeam1Players);
- TextTeam2Players := AddText (Theme.PartyNewRound.TextTeam2Players);
- TextTeam3Players := AddText (Theme.PartyNewRound.TextTeam3Players);
-
- StaticTeam1 := AddStatic (Theme.PartyNewRound.StaticTeam1);
- StaticTeam2 := AddStatic (Theme.PartyNewRound.StaticTeam2);
- StaticTeam3 := AddStatic (Theme.PartyNewRound.StaticTeam3);
- StaticNextPlayer1 := AddStatic (Theme.PartyNewRound.StaticNextPlayer1);
- StaticNextPlayer2 := AddStatic (Theme.PartyNewRound.StaticNextPlayer2);
- StaticNextPlayer3 := AddStatic (Theme.PartyNewRound.StaticNextPlayer3);
-
- LoadFromTheme(Theme.PartyNewRound);
-end;
-
-procedure TScreenPartyNewRound.onShow;
-var
- I: Integer;
- function GetTeamPlayers(const Num: Byte): String;
- var
- Players: Array of String;
- J: Byte;
- begin // to-do : Party
- if (Num-1 >= {PartySession.Teams.NumTeams}0) then
- exit;
-
- {//Create Players Array
- SetLength(Players, PartySession.Teams.TeamInfo[Num-1].NumPlayers);
- For J := 0 to PartySession.Teams.TeamInfo[Num-1].NumPlayers-1 do
- Players[J] := String(PartySession.Teams.TeamInfo[Num-1].PlayerInfo[J].Name);}
-
- //Implode and Return
- Result := Language.Implode(Players);
- end;
-begin
- inherited;
-
- // to-do : Party
- //PartySession.StartRound;
-
- //Set Visibility of Round Infos
- // to-do : Party
- I := {Length(PartySession.Rounds)}0;
- if (I >= 1) then
- begin
- Static[StaticRound1].Visible := True;
- Text[TextRound1].Visible := True;
- Text[TextWinner1].Visible := True;
-
- //Texts:
- //Text[TextRound1].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[0].Plugin].Name);
- //Text[TextWinner1].Text := PartySession.GetWinnerString(0);
- end
- else
- begin
- Static[StaticRound1].Visible := False;
- Text[TextRound1].Visible := False;
- Text[TextWinner1].Visible := False;
- end;
-
- if (I >= 2) then
- begin
- Static[StaticRound2].Visible := True;
- Text[TextRound2].Visible := True;
- Text[TextWinner2].Visible := True;
-
- //Texts:
- //Text[TextRound2].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[1].Plugin].Name);
- //Text[TextWinner2].Text := PartySession.GetWinnerString(1);
- end
- else
- begin
- Static[StaticRound2].Visible := False;
- Text[TextRound2].Visible := False;
- Text[TextWinner2].Visible := False;
- end;
-
- if (I >= 3) then
- begin
- Static[StaticRound3].Visible := True;
- Text[TextRound3].Visible := True;
- Text[TextWinner3].Visible := True;
-
- //Texts:
- //Text[TextRound3].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[2].Plugin].Name);
- //Text[TextWinner3].Text := PartySession.GetWinnerString(2);
- end
- else
- begin
- Static[StaticRound3].Visible := False;
- Text[TextRound3].Visible := False;
- Text[TextWinner3].Visible := False;
- end;
-
- if (I >= 4) then
- begin
- Static[StaticRound4].Visible := True;
- Text[TextRound4].Visible := True;
- Text[TextWinner4].Visible := True;
-
- //Texts:
- //Text[TextRound4].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[3].Plugin].Name);
- //Text[TextWinner4].Text := PartySession.GetWinnerString(3);
- end
- else
- begin
- Static[StaticRound4].Visible := False;
- Text[TextRound4].Visible := False;
- Text[TextWinner4].Visible := False;
- end;
-
- if (I >= 5) then
- begin
- Static[StaticRound5].Visible := True;
- Text[TextRound5].Visible := True;
- Text[TextWinner5].Visible := True;
-
- //Texts:
- //Text[TextRound5].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[4].Plugin].Name);
- //Text[TextWinner5].Text := PartySession.GetWinnerString(4);
- end
- else
- begin
- Static[StaticRound5].Visible := False;
- Text[TextRound5].Visible := False;
- Text[TextWinner5].Visible := False;
- end;
-
- if (I >= 6) then
- begin
- Static[StaticRound6].Visible := True;
- Text[TextRound6].Visible := True;
- Text[TextWinner6].Visible := True;
-
- //Texts:
- //Text[TextRound6].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[5].Plugin].Name);
- //Text[TextWinner6].Text := PartySession.GetWinnerString(5);
- end
- else
- begin
- Static[StaticRound6].Visible := False;
- Text[TextRound6].Visible := False;
- Text[TextWinner6].Visible := False;
- end;
-
- if (I >= 7) then
- begin
- Static[StaticRound7].Visible := True;
- Text[TextRound7].Visible := True;
- Text[TextWinner7].Visible := True;
-
- //Texts:
- //Text[TextRound7].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[6].Plugin].Name);
- //Text[TextWinner7].Text := PartySession.GetWinnerString(6);
- end
- else
- begin
- Static[StaticRound7].Visible := False;
- Text[TextRound7].Visible := False;
- Text[TextWinner7].Visible := False;
- end;
-
- //Display Scores
- {if (PartySession.Teams.NumTeams >= 1) then
- begin
- Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[0].Score);
- Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[0].Name);
- Text[TextTeam1Players].Text := GetTeamPlayers(1);
-
- Text[TextScoreTeam1].Visible := True;
- Text[TextNameTeam1].Visible := True;
- Text[TextTeam1Players].Visible := True;
- Static[StaticTeam1].Visible := True;
- Static[StaticNextPlayer1].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam1].Visible := False;
- Text[TextNameTeam1].Visible := False;
- Text[TextTeam1Players].Visible := False;
- Static[StaticTeam1].Visible := False;
- Static[StaticNextPlayer1].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[1].Score);
- Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[1].Name);
- Text[TextTeam2Players].Text := GetTeamPlayers(2);
-
- Text[TextScoreTeam2].Visible := True;
- Text[TextNameTeam2].Visible := True;
- Text[TextTeam2Players].Visible := True;
- Static[StaticTeam2].Visible := True;
- Static[StaticNextPlayer2].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam2].Visible := False;
- Text[TextNameTeam2].Visible := False;
- Text[TextTeam2Players].Visible := False;
- Static[StaticTeam2].Visible := False;
- Static[StaticNextPlayer2].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[2].Score);
- Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[2].Name);
- Text[TextTeam3Players].Text := GetTeamPlayers(3);
-
- Text[TextScoreTeam3].Visible := True;
- Text[TextNameTeam3].Visible := True;
- Text[TextTeam3Players].Visible := True;
- Static[StaticTeam3].Visible := True;
- Static[StaticNextPlayer3].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam3].Visible := False;
- Text[TextNameTeam3].Visible := False;
- Text[TextTeam3Players].Visible := False;
- Static[StaticTeam3].Visible := False;
- Static[StaticNextPlayer3].Visible := False;
- end;
-
- //nextRound Texts
- Text[TextNextRound].Text := Language.Translate(DllMan.Selected.PluginDesc);
- Text[TextNextRoundNo].Text := InttoStr(PartySession.CurRound + 1);
- if (PartySession.Teams.NumTeams >= 1) then
- begin
- Text[TextNextPlayer1].Text := PartySession.Teams.Teaminfo[0].Playerinfo[PartySession.Teams.Teaminfo[0].CurPlayer].Name;
- Text[TextNextPlayer1].Visible := True;
- end
- else
- Text[TextNextPlayer1].Visible := False;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Text[TextNextPlayer2].Text := PartySession.Teams.Teaminfo[1].Playerinfo[PartySession.Teams.Teaminfo[1].CurPlayer].Name;
- Text[TextNextPlayer2].Visible := True;
- end
- else
- Text[TextNextPlayer2].Visible := False;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Text[TextNextPlayer3].Text := PartySession.Teams.Teaminfo[2].Playerinfo[PartySession.Teams.Teaminfo[2].CurPlayer].Name;
- Text[TextNextPlayer3].Visible := True;
- end
- else
- Text[TextNextPlayer3].Visible := False; }
-
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenPartyNewRound.SetAnimationProgress(Progress: real);
-begin
- {Button[0].Texture.ScaleW := Progress;
- Button[1].Texture.ScaleW := Progress;
- Button[2].Texture.ScaleW := Progress; }
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas
deleted file mode 100644
index bd05e653..00000000
--- a/Game/Code/Screens/UScreenPartyOptions.pas
+++ /dev/null
@@ -1,279 +0,0 @@
-unit UScreenPartyOptions;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenPartyOptions = class(TMenu)
- public
- SelectLevel: Cardinal;
- SelectPlayList: Cardinal;
- SelectPlayList2: Cardinal;
- SelectRounds: Cardinal;
- SelectTeams: Cardinal;
- SelectPlayers1: Cardinal;
- SelectPlayers2: Cardinal;
- SelectPlayers3: Cardinal;
-
- PlayList: Integer;
- PlayList2: Integer;
- Rounds: Integer;
- NumTeams: Integer;
- NumPlayer1, NumPlayer2, NumPlayer3: Integer;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- procedure SetPlaylist2;
- end;
-
-var
- IPlaylist: array[0..2] of String;
- IPlaylist2: array of String;
-const
- ITeams: array[0..1] of String =('2', '3');
- IPlayers: array[0..3] of String =('1', '2', '3', '4');
- IRounds: array[0..5] of String = ('2', '3', '4', '5', '6', '7');
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, USong, UDLLManager, UPlaylist, USongs;
-
-function TScreenPartyOptions.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
- var
- I, J: Integer;
- OnlyMultiPlayer: boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
-
- SDLK_RETURN:
- begin
- //Don'T start when Playlist is Selected and there are no Playlists
- 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;
- end;
- //Save Difficulty
- Ini.Difficulty := SelectsS[SelectLevel].SelectedOption;
- Ini.SaveLevel;
-
-
- //Save Num Teams:
- {PartySession.Teams.NumTeams := NumTeams + 2;
- PartySession.Teams.Teaminfo[0].NumPlayers := NumPlayer1+1;
- PartySession.Teams.Teaminfo[1].NumPlayers := NumPlayer2+1;
- PartySession.Teams.Teaminfo[2].NumPlayers := NumPlayer3+1;}
-
- //Save Playlist
- PlaylistMan.Mode := TSingMode( Playlist );
- PlaylistMan.CurPlayList := High(Cardinal);
- //If Category Selected Search Category ID
- if Playlist = 1 then
- begin
- J := -1;
- For I := 0 to high(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Inc(J);
-
- if J = Playlist2 then
- begin
- PlaylistMan.CurPlayList := I;
- Break;
- end;
- end;
-
- //No Categorys or Invalid Entry
- If PlaylistMan.CurPlayList = High(Cardinal) then
- Exit;
- end
- else
- PlaylistMan.CurPlayList := Playlist2;
-
- //Start Party
- // to-do : Party
- //PartySession.StartNewParty(Rounds + 2);
-
- AudioPlayback.PlaySound(SoundLib.Start);
- //Go to Player Screen
- FadeTo(@ScreenPartyPlayer);
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
- SDLK_RIGHT:
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
-
- //Change Playlist2 if Playlist is Changed
- If (Interaction = 1) then
- begin
- SetPlaylist2;
- end //Change Team3 Players visibility
- Else If (Interaction = 4) then
- begin
- SelectsS[7].Visible := (NumTeams = 1);
- end;
- end;
- SDLK_LEFT:
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
-
- //Change Playlist2 if Playlist is Changed
- If (Interaction = 1) then
- begin
- SetPlaylist2;
- end //Change Team3 Players visibility
- Else If (Interaction = 4) then
- begin
- SelectsS[7].Visible := (NumTeams = 1);
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenPartyOptions.Create;
-var
- I: integer;
-begin
- inherited Create;
- //Fill IPlaylist
- IPlaylist[0] := Language.Translate('PARTY_PLAYLIST_ALL');
- IPlaylist[1] := Language.Translate('PARTY_PLAYLIST_CATEGORY');
- IPlaylist[2] := Language.Translate('PARTY_PLAYLIST_PLAYLIST');
-
- //Fill IPlaylist2
- SetLength(IPlaylist2, 1);
- IPlaylist2[0] := '---';
-
- //Clear all Selects
- NumTeams := 0;
- NumPlayer1 := 0;
- NumPlayer2 := 0;
- NumPlayer3 := 0;
- Rounds := 5;
- PlayList := 0;
- PlayList2 := 0;
-
- //Load Screen From Theme
- LoadFromTheme(Theme.PartyOptions);
-
- SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, Theme.ILevel);
- SelectPlayList := AddSelectSlide (Theme.PartyOptions.SelectPlayList, PlayList, IPlaylist);
- SelectPlayList2 := AddSelectSlide (Theme.PartyOptions.SelectPlayList2, PlayList2, IPlaylist2);
- SelectRounds := AddSelectSlide (Theme.PartyOptions.SelectRounds, Rounds, IRounds);
- SelectTeams := AddSelectSlide (Theme.PartyOptions.SelectTeams, NumTeams, ITeams);
- SelectPlayers1 := AddSelectSlide (Theme.PartyOptions.SelectPlayers1, NumPlayer1, IPlayers);
- SelectPlayers2 := AddSelectSlide (Theme.PartyOptions.SelectPlayers2, NumPlayer2, IPlayers);
- SelectPlayers3 := AddSelectSlide (Theme.PartyOptions.SelectPlayers3, NumPlayer3, IPlayers);
-
- Interaction := 0;
-
- //Hide Team3 Players
- SelectsS[7].Visible := False;
-end;
-
-procedure TScreenPartyOptions.SetPlaylist2;
-var I: Integer;
-begin
- Case Playlist of
- 0:
- begin
- SetLength(IPlaylist2, 1);
- IPlaylist2[0] := '---';
- end;
- 1:
- begin
- SetLength(IPlaylist2, 0);
- For I := 0 to high(CatSongs.Song) do
- begin
- If (CatSongs.Song[I].Main) then
- begin
- SetLength(IPlaylist2, Length(IPlaylist2) + 1);
- IPlaylist2[high(IPlaylist2)] := CatSongs.Song[I].Artist;
- end;
- end;
-
- If (Length(IPlaylist2) = 0) then
- begin
- SetLength(IPlaylist2, 1);
- IPlaylist2[0] := 'No Categories found';
- end;
- end;
- 2:
- begin
- if (Length(PlaylistMan.Playlists) > 0) then
- begin
- SetLength(IPlaylist2, Length(PlaylistMan.Playlists));
- PlaylistMan.GetNames(IPlaylist2);
- end
- else
- begin
- SetLength(IPlaylist2, 1);
- IPlaylist2[0] := 'No Playlists found';
- end;
- end;
- end;
-
- Playlist2 := 0;
- UpdateSelectSlideOptions(Theme.PartyOptions.SelectPlayList2, 2, IPlaylist2, Playlist2);
-end;
-
-procedure TScreenPartyOptions.onShow;
-begin
- inherited;
-
- Randomize;
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenPartyOptions.SetAnimationProgress(Progress: real);
-begin
- {for I := 0 to 6 do
- SelectS[I].Texture.ScaleW := Progress;}
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPartyPlayer.pas b/Game/Code/Screens/UScreenPartyPlayer.pas
deleted file mode 100644
index fa717677..00000000
--- a/Game/Code/Screens/UScreenPartyPlayer.pas
+++ /dev/null
@@ -1,340 +0,0 @@
-unit UScreenPartyPlayer;
-
-Interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenPartyPlayer = class(TMenu)
- public
- Team1Name: Cardinal;
- Player1Name: Cardinal;
- Player2Name: Cardinal;
- Player3Name: Cardinal;
- Player4Name: Cardinal;
-
- Team2Name: Cardinal;
- Player5Name: Cardinal;
- Player6Name: Cardinal;
- Player7Name: Cardinal;
- Player8Name: Cardinal;
-
- Team3Name: Cardinal;
- Player9Name: Cardinal;
- Player10Name: Cardinal;
- Player11Name: Cardinal;
- Player12Name: Cardinal;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, UParty;
-
-function TScreenPartyPlayer.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
-{*I, *}J: integer; // Auto Removed, Unused Variable (I)
- SDL_ModState: Word;
- procedure IntNext;
- begin
- repeat
- InteractNext;
- until Button[Interaction].Visible;
- end;
- procedure IntPrev;
- begin
- repeat
- InteractPrev;
- until Button[Interaction].Visible;
- end;
-begin
- Result := true;
-
- if (PressedDown) then
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT)
- else
- SDL_ModState := 0;
-
- begin // Key Down
- // check normal keys
- case CharCode of
- '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"':
- begin
- Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- // Templates for Names Mod
- SDLK_F1:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
- end;
- SDLK_F2:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
- end;
- SDLK_F3:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
- end;
- SDLK_F4:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
- end;
- SDLK_F5:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
- end;
- SDLK_F6:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
- end;
- SDLK_F7:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
- end;
- SDLK_F8:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
- end;
- SDLK_F9:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
- end;
- SDLK_F10:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
- end;
- SDLK_F11:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
- end;
- SDLK_F12:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
- end;
-
- SDLK_BACKSPACE:
- begin
- Button[Interaction].Text[0].DeleteLastL;
- end;
-
- SDLK_ESCAPE:
- begin
- Ini.SaveNames;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenPartyOptions);
- end;
-
- SDLK_RETURN:
- begin
-
- {//Save PlayerNames
- for I := 0 to PartySession.Teams.NumTeams-1 do
- begin
- PartySession.Teams.Teaminfo[I].Name := PChar(Button[I*5].Text[0].Text);
- for J := 0 to PartySession.Teams.Teaminfo[I].NumPlayers-1 do
- begin
- PartySession.Teams.Teaminfo[I].Playerinfo[J].Name := PChar(Button[I*5 + J+1].Text[0].Text);
- PartySession.Teams.Teaminfo[I].Playerinfo[J].TimesPlayed := 0;
- end;
- end;
-
- AudioPlayback.PlayStart;
- FadeTo(@ScreenPartyNewRound);}
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: IntNext;
- SDLK_UP: IntPrev;
- SDLK_RIGHT: IntNext;
- SDLK_LEFT: IntPrev;
- end;
- end;
-end;
-
-constructor TScreenPartyPlayer.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.PartyPlayer);
-
- Team1Name := AddButton(Theme.PartyPlayer.Team1Name);
- AddButton(Theme.PartyPlayer.Player1Name);
- AddButton(Theme.PartyPlayer.Player2Name);
- AddButton(Theme.PartyPlayer.Player3Name);
- AddButton(Theme.PartyPlayer.Player4Name);
-
- Team2Name := AddButton(Theme.PartyPlayer.Team2Name);
- AddButton(Theme.PartyPlayer.Player5Name);
- AddButton(Theme.PartyPlayer.Player6Name);
- AddButton(Theme.PartyPlayer.Player7Name);
- AddButton(Theme.PartyPlayer.Player8Name);
-
- Team3Name := AddButton(Theme.PartyPlayer.Team3Name);
- AddButton(Theme.PartyPlayer.Player9Name);
- AddButton(Theme.PartyPlayer.Player10Name);
- AddButton(Theme.PartyPlayer.Player11Name);
- AddButton(Theme.PartyPlayer.Player12Name);
-
- Interaction := 0;
-end;
-
-procedure TScreenPartyPlayer.onShow;
-var
- I: integer;
-begin
- inherited;
-
- // Templates for Names Mod
- for I := 1 to 4 do
- Button[I].Text[0].Text := Ini.Name[I-1];
-
- for I := 6 to 9 do
- Button[I].Text[0].Text := Ini.Name[I-2];
-
- for I := 11 to 14 do
- Button[I].Text[0].Text := Ini.Name[I-3];
-
- Button[0].Text[0].Text := Ini.NameTeam[0];
- Button[5].Text[0].Text := Ini.NameTeam[1];
- Button[10].Text[0].Text := Ini.NameTeam[2];
- // Templates for Names Mod end
-
- {If (PartySession.Teams.NumTeams>=1) then
- begin
- Button[0].Visible := True;
- Button[1].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=1);
- Button[2].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=2);
- Button[3].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=3);
- Button[4].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=4);
- end
- else
- begin
- Button[0].Visible := False;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := False;
- Button[4].Visible := False;
- end;
-
- If (PartySession.Teams.NumTeams>=2) then
- begin
- Button[5].Visible := True;
- Button[6].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=1);
- Button[7].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=2);
- Button[8].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=3);
- Button[9].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=4);
- end
- else
- begin
- Button[5].Visible := False;
- Button[6].Visible := False;
- Button[7].Visible := False;
- Button[8].Visible := False;
- Button[9].Visible := False;
- end;
-
- If (PartySession.Teams.NumTeams>=3) then
- begin
- Button[10].Visible := True;
- Button[11].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=1);
- Button[12].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=2);
- Button[13].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=3);
- Button[14].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=4);
- end
- else
- begin
- Button[10].Visible := False;
- Button[11].Visible := False;
- Button[12].Visible := False;
- Button[13].Visible := False;
- Button[14].Visible := False;
- end; }
-
-end;
-
-procedure TScreenPartyPlayer.SetAnimationProgress(Progress: real);
-var
- I: integer;
-begin
- for I := 0 to high(Button) do
- Button[I].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPartyScore.pas b/Game/Code/Screens/UScreenPartyScore.pas
deleted file mode 100644
index 176a94b2..00000000
--- a/Game/Code/Screens/UScreenPartyScore.pas
+++ /dev/null
@@ -1,302 +0,0 @@
-unit UScreenPartyScore;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
-
-type
- TScreenPartyScore = class(TMenu)
- public
- TextScoreTeam1: Cardinal;
- TextScoreTeam2: Cardinal;
- TextScoreTeam3: Cardinal;
- TextNameTeam1: Cardinal;
- TextNameTeam2: Cardinal;
- TextNameTeam3: Cardinal;
- StaticTeam1: Cardinal;
- StaticTeam1BG: Cardinal;
- StaticTeam1Deco: Cardinal;
- StaticTeam2: Cardinal;
- StaticTeam2BG: Cardinal;
- StaticTeam2Deco: Cardinal;
- StaticTeam3: Cardinal;
- StaticTeam3BG: Cardinal;
- StaticTeam3Deco: Cardinal;
- TextWinner: Cardinal;
-
- DecoTex: Array[0..5] of Integer;
- DecoColor: Array[0..5] of Record
- R, G, B: Real;
- end;
-
- MaxScore: Word;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage, UTexture, USkins;
-
-function TScreenPartyScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- {if (PartySession.CurRound < High(PartySession.Rounds)) then
- FadeTo(@ScreenPartyNewRound)
- else // to-do : Party
- begin
- PartySession.EndRound; }
- FadeTo(@ScreenPartyWin);
- //end;
- end;
-
- SDLK_RETURN:
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- // to-do : Party
- {if (PartySession.CurRound < High(PartySession.Rounds)) then
- FadeTo(@ScreenPartyNewRound)
- else }
- FadeTo(@ScreenPartyWin);
- end;
- end;
- end;
-end;
-
-constructor TScreenPartyScore.Create;
-var
-// I: integer; // Auto Removed, Unused Variable
- Tex: TTexture;
- R, G, B: Real;
- Color: Integer;
-begin
- inherited Create;
-
- TextScoreTeam1 := AddText (Theme.PartyScore.TextScoreTeam1);
- TextScoreTeam2 := AddText (Theme.PartyScore.TextScoreTeam2);
- TextScoreTeam3 := AddText (Theme.PartyScore.TextScoreTeam3);
- TextNameTeam1 := AddText (Theme.PartyScore.TextNameTeam1);
- TextNameTeam2 := AddText (Theme.PartyScore.TextNameTeam2);
- TextNameTeam3 := AddText (Theme.PartyScore.TextNameTeam3);
-
- StaticTeam1 := AddStatic (Theme.PartyScore.StaticTeam1);
- StaticTeam1BG := AddStatic (Theme.PartyScore.StaticTeam1BG);
- StaticTeam1Deco := AddStatic (Theme.PartyScore.StaticTeam1Deco);
- StaticTeam2 := AddStatic (Theme.PartyScore.StaticTeam2);
- StaticTeam2BG := AddStatic (Theme.PartyScore.StaticTeam2BG);
- StaticTeam2Deco := AddStatic (Theme.PartyScore.StaticTeam2Deco);
- StaticTeam3 := AddStatic (Theme.PartyScore.StaticTeam3);
- StaticTeam3BG := AddStatic (Theme.PartyScore.StaticTeam3BG);
- StaticTeam3Deco := AddStatic (Theme.PartyScore.StaticTeam3Deco);
-
- TextWinner := AddText (Theme.PartyScore.TextWinner);
-
- //Load Deco Textures
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- //Get Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.FirstColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[0].R := R;
- DecoColor[0].G := G;
- DecoColor[0].B := B;
-
- //Load Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture)), Theme.PartyScore.DecoTextures.FirstTyp, Color);
- DecoTex[0] := Tex.TexNum;
-
- //Get Second Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.SecondColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[1].R := R;
- DecoColor[1].G := G;
- DecoColor[1].B := B;
-
- //Load Second Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture)), Theme.PartyScore.DecoTextures.SecondTyp, Color);
- DecoTex[1] := Tex.TexNum;
-
- //Get Third Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.ThirdColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[2].R := R;
- DecoColor[2].G := G;
- DecoColor[2].B := B;
-
- //Load Third Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture)), Theme.PartyScore.DecoTextures.ThirdTyp, Color);
- DecoTex[2] := Tex.TexNum;
- end;
-
- LoadFromTheme(Theme.PartyScore);
-end;
-
-procedure TScreenPartyScore.onShow;
-var
- I, J: Integer;
- Placings: Array [0..5] of Byte;
-begin
- inherited;
-
-
- //Get Maxscore
-
- MaxScore := 0;
- for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- begin
- if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
- MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
- end;
-
- //Get Placings
- for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- begin
- Placings[I] := 0;
- for J := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- If (ScreenSingModi.PlayerInfo.Playerinfo[J].Score > ScreenSingModi.PlayerInfo.Playerinfo[I].Score) then
- Inc(Placings[I]);
- end;
-
-
- //Set Static Length
- Static[StaticTeam1].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
- Static[StaticTeam2].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
- Static[StaticTeam3].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
-
- //fix: prevents static from drawn out of bounds.
- if Static[StaticTeam1].Texture.ScaleW > 99 then Static[StaticTeam1].Texture.ScaleW := 99;
- if Static[StaticTeam2].Texture.ScaleW > 99 then Static[StaticTeam2].Texture.ScaleW := 99;
- if Static[StaticTeam3].Texture.ScaleW > 99 then Static[StaticTeam3].Texture.ScaleW := 99;
-
- //End Last Round // to-do : Party
- //PartySession.EndRound;
-
- //Set Winnertext
- //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(PartySession.CurRound)]);
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
- begin
- Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score);
- Text[TextNameTeam1].Text := String(ScreenSingModi.TeamInfo.Teaminfo[0].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam1Deco].Texture.TexNum := DecoTex[Placings[0]];
- Static[StaticTeam1Deco].Texture.ColR := DecoColor[Placings[0]].R;
- Static[StaticTeam1Deco].Texture.ColG := DecoColor[Placings[0]].G;
- Static[StaticTeam1Deco].Texture.ColB := DecoColor[Placings[0]].B;
- end;
-
- Text[TextScoreTeam1].Visible := True;
- Text[TextNameTeam1].Visible := True;
- Static[StaticTeam1].Visible := True;
- Static[StaticTeam1BG].Visible := True;
- Static[StaticTeam1Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam1].Visible := False;
- Text[TextNameTeam1].Visible := False;
- Static[StaticTeam1].Visible := False;
- Static[StaticTeam1BG].Visible := False;
- Static[StaticTeam1Deco].Visible := False;
- end;
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
- begin
- Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score);
- Text[TextNameTeam2].Text := String(ScreenSingModi.TeamInfo.Teaminfo[1].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam2Deco].Texture.TexNum := DecoTex[Placings[1]];
- Static[StaticTeam2Deco].Texture.ColR := DecoColor[Placings[1]].R;
- Static[StaticTeam2Deco].Texture.ColG := DecoColor[Placings[1]].G;
- Static[StaticTeam2Deco].Texture.ColB := DecoColor[Placings[1]].B;
- end;
-
- Text[TextScoreTeam2].Visible := True;
- Text[TextNameTeam2].Visible := True;
- Static[StaticTeam2].Visible := True;
- Static[StaticTeam2BG].Visible := True;
- Static[StaticTeam2Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam2].Visible := False;
- Text[TextNameTeam2].Visible := False;
- Static[StaticTeam2].Visible := False;
- Static[StaticTeam2BG].Visible := False;
- Static[StaticTeam2Deco].Visible := False;
- end;
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
- begin
- Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score);
- Text[TextNameTeam3].Text := String(ScreenSingModi.TeamInfo.Teaminfo[2].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam3Deco].Texture.TexNum := DecoTex[Placings[2]];
- Static[StaticTeam3Deco].Texture.ColR := DecoColor[Placings[2]].R;
- Static[StaticTeam3Deco].Texture.ColG := DecoColor[Placings[2]].G;
- Static[StaticTeam3Deco].Texture.ColB := DecoColor[Placings[2]].B;
- end;
-
- Text[TextScoreTeam3].Visible := True;
- Text[TextNameTeam3].Visible := True;
- Static[StaticTeam3].Visible := True;
- Static[StaticTeam3BG].Visible := True;
- Static[StaticTeam3Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam3].Visible := False;
- Text[TextNameTeam3].Visible := False;
- Static[StaticTeam3].Visible := False;
- Static[StaticTeam3BG].Visible := False;
- Static[StaticTeam3Deco].Visible := False;
- end;
-
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenPartyScore.SetAnimationProgress(Progress: real);
-begin
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
- Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
- Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
- Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPartyWin.pas b/Game/Code/Screens/UScreenPartyWin.pas
deleted file mode 100644
index 002c6f75..00000000
--- a/Game/Code/Screens/UScreenPartyWin.pas
+++ /dev/null
@@ -1,267 +0,0 @@
-unit UScreenPartyWin;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
-
-type
- TScreenPartyWin = class(TMenu)
- public
- TextScoreTeam1: Cardinal;
- TextScoreTeam2: Cardinal;
- TextScoreTeam3: Cardinal;
- TextNameTeam1: Cardinal;
- TextNameTeam2: Cardinal;
- TextNameTeam3: Cardinal;
- StaticTeam1: Cardinal;
- StaticTeam1BG: Cardinal;
- StaticTeam1Deco: Cardinal;
- StaticTeam2: Cardinal;
- StaticTeam2BG: Cardinal;
- StaticTeam2Deco: Cardinal;
- StaticTeam3: Cardinal;
- StaticTeam3BG: Cardinal;
- StaticTeam3Deco: Cardinal;
- TextWinner: Cardinal;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage;
-
-function TScreenPartyWin.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenMain);
- end;
-
- SDLK_RETURN:
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenMain);
- end;
- end;
- end;
-end;
-
-constructor TScreenPartyWin.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- TextScoreTeam1 := AddText (Theme.PartyWin.TextScoreTeam1);
- TextScoreTeam2 := AddText (Theme.PartyWin.TextScoreTeam2);
- TextScoreTeam3 := AddText (Theme.PartyWin.TextScoreTeam3);
- TextNameTeam1 := AddText (Theme.PartyWin.TextNameTeam1);
- TextNameTeam2 := AddText (Theme.PartyWin.TextNameTeam2);
- TextNameTeam3 := AddText (Theme.PartyWin.TextNameTeam3);
-
- StaticTeam1 := AddStatic (Theme.PartyWin.StaticTeam1);
- StaticTeam1BG := AddStatic (Theme.PartyWin.StaticTeam1BG);
- StaticTeam1Deco := AddStatic (Theme.PartyWin.StaticTeam1Deco);
- StaticTeam2 := AddStatic (Theme.PartyWin.StaticTeam2);
- StaticTeam2BG := AddStatic (Theme.PartyWin.StaticTeam2BG);
- StaticTeam2Deco := AddStatic (Theme.PartyWin.StaticTeam2Deco);
- StaticTeam3 := AddStatic (Theme.PartyWin.StaticTeam3);
- StaticTeam3BG := AddStatic (Theme.PartyWin.StaticTeam3BG);
- StaticTeam3Deco := AddStatic (Theme.PartyWin.StaticTeam3Deco);
-
- TextWinner := AddText (Theme.PartyWin.TextWinner);
-
- LoadFromTheme(Theme.PartyWin);
-end;
-
-procedure TScreenPartyWin.onShow;
-//var
-// I: Integer; // Auto Removed, Unused Variable
-// Placing: Integer; // Auto Removed, Unused Variable
-
- Function GetTeamColor(Team: Byte): Cardinal;
- var
- NameString: String;
- begin
- NameString := 'P' + InttoStr(Team+1) + 'Dark';
-
- Result := ColorExists(NameString);
- end;
-
-begin
- inherited;
-
- // to-do : Party
- //Get Team Placing
- //Placing := PartySession.GetTeamOrder;
-
- //Set Winnertext
- //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.Teams.Teaminfo[Placing[0]].Name]);
- {if (PartySession.Teams.NumTeams >= 1) then
- begin
- Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[0]].Score);
- Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[Placing[0]].Name);
-
- Text[TextScoreTeam1].Visible := True;
- Text[TextNameTeam1].Visible := True;
- Static[StaticTeam1].Visible := True;
- Static[StaticTeam1BG].Visible := True;
- Static[StaticTeam1Deco].Visible := True;
-
- //Set Static Color to Team Color
- If (Theme.PartyWin.StaticTeam1BG.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[0]);
- if (I <> -1) then
- begin
- Static[StaticTeam1BG].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam1BG].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam1BG].Texture.ColB := Color[I].RGB.B;
- end;
- end;
-
- If (Theme.PartyWin.StaticTeam1.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[0]);
- if (I <> -1) then
- begin
- Static[StaticTeam1].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam1].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam1].Texture.ColB := Color[I].RGB.B;
- end;
- end;
- end
- else
- begin
- Text[TextScoreTeam1].Visible := False;
- Text[TextNameTeam1].Visible := False;
- Static[StaticTeam1].Visible := False;
- Static[StaticTeam1BG].Visible := False;
- Static[StaticTeam1Deco].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[1]].Score);
- Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[Placing[1]].Name);
-
- Text[TextScoreTeam2].Visible := True;
- Text[TextNameTeam2].Visible := True;
- Static[StaticTeam2].Visible := True;
- Static[StaticTeam2BG].Visible := True;
- Static[StaticTeam2Deco].Visible := True;
-
- //Set Static Color to Team Color
- If (Theme.PartyWin.StaticTeam2BG.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[1]);
- if (I <> -1) then
- begin
- Static[StaticTeam2BG].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam2BG].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam2BG].Texture.ColB := Color[I].RGB.B;
- end;
- end;
-
- If (Theme.PartyWin.StaticTeam2.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[1]);
- if (I <> -1) then
- begin
- Static[StaticTeam2].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam2].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam2].Texture.ColB := Color[I].RGB.B;
- end;
- end;
- end
- else
- begin
- Text[TextScoreTeam2].Visible := False;
- Text[TextNameTeam2].Visible := False;
- Static[StaticTeam2].Visible := False;
- Static[StaticTeam2BG].Visible := False;
- Static[StaticTeam2Deco].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[2]].Score);
- Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[Placing[2]].Name);
-
- Text[TextScoreTeam3].Visible := True;
- Text[TextNameTeam3].Visible := True;
- Static[StaticTeam3].Visible := True;
- Static[StaticTeam3BG].Visible := True;
- Static[StaticTeam3Deco].Visible := True;
-
- //Set Static Color to Team Color
- If (Theme.PartyWin.StaticTeam3BG.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[2]);
- if (I <> -1) then
- begin
- Static[StaticTeam3BG].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam3BG].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam3BG].Texture.ColB := Color[I].RGB.B;
- end;
- end;
-
- If (Theme.PartyWin.StaticTeam3.Color = 'TeamColor') then
- begin
- I := GetTeamColor(Placing[2]);
- if (I <> -1) then
- begin
- Static[StaticTeam3].Texture.ColR := Color[I].RGB.R;
- Static[StaticTeam3].Texture.ColG := Color[I].RGB.G;
- Static[StaticTeam3].Texture.ColB := Color[I].RGB.B;
- end;
- end;
- end
- else
- begin
- Text[TextScoreTeam3].Visible := False;
- Text[TextNameTeam3].Visible := False;
- Static[StaticTeam3].Visible := False;
- Static[StaticTeam3BG].Visible := False;
- Static[StaticTeam3Deco].Visible := False;
- end; }
-
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenPartyWin.SetAnimationProgress(Progress: real);
-begin
- {if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
- Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Score / maxScore;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
- Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Score / maxScore;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
- Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Score / maxScore;}
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenPopup.pas b/Game/Code/Screens/UScreenPopup.pas
deleted file mode 100644
index b51fac98..00000000
--- a/Game/Code/Screens/UScreenPopup.pas
+++ /dev/null
@@ -1,252 +0,0 @@
-unit UScreenPopup;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenPopupCheck = class(TMenu)
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure ShowPopup(msg: String);
- function Draw: boolean; override;
- end;
-
-type
- TScreenPopupError = class(TMenu)
-{ private
- CurMenu: Byte; //Num of the cur. Shown Menu}
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- procedure ShowPopup(msg: String);
- function Draw: boolean; override;
- end;
-
-var
-// ISelections: Array of String;
- SelectValue: Integer;
-
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UPlaylist, UDisplay;
-
-function TScreenPopupCheck.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Display.CheckOK:=False;
- Display.NextScreenWithCheck:=NIL;
- Visible:=False;
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- case Interaction of
- 0: begin
- //Hack to Finish Singscreen correct on Exit with Q Shortcut
- if (Display.NextScreenWithCheck = NIL) then
- begin
- if (Display.CurrentScreen = @ScreenSing) then
- ScreenSing.Finish
- else if (Display.CurrentScreen = @ScreenSingModi) then
- ScreenSingModi.Finish;
- end;
-
- Display.CheckOK:=True;
- end;
- 1: begin
- Display.CheckOK:=False;
- Display.NextScreenWithCheck:=NIL;
- end;
- end;
- Visible:=False;
- Result := false;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenPopupCheck.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- AddBackground(Theme.CheckPopup.Background.Tex);
-
- AddButton(Theme.CheckPopup.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddButton(Theme.CheckPopup.Button2);
- if (Length(Button[1].Text) = 0) then
- AddButtonText(14, 20, 'Button 2');
-
- AddText(Theme.CheckPopup.TextCheck);
-
- for I := 0 to High(Theme.CheckPopup.Static) do
- AddStatic(Theme.CheckPopup.Static[I]);
-
- for I := 0 to High(Theme.CheckPopup.Text) do
- AddText(Theme.CheckPopup.Text[I]);
-
- Interaction := 0;
-end;
-
-function TScreenPopupCheck.Draw: boolean;
-begin
- Draw:=inherited Draw;
-end;
-
-procedure TScreenPopupCheck.onShow;
-begin
- inherited;
-end;
-
-procedure TScreenPopupCheck.ShowPopup(msg: String);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
-
- Text[0].Text := Language.Translate(msg);
-
- Button[0].Visible := True;
- Button[1].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_NO');
-end;
-
-// error popup
-
-function TScreenPopupError.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
-
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Visible:=False;
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- Visible:=False;
- Result := false;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenPopupError.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- AddBackground(Theme.CheckPopup.Background.Tex);
-
- AddButton(Theme.ErrorPopup.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddText(Theme.ErrorPopup.TextError);
-
- for I := 0 to High(Theme.ErrorPopup.Static) do
- AddStatic(Theme.ErrorPopup.Static[I]);
-
- for I := 0 to High(Theme.ErrorPopup.Text) do
- AddText(Theme.ErrorPopup.Text[I]);
-
- Interaction := 0;
-end;
-
-function TScreenPopupError.Draw: boolean;
-begin
- Draw:=inherited Draw;
-end;
-
-procedure TScreenPopupError.onShow;
-begin
- inherited;
-
-end;
-
-procedure TScreenPopupError.onHide;
-begin
-end;
-
-procedure TScreenPopupError.ShowPopup(msg: String);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
-
-{ //dirty hack... Text[0] is invisible for some strange reason
- for i:=1 to high(Text) do
- if i-1 <= high(msg) then
- begin
- Text[i].Visible:=True;
- Text[i].Text := msg[i-1];
- end
- else
- begin
- Text[i].Visible:=False;
- end;}
- Text[0].Text:=msg;
-
- Button[0].Visible := True;
-
- Button[0].Text[0].Text := 'OK';
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas
deleted file mode 100644
index ab6c020d..00000000
--- a/Game/Code/Screens/UScreenScore.pas
+++ /dev/null
@@ -1,848 +0,0 @@
-unit UScreenScore;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UDisplay,
- UMusic,
- USongs,
- UThemes,
- gl,
- math,
- UTexture;
-
-const
- ZBars : real = 0.8; // Z value for the bars
- ZRatingPic : real = 0.8; // Z value for the rating pictures
-
- EaseOut_MaxSteps : real = 10; // that's the speed of the bars (10 is fast | 100 is slower)
-
- BarRaiseSpeed : cardinal = 0; // Time for raising the bar one step higher (in ms)
-
-type
- TPlayerScoreScreenTexture = record // holds all colorized textures for up to 6 players
- //Bar textures
- Score_NoteBarLevel_Dark : TTexture; // Note
- Score_NoteBarRound_Dark : TTexture; // that's the round thing on top
-
- Score_NoteBarLevel_Light : TTexture; // LineBonus | Phrasebonus
- Score_NoteBarRound_Light : TTexture;
-
- Score_NoteBarLevel_Lightest : TTexture; // GoldenNotes
- Score_NoteBarRound_Lightest : TTexture;
- end;
-
- TPlayerScoreScreenData = record // holds the positions and other data
- Bar_Y :Real;
- Bar_Actual_Height : Real; // this one holds the actual height of the bar, while we animate it
- BarScore_ActualHeight : Real;
- BarLine_ActualHeight : Real;
- BarGolden_ActualHeight : Real;
- end;
-
- TPlayerScoreRatingPics = record // a fine array of the rating pictures
- RateEaseStep : Integer;
- RateEaseValue: Real;
- end;
-
- TScreenScore = class(TMenu)
- private
- BarTime : Cardinal;
- ArrayStartModifier : integer;
- public
- aPlayerScoreScreenTextures : array[1..6] of TPlayerScoreScreenTexture;
- aPlayerScoreScreenDatas : array[1..6] of TPlayerScoreScreenData;
- aPlayerScoreScreenRatings : array[1..6] of TPlayerScoreRatingPics;
-
- BarScore_EaseOut_Step : real;
- BarPhrase_EaseOut_Step : real;
- BarGolden_EaseOut_Step : real;
-
- TextArtist: integer;
- TextTitle: integer;
-
- TextArtistTitle : integer;
-
- TextName: array[1..6] of integer;
- TextScore: array[1..6] of integer;
-
- TextNotes: array[1..6] of integer;
- TextNotesScore: array[1..6] of integer;
- TextLineBonus: array[1..6] of integer;
- TextLineBonusScore: array[1..6] of integer;
- TextGoldenNotes: array[1..6] of integer;
- TextGoldenNotesScore: array[1..6] of integer;
- TextTotal: array[1..6] of integer;
- TextTotalScore: array[1..6] of integer;
-
- PlayerStatic: array[1..6] of array of integer;
- PlayerTexts : array[1..6] of array of integer;
-
-
- StaticBoxLightest: array[1..6] of integer;
- StaticBoxLight: array[1..6] of integer;
- StaticBoxDark: array[1..6] of integer;
-
- StaticBackLevel: array[1..6] of integer;
- StaticBackLevelRound: array[1..6] of integer;
- StaticLevel: array[1..6] of integer;
- StaticLevelRound: array[1..6] of integer;
-
- Animation: real;
-
- TextScore_ActualValue : array[1..6] of integer;
- TextPhrase_ActualValue : array[1..6] of integer;
- TextGolden_ActualValue : array[1..6] of integer;
-
-
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onShowFinish; override;
- function Draw: boolean; override;
- procedure FillPlayer(Item, P: integer);
-
- procedure EaseBarIn(PlayerNumber : Integer; BarType: String);
- procedure EaseScoreIn(PlayerNumber : Integer; ScoreType: String);
-
- procedure FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
-
-
- procedure DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
-
- //Rating Picture
- procedure ShowRating(PlayerNumber: integer);
- function CalculateBouncing(PlayerNumber : Integer): real;
- procedure DrawRating(PlayerNumber:integer;Rating:integer);
- end;
-
-implementation
-
-
-uses UGraphic,
- UScreenSong,
- UMenuStatic,
- UTime,
- UMain,
- UIni,
- ULog,
- ULanguage;
-
-function TScreenScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then begin
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE,
- SDLK_RETURN:
- begin
- FadeTo(@ScreenTop5);
- Exit;
- end;
-
- SDLK_SYSREQ:
- begin
- Display.SaveScreenShot;
- end;
- end;
- end;
-end;
-
-constructor TScreenScore.Create;
-var
- Player: integer;
- Counter: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Score);
-
- // These two texts arn't used in the deluxe skin
- TextArtist := AddText(Theme.Score.TextArtist);
- TextTitle := AddText(Theme.Score.TextTitle);
-
- TextArtistTitle := AddText(Theme.Score.TextArtistTitle);
-
- for Player := 1 to 6 do
- begin
- SetLength(PlayerStatic[Player], Length(Theme.Score.PlayerStatic[Player]));
- SetLength(PlayerTexts[Player], Length(Theme.Score.PlayerTexts[Player]));
-
- for Counter := 0 to High(Theme.Score.PlayerStatic[Player]) do
- PlayerStatic[Player, Counter] := AddStatic(Theme.Score.PlayerStatic[Player, Counter]);
-
- for Counter := 0 to High(Theme.Score.PlayerTexts[Player]) do
- PlayerTexts[Player, Counter] := AddText(Theme.Score.PlayerTexts[Player, Counter]);
-
- TextName[Player] := AddText(Theme.Score.TextName[Player]);
- TextScore[Player] := AddText(Theme.Score.TextScore[Player]);
-
- TextNotes[Player] := AddText(Theme.Score.TextNotes[Player]);
- TextNotesScore[Player] := AddText(Theme.Score.TextNotesScore[Player]);
- TextLineBonus[Player] := AddText(Theme.Score.TextLineBonus[Player]);
- TextLineBonusScore[Player] := AddText(Theme.Score.TextLineBonusScore[Player]);
- TextGoldenNotes[Player] := AddText(Theme.Score.TextGoldenNotes[Player]);
- TextGoldenNotesScore[Player] := AddText(Theme.Score.TextGoldenNotesScore[Player]);
- TextTotal[Player] := AddText(Theme.Score.TextTotal[Player]);
- TextTotalScore[Player] := AddText(Theme.Score.TextTotalScore[Player]);
-
- StaticBoxLightest[Player] := AddStatic(Theme.Score.StaticBoxLightest[Player]);
- StaticBoxLight[Player] := AddStatic(Theme.Score.StaticBoxLight[Player]);
- StaticBoxDark[Player] := AddStatic(Theme.Score.StaticBoxDark[Player]);
-
- StaticBackLevel[Player] := AddStatic(Theme.Score.StaticBackLevel[Player]);
- StaticBackLevelRound[Player] := AddStatic(Theme.Score.StaticBackLevelRound[Player]);
- StaticLevel[Player] := AddStatic(Theme.Score.StaticLevel[Player]);
- StaticLevelRound[Player] := AddStatic(Theme.Score.StaticLevelRound[Player]);
-
- //textures
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Dark := Tex_Score_NoteBarLevel_Dark[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Dark := Tex_Score_NoteBarRound_Dark[Player];
-
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Light := Tex_Score_NoteBarLevel_Light[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Light := Tex_Score_NoteBarRound_Light[Player];
-
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Lightest := Tex_Score_NoteBarLevel_Lightest[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Lightest := Tex_Score_NoteBarRound_Lightest[Player];
- end;
-
-end;
-
-procedure TScreenScore.onShow;
-var
- P: integer; // player
- I: integer;
- V: array[1..6] of boolean; // visibility array
-
-begin
-
-{**
- * Turn backgroundmusic on
- *}
- SoundLib.StartBgMusic;
-
- inherited;
-
- // all statics / texts are loaded at start - so that we have them all even if we change the amount of players
- // To show the corrects statics / text from the them, we simply modify the start of the according arrays
- // 1 Player -> Player[0].Score (The score for one player starts at 0)
- // -> Statics[1] (The statics for the one player screen start at 1)
- // 2 Player -> Player[0..1].Score
- // -> Statics[2..3]
- // 3 Player -> Player[0..5].Score
- // -> Statics[4..6]
- case PlayersPlay of
- 1: ArrayStartModifier := 0;
- 2, 4: ArrayStartModifier := 1;
- 3, 6: ArrayStartModifier := 3;
- else
- ArrayStartModifier := 0; //this should never happen
- end;
-
- for P := 1 to PlayersPlay do
- begin
- // data
- aPlayerScoreScreenDatas[P].Bar_Y := Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
-
- // ratings
- aPlayerScoreScreenRatings[P].RateEaseStep := 1;
- aPlayerScoreScreenRatings[P].RateEaseValue := 20;
- end;
-
-
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
-
- // set visibility
- case PlayersPlay of
- 1: begin
- V[1] := true;
- V[2] := false;
- V[3] := false;
- V[4] := false;
- V[5] := false;
- V[6] := false;
- end;
- 2, 4: begin
- V[1] := false;
- V[2] := true;
- V[3] := true;
- V[4] := false;
- V[5] := false;
- V[6] := false;
- end;
- 3, 6: begin
- V[1] := false;
- V[2] := false;
- V[3] := false;
- V[4] := true;
- V[5] := true;
- V[6] := true;
- end;
- end;
-
- for P := 1 to 6 do
- begin
- Text[TextName[P]].Visible := V[P];
- Text[TextScore[P]].Visible := V[P];
-
- // We set alpha to 0 , so we can nicely blend them in when we need them
- Text[TextScore[P]].Alpha := 0;
- Text[TextNotesScore[P]].Alpha := 0;
- Text[TextNotes[P]].Alpha := 0;
- Text[TextLineBonus[P]].Alpha := 0;
- Text[TextLineBonusScore[P]].Alpha := 0;
- Text[TextGoldenNotes[P]].Alpha := 0;
- Text[TextGoldenNotesScore[P]].Alpha := 0;
- Text[TextTotal[P]].Alpha := 0;
- Text[TextTotalScore[P]].Alpha := 0;
- Static[StaticBoxLightest[P]].Texture.Alpha := 0;
- Static[StaticBoxLight[P]].Texture.Alpha := 0;
- Static[StaticBoxDark[P]].Texture.Alpha := 0;
-
-
- Text[TextNotes[P]].Visible := V[P];
- Text[TextNotesScore[P]].Visible := V[P];
- Text[TextLineBonus[P]].Visible := V[P];
- Text[TextLineBonusScore[P]].Visible := V[P];
- Text[TextGoldenNotes[P]].Visible := V[P];
- Text[TextGoldenNotesScore[P]].Visible := V[P];
- Text[TextTotal[P]].Visible := V[P];
- Text[TextTotalScore[P]].Visible := V[P];
-
- for I := 0 to high(PlayerStatic[P]) do
- Static[PlayerStatic[P, I]].Visible := V[P];
-
- for I := 0 to high(PlayerTexts[P]) do
- Text[PlayerTexts[P, I]].Visible := V[P];
-
- Static[StaticBoxLightest[P]].Visible := V[P];
- Static[StaticBoxLight[P]].Visible := V[P];
- Static[StaticBoxDark[P]].Visible := V[P];
-
- // we draw that on our own
- Static[StaticBackLevel[P]].Visible := false;
- Static[StaticBackLevelRound[P]].Visible := false;
- Static[StaticLevel[P]].Visible := false;
- Static[StaticLevelRound[P]].Visible := false;
- end;
-end;
-
-procedure TScreenScore.onShowFinish;
-var
- index : integer;
-begin
- for index := 1 to (PlayersPlay) do
- begin
- TextScore_ActualValue[index] := 0;
- TextPhrase_ActualValue[index] := 0;
- TextGolden_ActualValue[index] := 0;
- end;
-
- BarScore_EaseOut_Step := 1;
- BarPhrase_EaseOut_Step := 1;
- BarGolden_EaseOut_Step := 1;
-end;
-
-function TScreenScore.Draw: boolean;
-var
- CurrentTime : Cardinal;
- PlayerCounter : integer;
-begin
-
- inherited Draw;
-{*
- player[0].ScoreInt := 7000;
- player[0].ScoreLineInt := 2000;
- player[0].ScoreGoldenInt := 1000;
- player[0].ScoreTotalInt := 10000;
-
- player[1].ScoreInt := 2500;
- player[1].ScoreLineInt := 1100;
- player[1].ScoreGoldenInt := 900;
- player[1].ScoreTotalInt := 4500;
-*}
- // Let's start to arise the bars
- CurrentTime := SDL_GetTicks();
- if((CurrentTime >= BarTime) AND ShowFinish) then
- begin
- BarTime := CurrentTime + BarRaiseSpeed;
-
- for PlayerCounter := 1 to PlayersPlay do
- begin
- // We actually arise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore)
- if (BarScore_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarScore_EaseOut_Step:= BarScore_EaseOut_Step + 1;
-
- // PhrasenBonus
- if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- if (BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1;
-
-
- // GoldenNotebonus
- if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- if (BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1;
-
- // Draw golden score bar #
- EaseBarIn(PlayerCounter, 'Golden');
- EaseScoreIn(PlayerCounter,'Golden');
- end;
-
- // Draw phrase score bar #
- EaseBarIn(PlayerCounter, 'Line');
- EaseScoreIn(PlayerCounter,'Line');
- end;
-
- // Draw plain score bar #
- EaseBarIn(PlayerCounter, 'Note');
- EaseScoreIn(PlayerCounter,'Note');
-
-
- FillPlayerItems(PlayerCounter,'Funky');
-
- end;
- end;
-
-
-(*
- //todo: i need a clever method to draw statics with their z value
- for I := 0 to Length(Static) - 1 do
- Static[I].Draw;
- for I := 0 to Length(Text) - 1 do
- Text[I].Draw;
-*)
-
- Result := true;
-end;
-
-procedure TscreenScore.FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
-var
- ThemeIndex: integer;
-begin
- // todo: take the name from player[PlayerNumber].Name instead of the ini when this is done (mog)
- Text[TextName[PlayerNumber + ArrayStartModifier]].Text := Ini.Name[PlayerNumber - 1];
- // end todo
-
- ThemeIndex := PlayerNumber + ArrayStartModifier;
-
- //golden
- Text[TextGoldenNotesScore[ThemeIndex]].Text := IntToStr(TextGolden_ActualValue[PlayerNumber]);
- Text[TextGoldenNotesScore[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
-
- Static[StaticBoxLightest[ThemeIndex]].Texture.Alpha := (BarGolden_EaseOut_Step / 100);
- Text[TextGoldenNotes[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
-
- // line bonus
- Text[TextLineBonusScore[ThemeIndex]].Text := IntToStr(TextPhrase_ActualValue[PlayerNumber]);
- Text[TextLineBonusScore[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
-
- Static[StaticBoxLight[ThemeIndex]].Texture.Alpha := (BarPhrase_EaseOut_Step / 100);
- Text[TextLineBonus[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
-
- // plain score
- Text[TextNotesScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber]);
- Text[TextNotes[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Static[StaticBoxDark[ThemeIndex]].Texture.Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextNotesScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- // total score
- Text[TextTotalScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber] + TextPhrase_ActualValue[PlayerNumber] + TextGolden_ActualValue[PlayerNumber]);
- Text[TextTotalScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- if(BarGolden_EaseOut_Step = 100) then
- begin
- ShowRating(PlayerNumber);
- end;
-end;
-
-
-procedure TScreenScore.ShowRating(PlayerNumber: integer);
-var
- Rating : integer;
- ThemeIndex : integer;
-begin
-
- ThemeIndex := PlayerNumber + ArrayStartModifier;
-
- case (Player[PlayerNumber-1].ScoreTotalInt) of
- 0..2009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
- Rating := 0;
- end;
- 2010..4009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_AMATEUR');
- Rating := 1;
- end;
- 4010..5009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_WANNABE');
- Rating := 2;
- end;
- 5010..6009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_HOPEFUL');
- Rating := 3;
- end;
- 6010..7509:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_RISING_STAR');
- Rating := 4;
- end;
- 7510..8509:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
- Rating := 5;
- end;
- 8510..9009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
- Rating := 6;
- end;
- 9010..10000:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_ULTRASTAR');
- Rating := 7;
- end;
- else
- Rating := 0; // Cheata :P
- end;
-
- //todo: this could break if the width is not given, for instance when there's a skin with no picture for ratings
- if ( Theme.Score.StaticRatings[ThemeIndex].W > 0 ) AND ( aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue > 0 ) then
- begin
- Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
- end;
- // end todo
-
- DrawRating(PlayerNumber, Rating);
-end;
-
-procedure TscreenScore.DrawRating(PlayerNumber:integer;Rating:integer);
-var
- Posx : real;
- Posy : real;
- Width :real;
-begin
-
- CalculateBouncing(PlayerNumber);
-
- PosX := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].X + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W * 0.5);
- PosY := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].Y + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].H * 0.5); ;
-
- Width := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue/2;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Score_Ratings[Rating].TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(PosX - Width, PosY - Width);
- glTexCoord2f(Tex_Score_Ratings[Rating].TexW, 0); glVertex2f(PosX + Width, PosY - Width);
- glTexCoord2f(Tex_Score_Ratings[Rating].TexW, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX + Width, PosY + Width);
- glTexCoord2f(0, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX - Width, PosY + Width);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-end;
-
-
-
-function TscreenScore.CalculateBouncing(PlayerNumber : Integer): real;
-var
- ReturnValue : real;
- p, s : real;
-
- RaiseStep, MaxVal : real;
- EaseOut_Step : integer;
-begin
- EaseOut_Step := aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep;
- MaxVal := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W;
-
- RaiseStep := EaseOut_Step;
-
- if (MaxVal > 0) AND (RaiseStep > 0) then
- RaiseStep := RaiseStep / MaxVal;
-
- if (RaiseStep = 1) then
- begin
- ReturnValue := MaxVal;
- end
- else
- begin
- p := MaxVal * 0.4;
-
- s := p/(2*PI) * arcsin (1);
- ReturnValue := MaxVal * power(2,-5 * RaiseStep) * sin( (RaiseStep * MaxVal - s) * (2 * PI) / p) + MaxVal;
-
- inc(aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep);
- aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue := ReturnValue;
- end;
-
- Result := ReturnValue;
-end;
-
-
-procedure TscreenScore.EaseBarIn(PlayerNumber : Integer; BarType: String);
-const
- RaiseSmoothness : integer = 100;
-var
- MaxHeight : real;
- NewHeight : real;
-
- Height2Reach : real;
- RaiseStep : real;
- BarStartPosY : single;
-
- lTmp : real;
- Score : integer;
-begin
- MaxHeight := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].H;
-
- // let's get the points according to the bar we draw
- // score array starts at 0, which means the score for player 1 is in score[0]
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- if (BarType = 'Note') then
- begin
- Score := Player[PlayerNumber - 1].ScoreInt;
- RaiseStep := BarScore_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight;
- end
- else if (BarType = 'Line') then
- begin
- Score := Player[PlayerNumber - 1].ScoreLineInt;
- RaiseStep := BarPhrase_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight;
- end
- else if (BarType = 'Golden') then
- begin
- Score := Player[PlayerNumber - 1].ScoreGoldenInt;
- RaiseStep := BarGolden_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight;
- end
- else
- begin
- Log.LogCritical('Unknown bar-type: ' + BarType, 'TScreenScore.EaseBarIn');
- Exit; // suppress warnings
- end;
-
- // the height dependend of the score
- Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight;
-
- if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then
- begin
- // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- lTmp := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY);
-
- if ( RaiseSmoothness > 0 ) and ( lTmp > 0 ) then
- NewHeight := lTmp / RaiseSmoothness;
-
- end
- else
- NewHeight := Height2Reach;
-
- DrawBar(BarType, PlayerNumber, BarStartPosY, NewHeight);
-
- if (BarType = 'Note') then
- aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight := NewHeight
- else if (BarType = 'Line') then
- aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight := NewHeight
- else if (BarType = 'Golden') then
- aPlayerScoreScreenDatas[PlayerNumber].BarGolden_ActualHeight := NewHeight;
-end;
-
-procedure TscreenScore.DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
-var
- Width:real;
- BarStartPosX:real;
-begin
- // this is solely for better readability of the drawing
- Width := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].W;
- BarStartPosX := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].X;
-
- glColor4f(1, 1, 1, 1);
-
- // set the texture for the bar
- if (BarType = 'Note') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Dark.TexNum);
- if (BarType = 'Line') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Light.TexNum);
- if (BarType = 'Golden') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Lightest.TexNum);
-
- //draw it
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY, ZBars);
- glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY, ZBars);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-
- //the round thing on top
- if (BarType = 'Note') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Dark.TexNum);
- if (BarType = 'Line') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Light.TexNum);
- if (BarType = 'Golden') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Lightest.TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex3f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
- glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
- glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-end;
-
-procedure TScreenScore.EaseScoreIn(PlayerNumber: integer; ScoreType : String);
-const
- RaiseSmoothness : integer = 100;
-var
- RaiseStep : Real;
- lTmpA : Real;
- ScoreReached :Integer;
- EaseOut_Step :Real;
- ActualScoreValue:integer;
-begin
- if (ScoreType = 'Note') then
- begin
- EaseOut_Step := BarScore_EaseOut_Step;
- ActualScoreValue := TextScore_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreInt;
- end;
- if (ScoreType = 'Line') then
- begin
- EaseOut_Step := BarPhrase_EaseOut_Step;
- ActualScoreValue := TextPhrase_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreLineInt;
- end;
- if (ScoreType = 'Golden') then
- begin
- EaseOut_Step := BarGolden_EaseOut_Step;
- ActualScoreValue := TextGolden_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt;
- end;
-
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- RaiseStep := EaseOut_Step;
-
- if (ActualScoreValue < ScoreReached) then
- begin
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20));
- if ( lTmpA > 0 ) AND
- ( RaiseSmoothness > 0 ) then
- begin
- if (ScoreType = 'Note') then
- TextScore_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- if (ScoreType = 'Line') then
- TextPhrase_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- if (ScoreType = 'Golden') then
- TextGolden_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- end;
- end
- else
- begin
- if (ScoreType = 'Note') then
- TextScore_ActualValue[PlayerNumber] := ScoreReached;
- if (ScoreType = 'Line') then
- TextPhrase_ActualValue[PlayerNumber] := ScoreReached;
- if (ScoreType = 'Golden') then
- TextGolden_ActualValue[PlayerNumber] := ScoreReached;
- end;
-end;
-
-procedure TScreenScore.FillPlayer(Item, P: integer);
-var
- S: string;
-begin
- Text[TextName[Item]].Text := Ini.Name[P];
-
- S := IntToStr((Round(Player[P].Score) div 10) * 10);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextNotesScore[Item]].Text := S;
-
- // while (Length(S)<5) do S := '0' + S;
- // Text[TextTotalScore[Item]].Text := S;
-
- //fixed: line bonus and golden notes don't show up,
- // another bug: total score was shown without added golden-, linebonus
- S := IntToStr(Player[P].ScoreTotalInt);
- while (Length(S)<5) do
- S := '0' + S;
- Text[TextTotalScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreLineInt);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextLineBonusScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreGoldenInt);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextGoldenNotesScore[Item]].Text := S;
- //end of fix
-
-
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
deleted file mode 100644
index 911d122e..00000000
--- a/Game/Code/Screens/UScreenSing.pas
+++ /dev/null
@@ -1,934 +0,0 @@
-unit UScreenSing;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses UMenu,
- UMusic,
- SDL,
- SysUtils,
- UFiles,
- UTime,
- USongs,
- UIni,
- ULog,
- UTexture,
- ULyrics,
- TextGL,
- gl,
- UThemes,
- UGraphicClasses,
- USingScores;
-
-type
- TLyricsSyncSource = class(TSyncSource)
- function GetClock(): real; override;
- end;
-
-type
- TScreenSing = class(TMenu)
- protected
- Paused: boolean; //Pause Mod
- LyricsSync: TLyricsSyncSource;
- NumEmptySentences: integer;
- public
- //TextTime: integer;
-
- // TimeBar fields
- StaticTimeProgress: integer;
- TextTimeText: integer;
-
- StaticP1: integer;
- TextP1: integer;
-
- //shown when game is in 2/4 player modus
- StaticP1TwoP: integer;
- TextP1TwoP: integer;
-
- //shown when game is in 3/6 player modus
- StaticP1ThreeP: integer;
- TextP1ThreeP: integer;
-
- StaticP2R: integer;
- TextP2R: integer;
-
- StaticP2M: integer;
- TextP2M: integer;
-
- StaticP3R: integer;
- TextP3R: integer;
-
- StaticPausePopup: integer;
-
- Tex_Background: TTexture;
- FadeOut: boolean;
- Lyrics: TLyricEngine;
-
- //Score Manager:
- Scores: TSingScores;
-
- fShowVisualization: boolean;
- fCurrentVideoPlaybackEngine: IVideoPlayback;
-
- constructor Create; override;
- procedure onShow; override;
- procedure onShowFinish; override;
-
- function ParseInput(PressedKey: cardinal; CharCode: widechar;
- PressedDown: boolean): boolean; override;
- function Draw: boolean; override;
-
- procedure Finish; virtual;
- procedure Pause; // Toggle Pause
-
- procedure OnSentenceEnd(SentenceIndex: cardinal); // for LineBonus + Singbar
- procedure OnSentenceChange(SentenceIndex: cardinal); // for Golden Notes
- end;
-
-implementation
-
-uses UGraphic,
- UDraw,
- UMain,
- USong,
- Classes,
- URecord,
- ULanguage,
- Math;
-
- // Method for input parsing. If False is returned, GetNextWindow
- // should be checked to know the next window to load;
-function TScreenSing.ParseInput(PressedKey: cardinal; CharCode: widechar;
- PressedDown: boolean): boolean;
-begin
- Result := True;
- if (PressedDown) then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- //When not ask before Exit then Finish now
- if (Ini.AskbeforeDel <> 1) then
- Finish
- //else just Pause and let the Popup make the Work
- else if not Paused then
- Pause;
-
- Result := False;
- Exit;
- end;
- 'V': //Show Visualization
- begin
- fShowVisualization := not fShowVisualization;
-
- if fShowVisualization then
- fCurrentVideoPlaybackEngine := Visualization
- else
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- if fShowVisualization then
- fCurrentVideoPlaybackEngine.play;
-
- Exit;
- end;
- 'P':
- begin
- Pause;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE:
- begin
- //Record Sound Hack:
- //Sound[0].BufferLong
-
- Finish;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenScore);
- end;
-
- SDLK_SPACE:
- begin
- Pause;
- end;
-
- SDLK_TAB: //Change Visualization Preset
- begin
- if fShowVisualization then
- fCurrentVideoPlaybackEngine.Position := now; // move to a random position
- end;
-
- SDLK_RETURN:
- begin
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN:
- begin
- end;
- SDLK_UP:
- begin
- end;
- end;
- end;
-end;
-
-//Pause Mod
-procedure TScreenSing.Pause;
-begin
- if (not Paused) then //enable Pause
- begin
- // pause Time
- Paused := True;
-
- LyricsState.Pause();
-
- // pause Music
- AudioPlayback.Pause;
-
- // pause Video
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path +
- CurrentSong.Video) then
- fCurrentVideoPlaybackEngine.Pause;
-
- end
- else //disable Pause
- begin
- LyricsState.Resume();
-
- // Play Music
- AudioPlayback.Play;
-
- // Video
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path +
- CurrentSong.Video) then
- fCurrentVideoPlaybackEngine.Pause;
-
- Paused := False;
- end;
-end;
-//Pause Mod End
-
-constructor TScreenSing.Create;
-var
- I: integer;
- P: integer;
-begin
- inherited Create;
-
- fShowVisualization := False;
-
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- //Create Score Class
- Scores := TSingScores.Create;
- Scores.LoadfromTheme;
-
- LoadFromTheme(Theme.Sing);
-
- //TimeBar
- StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
- TextTimeText := AddText(Theme.Sing.TextTimeText);
-
- // 1 player | P1
- StaticP1 := AddStatic(Theme.Sing.StaticP1);
- TextP1 := AddText(Theme.Sing.TextP1);
-
- // 2 or 4 players | P1
- StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
- TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
-
- // | P2
- StaticP2R := AddStatic(Theme.Sing.StaticP2R);
- TextP2R := AddText(Theme.Sing.TextP2R);
-
- // 3 or 6 players | P1
- StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
- TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
-
- // | P2
- StaticP2M := AddStatic(Theme.Sing.StaticP2M);
- TextP2M := AddText(Theme.Sing.TextP2M);
-
- // | P3
- StaticP3R := AddStatic(Theme.Sing.StaticP3R);
- TextP3R := AddText(Theme.Sing.TextP3R);
-
- StaticPausePopup := AddStatic(Theme.Sing.PausePopUp);
-
- //Pausepopup is not visibile at the beginning
- Static[StaticPausePopup].Visible := False;
-
- Lyrics := TLyricEngine.Create(80, Skin_LyricsT, 640, 12, 80, Skin_LyricsT + 36, 640, 12);
-
- LyricsSync := TLyricsSyncSource.Create();
-end;
-
-procedure TScreenSing.onShow;
-var
- P: integer;
- V1: boolean;
- V1TwoP: boolean; //Position of ScoreBox in two-player mode
- V1ThreeP: boolean; //Position of ScoreBox in three-player mode
- V2R: boolean;
- V2M: boolean;
- V3R: boolean;
- NR: TRecR; //Some enlightment of who, how and what this is here please
- Color: TRGB;
-
- success: boolean;
-begin
- inherited;
-
- Log.LogStatus('Begin', 'onShow');
- FadeOut := False;
-
- // reset video playback engine, to play Video Clip...
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- // setup score manager
- Scores.ClearPlayers; // clear old player values
- Color.R := 0;
- Color.G := 0;
- Color.B := 0; // dummy atm <- \(O.o)/? B like bummy?
-
- // add new players
- for P := 0 to PlayersPlay - 1 do
- begin
- Scores.AddPlayer(Tex_ScoreBG[P], Color);
- end;
-
- Scores.Init; //Get Positions for Players
-
- // prepare players
- SetLength(Player, PlayersPlay);
-
- case PlayersPlay of
- 1:
- begin
- V1 := True;
- V1TwoP := False;
- V1ThreeP := False;
- V2R := False;
- V2M := False;
- V3R := False;
- end;
- 2:
- begin
- V1 := False;
- V1TwoP := True;
- V1ThreeP := False;
- V2R := True;
- V2M := False;
- V3R := False;
- end;
- 3:
- begin
- V1 := False;
- V1TwoP := False;
- V1ThreeP := True;
- V2R := False;
- V2M := True;
- V3R := True;
- end;
- 4:
- begin // double screen
- V1 := False;
- V1TwoP := True;
- V1ThreeP := False;
- V2R := True;
- V2M := False;
- V3R := False;
- end;
- 6:
- begin // double screen
- V1 := False;
- V1TwoP := False;
- V1ThreeP := True;
- V2R := False;
- V2M := True;
- V3R := True;
- end;
-
- end;
-
- //This one is shown in 1P mode
- Static[StaticP1].Visible := V1;
- Text[TextP1].Visible := V1;
-
-
- //This one is shown in 2/4P mode
- Static[StaticP1TwoP].Visible := V1TwoP;
- Text[TextP1TwoP].Visible := V1TwoP;
-
- Static[StaticP2R].Visible := V2R;
- Text[TextP2R].Visible := V2R;
-
-
- //This one is shown in 3/6P mode
- Static[StaticP1ThreeP].Visible := V1ThreeP;
- Text[TextP1ThreeP].Visible := V1ThreeP;
-
-
- Static[StaticP2M].Visible := V2M;
- Text[TextP2M].Visible := V2M;
-
-
- Static[StaticP3R].Visible := V3R;
- Text[TextP3R].Visible := V3R;
-
-
- // FIXME: sets Path and Filename to ''
- ResetSingTemp;
-
- CurrentSong := CatSongs.Song[CatSongs.Selected];
-
- // FIXME: bad style, put the try-except into LoadSong() and not here
- try
- // Check if file is XML
- if copy(CurrentSong.FileName, length(CurrentSong.FileName) - 3, 4) = '.xml' then
- success := CurrentSong.LoadXMLSong()
- else
- success := CurrentSong.LoadSong();
- except
- success := False;
- end;
-
- if (not success) then
- begin
- // error loading song -> go back to song screen and show some error message
- FadeTo(@ScreenSong);
- // select new song in party mode
- if ScreenSong.Mode = smPartyMode then
- ScreenSong.SelectRandomSong();
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_CORRUPT_SONG'));
- // FIXME: do we need this?
- CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
- Exit;
- end;
-
- // reset video playback engine, to play video clip...
- fCurrentVideoPlaybackEngine.Close;
- fCurrentVideoPlaybackEngine := VideoPlayback;
-{**
- * == Background ==
- * We have four types of backgrounds:
- * + Blank : Nothing has been set, this is our fallback
- * + Picture : Picture has been set, and exists - otherwise we fallback
- * + Video : Video has been set, and exists - otherwise we fallback
- * + Visualization: + Off : No Visialization
- * + WhenNoVideo: Overwrites Blank and Picture
- * + On : Overwrites Blank, Picture and Video
- *}
-{**
- * set background to: video
- *}
- CurrentSong.VideoLoaded := False;
- fShowVisualization := False;
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
- begin
- if (fCurrentVideoPlaybackEngine.Open(CurrentSong.Path + CurrentSong.Video)) then
- begin
- fShowVisualization := False;
- fCurrentVideoPlaybackEngine := VideoPlayback;
- fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start;
- CurrentSong.VideoLoaded := True;
- fCurrentVideoPlaybackEngine.play;
- end;
- end;
-
-{**
- * set background to: picture
- *}
- if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = False)
- and (TVisualizerOption(Ini.VisualizerOption) = voOff) then
- try
- Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background);
- except
- Log.LogError('Background could not be loaded: ' + CurrentSong.Path +
- CurrentSong.Background);
- Tex_Background.TexNum := 0;
- end
- else
- Tex_Background.TexNum := 0;
-{**
- * set background to: visualization (Overwrites all)
- *}
- if (TVisualizerOption(Ini.VisualizerOption) in [voOn]) then
- begin
- fShowVisualization := True;
- fCurrentVideoPlaybackEngine := Visualization;
- fCurrentVideoPlaybackEngine.play;
- end;
-
-{**
- * set background to: visualization (Videos are still shown)
- *}
- if ((TVisualizerOption(Ini.VisualizerOption) in [voWhenNoVideo]) and
- (CurrentSong.VideoLoaded = False)) then
- begin
- fShowVisualization := True;
- fCurrentVideoPlaybackEngine := Visualization;
- fCurrentVideoPlaybackEngine.play;
- end;
-
- // prepare lyrics timer
- LyricsState.Reset();
- LyricsState.SetCurrentTime(CurrentSong.Start);
- LyricsState.StartTime := CurrentSong.Gap;
- if (CurrentSong.Finish > 0) then
- LyricsState.TotalTime := CurrentSong.Finish / 1000
- else
- LyricsState.TotalTime := AudioPlayback.Length;
- LyricsState.UpdateBeats();
-
- // prepare music
- AudioPlayback.Stop();
- AudioPlayback.Position := CurrentSong.Start;
- // synchronize music to the lyrics
- AudioPlayback.SetSyncSource(LyricsSync);
-
- // prepare and start voice-capture
- AudioInput.CaptureStart;
-
- for P := 0 to High(Player) do
- ClearScores(P);
-
- // main text
- Lyrics.Clear(CurrentSong.BPM[0].BPM, CurrentSong.Resolution);
-
- // set custom options
- case Ini.LyricsFont of
- 0:
- begin
- Lyrics.UpperLineSize := 14;
- Lyrics.LowerLineSize := 14;
- Lyrics.FontStyle := 0;
-
- Lyrics.LineColor_en.R := Skin_FontR;
- Lyrics.LineColor_en.G := Skin_FontG;
- Lyrics.LineColor_en.B := Skin_FontB;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.4;
- Lyrics.LineColor_dis.G := 0.4;
- Lyrics.LineColor_dis.B := 0.4;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 5 / 256;
- Lyrics.LineColor_act.G := 163 / 256;
- Lyrics.LineColor_act.B := 210 / 256;
- Lyrics.LineColor_act.A := 1;
- end;
- 1:
- begin
- Lyrics.UpperLineSize := 14;
- Lyrics.LowerLineSize := 14;
- Lyrics.FontStyle := 2;
-
- Lyrics.LineColor_en.R := 0.75;
- Lyrics.LineColor_en.G := 0.75;
- Lyrics.LineColor_en.B := 1;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.8;
- Lyrics.LineColor_dis.G := 0.8;
- Lyrics.LineColor_dis.B := 0.8;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 0.5;
- Lyrics.LineColor_act.G := 0.5;
- Lyrics.LineColor_act.B := 1;
- Lyrics.LineColor_act.A := 1;
- end;
- 2:
- begin
- Lyrics.UpperLineSize := 12;
- Lyrics.LowerLineSize := 12;
- Lyrics.FontStyle := 3;
-
- Lyrics.LineColor_en.R := 0.75;
- Lyrics.LineColor_en.G := 0.75;
- Lyrics.LineColor_en.B := 1;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.8;
- Lyrics.LineColor_dis.G := 0.8;
- Lyrics.LineColor_dis.B := 0.8;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 0.5;
- Lyrics.LineColor_act.G := 0.5;
- Lyrics.LineColor_act.B := 1;
- Lyrics.LineColor_act.A := 1;
- end;
- end; // case
-
- // Initialize lyrics by filling its queue
- while (not Lyrics.IsQueueFull) and (Lyrics.LineCounter <=
- High(Lines[0].Line)) do
- begin
- Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
- end;
-
- // Deactivate pause
- Paused := False;
-
- // Kill all stars not killed yet (GoldenStarsTwinkle Mod)
- GoldenRec.SentenceChange;
-
- // set Position of Line Bonus - Line Bonus end
- // set number of empty sentences for Line Bonus
- NumEmptySentences := 0;
- for P := Low(Lines[0].Line) to High(Lines[0].Line) do
- if Lines[0].Line[P].TotalNotes = 0 then
- Inc(NumEmptySentences);
-
- Log.LogStatus('End', 'onShow');
-end;
-
-procedure TScreenSing.onShowFinish;
-begin
- // start lyrics
- LyricsState.Resume();
-
- // start music
- AudioPlayback.Play();
-
- // start timer
- CountSkipTimeSet;
-end;
-
-function TScreenSing.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Flash: real;
- S: integer;
- T: integer;
- CurLyricsTime: real;
-begin
-
- // set player names (for 2 screens and only Singstar skin)
- if ScreenAct = 1 then
- begin
- Text[TextP1].Text := 'P1';
- Text[TextP1TwoP].Text := 'P1';
- Text[TextP1ThreeP].Text := 'P1';
- Text[TextP2R].Text := 'P2';
- Text[TextP2M].Text := 'P2';
- Text[TextP3R].Text := 'P3';
- end;
-
- if ScreenAct = 2 then
- begin
- case PlayersPlay of
- 4:
- begin
- Text[TextP1TwoP].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 6:
- begin
- Text[TextP1ThreeP].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- end; // case
- end; // if
-
-
- ////
- // dual screen, part 1
- ////////////////////////
-
- // Note: ScreenX is the offset of the current screen in dual-screen mode so we
- // will move the statics and texts to the correct screen here.
- // FIXME: clean up this weird stuff. Commenting this stuff out, nothing
- // was missing on screen w/ 6 players - so do we even need this stuff?
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10 * ScreenX;
-
- Text[TextP1].X := Text[TextP1].X + 10 * ScreenX;
-
- {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10 * ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X + 10 * ScreenX;
-
- {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
-
- // end of weird stuff
-
- Static[1].Texture.X := Static[1].Texture.X + 10 * ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X + 10 * ScreenX;
-
-
-
- // retrieve current lyrics time, we have to store the value to avoid
- // that min- and sec-values do not match
- CurLyricsTime := LyricsState.GetCurrentTime();
- Min := Round(CurLyricsTime) div 60;
- Sec := Round(CurLyricsTime) mod 60;
-
- // update static menu with time ...
- Text[TextTimeText].Text := '';
- if Min < 10 then
- Text[TextTimeText].Text := '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
- if Sec < 10 then
- Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
-
- // draw static menu (BG)
- // Note: there is no menu and the animated background brakes the video playback
- //DrawBG;
-
- // Draw Background
- SingDrawBackground;
-
- // update and draw movie
- if (ShowFinish and (CurrentSong.VideoLoaded or fShowVisualization)) then
- begin
- if assigned(fCurrentVideoPlaybackEngine) then
- begin
- fCurrentVideoPlaybackEngine.GetFrame(LyricsState.GetCurrentTime());
- fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
- end;
- end;
-
- // draw static menu (FG)
- DrawFG;
-
- // check for music finish
- //Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LyricsState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish));
- if ShowFinish then
- begin
- if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or
- (LyricsState.GetCurrentTime() * 1000 <= CurrentSong.Finish)) then
- begin
- // analyze song if not paused
- if (not Paused) then
- Sing(Self);
- end
- else
- begin
- if (not FadeOut) then
- begin
- Finish;
- FadeOut := True;
- FadeTo(@ScreenScore);
- end;
- end;
- end;
-
- // always draw custom items
- SingDraw;
-
- //GoldenNoteStarsTwinkle
- GoldenRec.SpawnRec;
-
- //Draw Scores
- Scores.Draw;
-
- ////
- // dual screen, part 2
- ////////////////////////
-
- // Note: ScreenX is the offset of the current screen in dual-screen mode so we
- // will move the statics and texts to the correct screen here.
- // FIXME: clean up this weird stuff
-
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10 * ScreenX;
- Text[TextP1].X := Text[TextP1].X - 10 * ScreenX;
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10 * ScreenX;
- Text[TextP2R].X := Text[TextP2R].X - 10 * ScreenX;
-
- //end of weird
-
- Static[1].Texture.X := Static[1].Texture.X - 10 * ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X - 10 * ScreenX;
-
- // Draw Pausepopup
- // FIXME: this is a workaround that the Static is drawn over the Lyrics, Lines, Scores and Effects
- // maybe someone could find a better solution
- if Paused then
- begin
- Static[StaticPausePopup].Visible := True;
- Static[StaticPausePopup].Draw;
- Static[StaticPausePopup].Visible := False;
- end;
-
- Result := True;
-end;
-
-procedure TScreenSing.Finish;
-begin
- AudioInput.CaptureStop;
- AudioPlayback.Stop;
- AudioPlayback.SetSyncSource(nil);
-
- if (Ini.SavePlayback = 1) then
- begin
- Log.BenchmarkStart(0);
- Log.LogVoice(0);
- Log.LogVoice(1);
- Log.LogVoice(2);
- Log.BenchmarkEnd(0);
- Log.LogBenchmark('Creating files', 0);
- end;
-
- if CurrentSong.VideoLoaded then
- begin
- fCurrentVideoPlaybackEngine.Close;
- CurrentSong.VideoLoaded := False; // to prevent drawing closed video
- end;
-
- SetFontItalic(False);
-end;
-
-procedure TScreenSing.OnSentenceEnd(SentenceIndex: cardinal);
-var
- PlayerIndex: integer;
- CurrentPlayer: PPLayer;
- CurrentScore: real;
- Line: PLine;
- LinePerfection: real; // perfection of singing performance on the current line
- Rating: integer;
- LineScore: real;
- LineBonus: real;
- MaxSongScore: integer; // max. points for the song (without line bonus)
- MaxLineScore: real; // max. points for the current line
-const
- // TODO: move this to a better place
- MAX_LINE_RATING = 8; // max. rating for singing performance
-begin
- Line := @Lines[0].Line[SentenceIndex];
-
- // check for empty sentence
- if (Line.TotalNotes <= 0) then
- Exit;
-
- // set max song score
- if (Ini.LineBonus = 0) then
- MaxSongScore := MAX_SONG_SCORE
- else
- MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
-
- // Note: ScoreValue is the sum of all note values of the song
- MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue);
-
- for PlayerIndex := 0 to High(Player) do
- begin
- CurrentPlayer := @Player[PlayerIndex];
- CurrentScore := CurrentPlayer.Score + CurrentPlayer.ScoreGolden;
-
- // Line Bonus
-
- // points for this line
- LineScore := CurrentScore - CurrentPlayer.ScoreLast;
-
- // determine LinePerfection
- // Note: the "+2" extra points are a little bonus so the player does not
- // have to be that perfect to reach the bonus steps.
- LinePerfection := (LineScore + 2) / MaxLineScore;
-
- // clamp LinePerfection to range [0..1]
- if (LinePerfection < 0) then
- LinePerfection := 0
- else if (LinePerfection > 1) then
- LinePerfection := 1;
-
- // add line-bonus if enabled
- if (Ini.LineBonus > 0) then
- begin
- // line-bonus points (same for each line, no matter how long the line is)
- LineBonus := MAX_SONG_LINE_BONUS / (Length(Lines[0].Line) -
- NumEmptySentences);
- // apply line-bonus
- CurrentPlayer.ScoreLine :=
- CurrentPlayer.ScoreLine + LineBonus * LinePerfection;
- CurrentPlayer.ScoreLineInt := Round(CurrentPlayer.ScoreLine / 10) * 10;
- // update total score
- CurrentPlayer.ScoreTotalInt :=
- CurrentPlayer.ScoreInt +
- CurrentPlayer.ScoreGoldenInt
- + CurrentPlayer.ScoreLineInt;
-
- // spawn rating pop-up
- Rating := Round(LinePerfection * MAX_LINE_RATING);
- Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt);
- end;
-
- // PerfectLineTwinkle (effect), Part 1
- if (Ini.EffectSing = 1) then
- CurrentPlayer.LastSentencePerfect := (LinePerfection >= 1);
-
- // refresh last score
- CurrentPlayer.ScoreLast := CurrentScore;
- end;
-
- // PerfectLineTwinkle (effect), Part 2
- if (Ini.EffectSing = 1) then
- GoldenRec.SpawnPerfectLineTwinkle;
-end;
-
- // Called on sentence change
- // SentenceIndex: index of the new active sentence
-procedure TScreenSing.OnSentenceChange(SentenceIndex: cardinal);
-var
- LyricEngine: TLyricEngine;
-begin
- //GoldenStarsTwinkle
- GoldenRec.SentenceChange;
-
- // Fill lyrics queue and set upper line to the current sentence
- while (Lyrics.GetUpperLineIndex() < SentenceIndex) or
- (not Lyrics.IsQueueFull) do
- begin
- // Add the next line to the queue or a dummy if no more lines are available
- if (Lyrics.LineCounter <= High(Lines[0].Line)) then
- Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter])
- else
- Lyrics.AddLine(nil);
- end;
-
- // AddLine draws the passed line to the back-buffer of the render context
- // and copies it into a texture afterwards (offscreen rendering).
- // This leaves an in invalidated screen. Calling Draw() makes sure,
- // that the back-buffer stores the sing-screen, when the next
- // swap between the back- and front-buffer is done (eliminates flickering)
- // calling AddLine() right before the regular screen update (Display.Draw)
- // would be a better solution.
- Draw;
-end;
-
-function TLyricsSyncSource.GetClock(): real;
-begin
- Result := LyricsState.GetCurrentTime();
-end;
-
-end.
-
diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas
deleted file mode 100644
index 616ba1c1..00000000
--- a/Game/Code/Screens/UScreenSingModi.pas
+++ /dev/null
@@ -1,707 +0,0 @@
-unit UScreenSingModi;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses UMenu,
- UMusic,
- SDL,
- SysUtils,
- UFiles,
- UTime,
- USongs,
- UIni,
- ULog,
- UTexture,
- ULyrics,
- TextGL,
- gl,
-
- UThemes,
- //ULCD, //TODO: maybe LCD Support as Plugin?
- UScreenSing,
- ModiSDK;
-
-type
- TScreenSingModi = class(TScreenSing)
- protected
- //paused: boolean; //Pause Mod
- //PauseTime: Real;
- //NumEmptySentences: integer;
- public
- //TextTime: integer;
-
- //StaticP1: integer;
- //StaticP1ScoreBG: integer;
- //TextP1: integer;
- //TextP1Score: integer;
-
- //StaticP2R: integer;
- //StaticP2RScoreBG: integer;
- //TextP2R: integer;
- //TextP2RScore: integer;
-
- //StaticP2M: integer;
- //StaticP2MScoreBG: integer;
- //TextP2M: integer;
- //TextP2MScore: integer;
-
- //StaticP3R: integer;
- //StaticP3RScoreBG: integer;
- //TextP3R: integer;
- //TextP3RScore: integer;
-
- //Tex_Background: TTexture;
- //FadeOut: boolean;
- //LyricMain: TLyric;
- //LyricSub: TLyric;
- Winner: Byte; //Who Wins
- PlayerInfo: TPlayerInfo;
- TeamInfo: TTeamInfo;
-
- constructor Create; override;
- procedure onShow; override;
- //procedure onShowFinish; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure Finish; override;
- //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //procedure Pause; //Pause Mod(Toggles Pause)
- end;
-
-type
- TCustomSoundEntry = record
- Filename : String;
- Stream : TAudioPlaybackStream;
- end;
-
-var
- //Custom Sounds
- CustomSounds: array of TCustomSoundEntry;
-
-//Procedured for Plugin
-function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall;
-//function Translate (const Name: PChar): PChar; stdcall;
-procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
-function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
-procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
-
-//Utilys
-function ToSentences(Const Lines: TLines): TSentences;
-
-implementation
-uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses;
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSingModi.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Finish;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenPartyScore);
- end;
-
- else
- Result := inherited ParseInput(PressedKey, CharCode, PressedDown);
- end;
- end;
-end;
-
-constructor TScreenSingModi.Create;
-begin
- inherited Create;
-
-end;
-
-function ToSentences(Const Lines: TLines): TSentences;
-var
- I, J: Integer;
-begin
- Result.Current := Lines.Current;
- Result.High := Lines.High;
- Result.Number := Lines.Number;
- Result.Resolution := Lines.Resolution;
- Result.NotesGAP := Lines.NotesGAP;
- Result.TotalLength := Lines.ScoreValue;
-
- SetLength(Result.Sentence, Length(Lines.Line));
- for I := low(Result.Sentence) to high(Result.Sentence) do
- begin
- Result.Sentence[I].Start := Lines.Line[I].Start;
- Result.Sentence[I].StartNote := Lines.Line[I].Note[0].Start;
- Result.Sentence[I].Lyric := Lines.Line[I].Lyric;
- Result.Sentence[I].LyricWidth := Lines.Line[I].LyricWidth;
- Result.Sentence[I].End_ := Lines.Line[I].End_;
- Result.Sentence[I].BaseNote := Lines.Line[I].BaseNote;
- Result.Sentence[I].HighNote := Lines.Line[I].HighNote;
- Result.Sentence[I].TotalNotes := Lines.Line[I].TotalNotes;
-
- SetLength(Result.Sentence[I].Note, Length(Lines.Line[I].Note));
- for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do
- begin
- Result.Sentence[I].Note[J].Color := Lines.Line[I].Note[J].Color;
- Result.Sentence[I].Note[J].Start := Lines.Line[I].Note[J].Start;
- Result.Sentence[I].Note[J].Length := Lines.Line[I].Note[J].Length;
- Result.Sentence[I].Note[J].Tone := Lines.Line[I].Note[J].Tone;
- //Result.Sentence[I].Note[J].Text := Lines.Line[I].Note[J].Tekst;
- Result.Sentence[I].Note[J].FreeStyle := (Lines.Line[I].Note[J].NoteType = ntFreestyle);
- end;
- end;
-end;
-
-procedure TScreenSingModi.onShow;
-var
- I: Integer;
-begin
- inherited;
-
- PlayersPlay := TeamInfo.NumTeams;
-
- if DLLMan.Selected.LoadSong then //Start with Song
- begin
- inherited;
- end
- else //Start Without Song
- begin
- AudioInput.CaptureStart;
- end;
-
-//Set Playerinfo
- PlayerInfo.NumPlayers := PlayersPlay;
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]);
- PlayerInfo.Playerinfo[I].Score := 0;
- PlayerInfo.Playerinfo[I].Bar := 50;
- PlayerInfo.Playerinfo[I].Enabled := True;
- end;
-
- for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do
- begin
- PlayerInfo.Playerinfo[I].Score:= 0;
- PlayerInfo.Playerinfo[I].Bar := 0;
- PlayerInfo.Playerinfo[I].Enabled := False;
- end;
-
- {Case PlayersPlay of
- 1: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
- end;
- 2,4: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
- PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
- PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
- PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
- PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
- end;
- 3,6: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
- PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
- PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
- PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X;
- PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
- PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X;
- PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
- PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
- PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
- end;
- end; }
-
- // play music (I)
- //Music.CaptureStart;
- //Music.MoveTo(AktSong.Start);
-
- //Init Plugin
- if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Lines[0]), LoadTex, Print, LoadSound, PlaySound) then
- begin
- //Fehler
- Log.LogError('Could not Init Plugin');
- Halt;
- end;
-
- // Set Background (Little Workaround, maybe change sometime)
- if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then
- ScreenSing.Tex_Background := Tex_Background;
-
- Winner := 0;
-
- //Set Score Visibility
- {if PlayersPlay = 1 then begin
- Text[TextP1Score].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore;
- end;
-
- if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin
- Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore;
- end;
-
- if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin
- Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore;
- end; }
-end;
-
-function TScreenSingModi.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- S, I: integer;
- T: integer;
- CurLyricsTime: real;
-begin
- Result := false;
-
- //Set Playerinfo
- PlayerInfo.NumPlayers := PlayersPlay;
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name);
- if PlayerInfo.Playerinfo[I].Enabled then
- begin
- if (Player[I].ScoreTotalInt <= MAX_SONG_SCORE) then
- PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalInt;
- PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100);
- end;
- end;
-
- //Show Score
- if DLLMan.Selected.ShowScore then
- begin
- {//ScoreBG Mod
- // set player colors
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
-
-
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
-
-
-
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P4Dark');
-
-
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
-
-
-
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P3Dark');
-
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
-
-
-
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P6Dark');
-
-
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
-
-
-
-
- end;
- end;
- //end ScoreBG Mod }
-
- // set player names (for 2 screens and only Singstar skin)
- if ScreenAct = 1 then begin
- Text[TextP1].Text := 'P1';
- Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin
- Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin
- Text[TextP2R].Text := 'P2';
- Text[TextP2M].Text := 'P2';
- Text[TextP3R].Text := 'P3';
- end;
-
- if ScreenAct = 2 then begin
- case PlayersPlay of
- 4: begin
- Text[TextP1TwoP].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 6: begin
- Text[TextP1ThreeP].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- end; // case
- end; // if
-
-
- // stereo <- and where iss P2M? or P3?
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
- Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
-
- {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
- Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
-
- {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
-
- // .. and scores
- {if PlayersPlay = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1Score].Text := Tekst;
- end;
-
- if PlayersPlay = 2 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 3 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[4].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[5].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- end; }
-
- end; //ShowScore
-
- for S := 1 to 1 do
- Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X + 10*ScreenX;
-
- if DLLMan.Selected.LoadSong then
- begin
- // update static menu with time ...
- CurLyricsTime := LyricsState.GetCurrentTime();
- Min := Round(CurLyricsTime) div 60;
- Sec := Round(CurLyricsTime) mod 60;
-
- Text[TextTimeText].Text := '';
- if Min < 10 then Text[TextTimeText].Text := '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
- if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
- end;
-
- // draw static menu (BG)
- DrawBG;
-
- //Draw Background
- if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then
- SingDrawBackground;
-
- // comment by blindy: wo zum henker wird denn in diesem screen ein video abgespielt?
- // update and draw movie
- // wie wo wadd? also in der selben funktion in der uscreensing kommt des video in der zeile 995, oder was wollteste wissen? :X
-{ if ShowFinish and CurrentSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin
- UpdateSmpeg; // this only draws
- end;}
-
- // draw static menu (FG)
- DrawFG;
-
- if ShowFinish then begin
- if DllMan.Selected.LoadSong then
- begin
- if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (LyricsState.GetCurrentTime*1000 <= CurrentSong.Finish)) then begin
- //Pause Mod:
- if not Paused then
- Sing(Self); // analyze song
- end else begin
- if not FadeOut then begin
- Finish;
- FadeOut := true;
- FadeTo(@ScreenPartyScore);
- end;
- end;
- end;
- end;
-
- // draw custom items
- SingModiDraw(PlayerInfo); // always draw
-
- //GoldenNoteStarsTwinkle Mod
- GoldenRec.SpawnRec;
- //GoldenNoteStarsTwinkle Mod
-
- //Update PlayerInfo
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- if PlayerInfo.Playerinfo[I].Enabled then
- begin
- //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
- PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalInt;
- end;
- end;
-
- if ((ShowFinish) AND (NOT Paused)) then
- begin
- if not DLLMan.PluginDraw(Playerinfo, Lines[0].Current) then
- begin
- if not FadeOut then begin
- Finish;
- FadeOut := true;
- FadeTo(@ScreenPartyScore);
- end;
- end;
- end;
-
- //Change PlayerInfo/Changeables
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- if (Player[I].ScoreTotalInt <> PlayerInfo.Playerinfo[I].Score) then
- begin
- //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI);
- Player[I].ScoreTotalInt := PlayerInfo.Playerinfo[I].Score;
- end;
- {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then
- Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; }
- end;
-
- // back stereo
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
- Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
-
- {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;}
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
- Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
-
- {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;}
-
-
- for S := 1 to 1 do
- Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X - 10*ScreenX;
-
- Result := true;
-end;
-
-procedure TScreenSingModi.Finish;
-begin
-inherited Finish;
-
-Winner := DllMan.PluginFinish(PlayerInfo);
-
-//Log.LogError('Winner: ' + InttoStr(Winner));
-
-//DLLMan.UnLoadPlugin;
-end;
-
-function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall;
-var
- Texname, EXT: String;
- Tex: TTexture;
-begin
- //Get texture Name
- TexName := Skin.GetTextureFileName(String(Name));
- //Get File Typ
- Ext := ExtractFileExt(TexName);
- if (uppercase(Ext) = '.JPG') then
- Ext := 'JPG'
- else
- Ext := 'BMP';
-
- Tex := Texture.LoadTexture(false, PChar(TexName), UTEXTURE.TTextureType(Typ), 0);
-
- Result.TexNum := Tex.TexNum;
- Result.W := Tex.W;
- Result.H := Tex.H;
-end;
-{
-function Translate (const Name: PChar): PChar; stdcall;
-begin
- Result := PChar(Language.Translate(String(Name)));
-end; }
-
-procedure Print(const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
-begin
- SetFontItalic ((Style and 128) = 128);
- SetFontStyle(Style and 7);
- SetFontSize(Size);
- SetFontPos (X, Y);
- glPrint (PChar(Language.Translate(String(Text))));
-end;
-
-function LoadSound(const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
-var
- Stream: TAudioPlaybackStream;
- i: Integer;
- Filename: String;
-begin
- //Search for Sound in already loaded Sounds
- Filename := UpperCase(SoundPath + Name);
- for i := 0 to High(CustomSounds) do
- begin
- if (UpperCase(CustomSounds[i].Filename) = Filename) then
- begin
- Result := i;
- Exit;
- end;
- end;
-
- Stream := AudioPlayback.OpenSound(SoundPath + String(Name));
- if (Stream = nil) then
- begin
- Result := 0;
- Exit;
- end;
-
- SetLength(CustomSounds, Length(CustomSounds)+1);
- CustomSounds[High(CustomSounds)].Stream := Stream;
- Result := High(CustomSounds);
-end;
-
-procedure PlaySound(const Index: Cardinal); stdcall; //Plays a Custom Sound
-begin
- if (Index <= High(CustomSounds)) then
- AudioPlayback.PlaySound(CustomSounds[Index].Stream);
-end;
-
-end.
-
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
deleted file mode 100644
index be1320f2..00000000
--- a/Game/Code/Screens/UScreenSong.pas
+++ /dev/null
@@ -1,2019 +0,0 @@
-unit UScreenSong;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- UMenu,
- SDL,
- UMusic,
- UFiles,
- UTime,
- UDisplay,
- USongs,
- SysUtils,
- UCommon,
- ULog,
- UThemes,
- UTexture,
- ULanguage,
- USong,
- UIni;
-
-type
- TScreenSong = class(TMenu)
- private
- EqualizerData: TFFTData; // moved here to avoid stack overflows
- EqualizerBands: array of Byte;
- EqualizerTime: Cardinal;
-
- procedure StartMusicPreview();
- procedure StopMusicPreview();
- public
- TextArtist: integer;
- TextTitle: integer;
- TextNumber: integer;
-
- //Video Icon Mod
- VideoIcon: Cardinal;
-
- TextCat: integer;
- StaticCat: integer;
-
- SongCurrent: real;
- SongTarget: real;
-
- HighSpeed: boolean;
- CoverFull: boolean;
- CoverTime: real;
- MusicPreviewTimer: PSDL_TimerID;
-
- CoverX: integer;
- CoverY: integer;
- CoverW: integer;
- is_jump: boolean; // Jump to Song Mod
- is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
-
- //Party Mod
- Mode: TSingMode;
-
- //party Statics (Joker)
- StaticTeam1Joker1: Cardinal;
- StaticTeam1Joker2: Cardinal;
- StaticTeam1Joker3: Cardinal;
- StaticTeam1Joker4: Cardinal;
- StaticTeam1Joker5: Cardinal;
-
- StaticTeam2Joker1: Cardinal;
- StaticTeam2Joker2: Cardinal;
- StaticTeam2Joker3: Cardinal;
- StaticTeam2Joker4: Cardinal;
- StaticTeam2Joker5: Cardinal;
-
- StaticTeam3Joker1: Cardinal;
- StaticTeam3Joker2: Cardinal;
- StaticTeam3Joker3: Cardinal;
- StaticTeam3Joker4: Cardinal;
- StaticTeam3Joker5: Cardinal;
-
- StaticParty: array of Cardinal;
- TextParty: array of Cardinal;
- StaticNonParty: array of Cardinal;
- TextNonParty: array of Cardinal;
-
-
- constructor Create; override;
- procedure SetScroll;
- //procedure SetScroll1;
- //procedure SetScroll2;
- procedure SetScroll3;
- procedure SetScroll4;
- procedure SetScroll5;
- procedure SetScroll6;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure GenerateThumbnails();
- procedure onShow; override;
- procedure onHide; override;
- procedure SelectNext;
- procedure SelectPrev;
- //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
- procedure SkipTo(Target: Cardinal);
- procedure FixSelected; //Show Wrong Song when Tabs on Fix
- procedure FixSelected2; //Show Wrong Song when Tabs on Fix
- procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
- procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
- procedure HideCatTL;// Show Cat in Tob left
- procedure Refresh; //Refresh Song Sorting
- procedure DrawEqualizer;
- procedure ChangeMusic;
- //Party Mode
- procedure SelectRandomSong;
- procedure SetJoker;
- procedure SetStatics;
- //procedures for Menu
- procedure StartSong;
- procedure OpenEditor;
- procedure DoJoker(Team: Byte);
- procedure SelectPlayers;
-
- procedure UnloadDetailedCover;
-
- //Extensions
- procedure DrawExtensions;
- end;
-
-implementation
-
-uses
- UGraphic,
- UMain,
- UCovers,
- math,
- gl,
- USkins,
- UDLLManager,
- UParty,
- UPlaylist,
- UMenuButton,
- UScreenSongMenu;
-
-// ***** Public methods ****** //
-
-//Show Wrong Song when Tabs on Fix
-procedure TScreenSong.FixSelected;
-var I, I2: Integer;
-begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongCurrent := I2;
- SongTarget := I2;
- end;
-end;
-
-procedure TScreenSong.FixSelected2;
-var I, I2: Integer;
-begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongTarget := I2;
- end;
-end;
-//Show Wrong Song when Tabs on Fix End
-
-procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
-begin
- Text[TextCat].Text := Caption;
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := False;
-end;
-
-//Show Cat in Top Left Mod
-procedure TScreenSong.ShowCatTL(Cat: Integer);
-begin
- //Change
- Text[TextCat].Text := CatSongs.Song[Cat].Artist;
- Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
-
- //Show
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := True;
-end;
-
-procedure TScreenSong.HideCatTL;
-begin
- //Hide
- //Text[TextCat].Visible := false;
- Static[StaticCat].Visible := false;
- //New -> Show Text specified in Theme
- Text[TextCat].Visible := True;
- Text[TextCat].Text := Theme.Song.TextCat.Text;
-end;
-//Show Cat in Top Left Mod End
-
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSong.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- I: integer;
- I2: integer;
- SDL_ModState: Word;
- Letter: WideChar;
-begin
- Result := true;
-
- //Song Screen Extensions (Jumpto + Menu)
- if (ScreenSongMenu.Visible) then
- begin
- Result := ScreenSongMenu.ParseInput(PressedKey, CharCode, PressedDown);
- Exit;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- Result := ScreenSongJumpto.ParseInput(PressedKey, CharCode, PressedDown);
- Exit;
- end;
-
- if (PressedDown) then
- begin // Key Down
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- //Jump to Artist/Titel
- if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then
- begin
- if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z')]) ) then
- begin
- Letter := WideCharUpperCase(CharCode)[1];
- I2 := Length(CatSongs.Song);
-
- //Jump To Titel
- if (SDL_ModState = (KMOD_LALT or KMOD_LSHIFT)) then
- begin
- for I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
- (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and
- (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Break and Exit
- Exit;
- end;
- end;
- end
- //Jump to Artist
- else if (SDL_ModState = KMOD_LALT) then
- begin
- for I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
- (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and
- (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
-
- //Break and Exit
- Exit;
- end;
- end;
- end;
- end;
-
- Exit;
- end;
-
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
-
- 'M': //Show SongMenu
- begin
- if (Songs.SongList.Count > 0) then
- begin
- if (Mode = smNormal) then
- begin
- if (not CatSongs.Song[Interaction].Main) then // clicked on Song
- begin
- if CatSongs.CatNumShow = -3 then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end
- else
- begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- end //Party Mode -> Show Party Menu
- else
- begin
- ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
- end;
- Exit;
- end;
-
- 'P': //Show Playlist Menu
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- Exit;
- end;
-
- 'J': //Show Jumpto Menu
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- ScreenSongJumpto.Visible := True;
- end;
- Exit;
- end;
-
- 'E':
- begin
- OpenEditor;
- Exit;
- end;
-
- 'R':
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- if (SDL_ModState = KMOD_LSHIFT) and (Ini.Tabs_at_startup = 1) then //Random Category
- begin
- I2 := 0; //Count Cats
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Inc(I2);
- end;
-
- I2 := Random (I2)+1; //Zufall
-
- //Find Cat:
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Dec(I2);
- if (I2<=0) then
- begin
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- Interaction := I;
-
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
- break;
- end;
- end;
- end
- else if (SDL_ModState = KMOD_LCTRL) and (Ini.Tabs_at_startup = 1) then //random in All Categorys
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
-
- //In I is now the categorie in I2 the song
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Fix: Not Existing Song selected:
- //if (I+1=I2) then Inc(I2);
-
- //Choose Song
- SkipTo(I2-I);
- end
- else //Random in one Category
- begin
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- end;
- Exit;
- end;
- end; // normal keys
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- if (Mode = smNormal) then
- begin
- //On Escape goto Cat-List Hack
- if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow <> -1) then
- begin
- //Find Category
- I := Interaction;
- while not catsongs.Song[I].Main do
- begin
- Dec (I);
- if (I < low(catsongs.Song)) then
- break;
- end;
- if (I<= 1) then
- Interaction := high(catsongs.Song)
- else
- Interaction := I - 1;
-
- //Stop Music
- StopMusicPreview();
-
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- HideCatTL;
-
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
- //SelectPrev;
- //CatSongs.Song[0].Visible := False;
- end
- else
- begin
- //On Escape goto Cat-List Hack End
- //Tabs off and in Search or Playlist -> Go back to Song view
- if (CatSongs.CatNumShow < -1) then
- begin
- //Atm: Set Empty Filter
- CatSongs.SetFilter('', 0);
-
- //Show Cat in Top Left Mod
- HideCatTL;
- Interaction := 0;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- ChangeMusic;
- end
- else
- begin
- StopMusicPreview();
- AudioPlayback.PlaySound(SoundLib.Back);
-
- FadeTo(@ScreenMain);
- end;
-
- end;
- end
- //When in party Mode then Ask before Close
- else if (Mode = smPartyMode) then
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
- end;
- end;
- SDLK_RETURN:
- begin
- if Songs.SongList.Count > 0 then
- begin
- {$IFDEF UseSerialPort}
- // PortWriteB($378, 0);
- {$ENDIF}
- if CatSongs.Song[Interaction].Main then
- begin // clicked on Category Button
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- //I := CatSongs.VisibleIndex(Interaction);
- CatSongs.ClickCategoryButton(Interaction);
- {I2 := CatSongs.VisibleIndex(Interaction);
- SongCurrent := SongCurrent - I + I2;
- SongTarget := SongTarget - I + I2; }
-
- // SetScroll4;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- //Play Music:
- ChangeMusic;
- end
- else
- begin // clicked on song
- if (Mode = smNormal) then //Normal Mode -> Start Song
- begin
- //Do the Action that is specified in Ini
- case Ini.OnSongClick of
- 0: StartSong;
- 1: SelectPlayers;
- 2:begin
- if (CatSongs.CatNumShow = -3) then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end;
- end;
- end
- else if (Mode = smPartyMode) then //PartyMode -> Show Menu
- begin
- if (Ini.PartyPopup = 1) then
- ScreenSongMenu.MenuShow(SM_Party_Main)
- else
- ScreenSong.StartSong;
- end;
- end;
- end;
- end;
-
- SDLK_DOWN:
- begin
- if (Mode = smNormal) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main do
- begin
- Inc (I);
- if (I > high(catsongs.Song)) then
- I := low(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- CatSongs.ClickCategoryButton(Interaction);
- SelectNext;
- FixSelected;
-
- //Play Music:
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
-
- end;
-
- //
- //Cat Change Hack End}
- end;
- end;
- end;
- SDLK_UP:
- begin
- if (Mode = smNormal) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- I2 := 0;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main or (I2 = 0) do
- begin
- if catsongs.Song[I].Main then
- Inc(I2);
- Dec (I);
- if (I < low(catsongs.Song)) then
- I := high(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
-
- //Play Music:
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
- end;
- end;
- //Cat Change Hack End}
- end;
- end;
-
- SDLK_RIGHT:
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- AudioPlayback.PlaySound(SoundLib.Change);
- SelectNext;
- //InteractNext;
- //SongTarget := Interaction;
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Light.LightOne(1, 200); //TODO: maybe Light Support as Plugin?
- end;
- end;
-
- SDLK_LEFT:
- begin
- if (Songs.SongList.Count > 0)and (Mode = smNormal) then
- begin
- AudioPlayback.PlaySound(SoundLib.Change);
- SelectPrev;
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Light.LightOne(0, 200); //TODO: maybe Light Support as Plugin?
- end;
- end;
-
- SDLK_1:
- begin //Joker // to-do : Party
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 1) and (PartySession.Teams.Teaminfo[0].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[0].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
-
- SDLK_2:
- begin //Joker
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 2) and (PartySession.Teams.Teaminfo[1].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[1].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
-
- SDLK_3:
- begin //Joker
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 3) and (PartySession.Teams.Teaminfo[2].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[2].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
- end;
- end;
-end;
-
-constructor TScreenSong.Create;
-var
- i: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Song);
-
- TextArtist := AddText(Theme.Song.TextArtist);
- TextTitle := AddText(Theme.Song.TextTitle);
- TextNumber := AddText(Theme.Song.TextNumber);
-
- //Show Cat in Top Left mod
- TextCat := AddText(Theme.Song.TextCat);
- StaticCat := AddStatic(Theme.Song.StaticCat);
-
- //Show Video Icon Mod
- VideoIcon := AddStatic(Theme.Song.VideoIcon);
-
- //Party Mode
- StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
- StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
- StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
- StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
- StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
-
- StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
- StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
- StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
- StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
- StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
-
- StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
- StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
- StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
- StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
- StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
-
- //Load Party or NonParty specific Statics and Texts
- SetLength(StaticParty, Length(Theme.Song.StaticParty));
- for i := 0 to High(Theme.Song.StaticParty) do
- StaticParty[i] := AddStatic(Theme.Song.StaticParty[i]);
-
- SetLength(TextParty, Length(Theme.Song.TextParty));
- for i := 0 to High(Theme.Song.TextParty) do
- TextParty[i] := AddText(Theme.Song.TextParty[i]);
-
- SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
- for i := 0 to High(Theme.Song.StaticNonParty) do
- StaticNonParty[i] := AddStatic(Theme.Song.StaticNonParty[i]);
-
- SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
- for i := 0 to High(Theme.Song.TextNonParty) do
- TextNonParty[i] := AddText(Theme.Song.TextNonParty[i]);
-
- // Song List
- //Songs.LoadSongList; // moved to the UltraStar unit
- CatSongs.Refresh;
-
- GenerateThumbnails();
-
-
- // Randomize Patch
- Randomize;
- //Equalizer
- SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
- //ClearArray
- For I := low(EqualizerBands) to high(EqualizerBands) do
- EqualizerBands[I] := 3;
-
- if (Length(CatSongs.Song) > 0) then
- Interaction := 0;
-end;
-
-procedure TScreenSong.GenerateThumbnails();
-var
- I: Integer;
- CoverButtonIndex: integer;
- CoverButton: TButton;
- CoverName: string;
- CoverTexture: TTexture;
- Cover: TCover;
- Song: TSong;
-begin
- if (Length(CatSongs.Song) <= 0) then
- Exit;
-
- // set length of button array once instead for every song
- SetButtonLength(Length(CatSongs.Song));
-
- // create all buttons
- for I := 0 to High(CatSongs.Song) do
- begin
- CoverButton := nil;
-
- // create a clickable cover
- CoverButtonIndex := AddButton(300 + I*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
- if (CoverButtonIndex > -1) then
- CoverButton := Button[CoverButtonIndex];
- if (CoverButton = nil) then
- Continue;
-
- Song := CatSongs.Song[I];
-
- // if cover-image is not found then show 'no cover'
- if (not FileExists(Song.Path + Song.Cover)) then
- Song.Cover := '';
-
- if (Song.Cover = '') then
- CoverName := Skin.GetTextureFileName('SongCover')
- else
- CoverName := Song.Path + Song.Cover;
-
- // load cover and cache its texture
- Cover := Covers.FindCover(CoverName);
- if (Cover = nil) then
- Cover := Covers.AddCover(CoverName);
-
- // use the cached texture
- // TODO: this is a workaround until the new song-loading works.
- // The TCover object should be added to the song-object. The thumbnails
- // should be loaded each time the song-screen is shown (it is real fast).
- // This way, we will not waste that much memory and have a link between
- // song and cover.
- if (Cover <> nil) then
- begin
- CoverTexture := Cover.GetPreviewTexture();
- Texture.AddTexture(CoverTexture, TEXTURE_TYPE_PLAIN, true);
- CoverButton.Texture := CoverTexture;
- end;
-
- Cover.Free;
- end;
-end;
-
-procedure TScreenSong.SetScroll;
-var
- VS, B: Integer;
-begin
- VS := CatSongs.VisibleSongs;
- if VS > 0 then
- begin
- // Set Positions
- case Theme.Song.Cover.Style of
- 3: SetScroll3;
- 5:begin
- if VS > 5 then
- SetScroll5
- else
- SetScroll4;
- end;
- 6: SetScroll6;
- else SetScroll4;
- end;
-
- // Set visibility of video icon
- Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
-
- // Set texts
- Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
- Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
- if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
- begin
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
- Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
- end
- else if (CatSongs.CatNumShow = -2) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (CatSongs.CatNumShow = -3) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (Ini.Tabs_at_startup = 1) then
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
- else
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
- end
- else
- begin
- Text[TextNumber].Text := '0/0';
- Text[TextArtist].Text := '';
- Text[TextTitle].Text := '';
- for B := 0 to High(Button) do
- Button[B].Visible := False;
-
- end;
-end;
-
-(*
-procedure TScreenSong.SetScroll1;
-var
- B: integer; // button
- //BMin: integer; // button min // Auto Removed, Unused Variable
- //BMax: integer; // button max // Auto Removed, Unused Variable
- Src: integer;
- //Dst: integer;
- Count: integer; // Dst is not used. Count is used.
- Ready: boolean;
-
- VisCount: integer; // count of visible (or selectable) buttons
- VisInt: integer; // visible position of interacted button
- Typ: integer; // 0 when all songs fits the screen
- Placed: integer; // number of placed visible buttons
-begin
- //Src := 0;
- //Dst := -1;
- Count := 1;
- Typ := 0;
- Ready := false;
- Placed := 0;
-
- VisCount := 0;
- for B := 0 to High(Button) do
- if CatSongs.Song[B].Visible then Inc(VisCount);
-
- VisInt := 0;
- for B := 0 to Interaction-1 do
- if CatSongs.Song[B].Visible then Inc(VisInt);
-
-
- if VisCount <= 6 then begin
- Typ := 0;
- end else begin
- if VisInt <= 3 then begin
- Typ := 1;
- Count := 7;
- Ready := true;
- end;
-
- if (VisCount - VisInt) <= 3 then begin
- Typ := 2;
- Count := 7;
- Ready := true;
- end;
-
- if not Ready then begin
- Typ := 3;
- Src := Interaction;
- end;
- end;
-
-
-
- // hide all buttons
- for B := 0 to High(Button) do begin
- Button[B].Visible := false;
- Button[B].Selectable := CatSongs.Song[B].Visible;
- end;
-
- {
- for B := Src to Dst do begin
- //Button[B].Visible := true;
- Button[B].Visible := CatSongs.Song[B].Visible;
- Button[B].Selectable := Button[B].Visible;
- Button[B].Y := 140 + (B-Src) * 60;
- end;
- }
-
-
- if Typ = 0 then begin
- for B := 0 to High(Button) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- end;
- end;
- end;
-
- if Typ = 1 then begin
- B := 0;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
- end;
-
- if Typ = 2 then begin
- B := High(Button);
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (6-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
- end;
-
- if Typ = 3 then begin
- B := Src;
- Count := 4;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (3+Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
-
- B := Src-1;
- Placed := 0;
- Count := 3;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (2-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
-
- end;
-
- if Length(Button) > 0 then
- Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
-end;
-
-procedure TScreenSong.SetScroll2;
-var
- B: integer;
- //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- //Wsp2: real;
-begin
- // liniowe
- for B := 0 to High(Button) do
- Button[B].X := 300 + (B - Interaction) * 260;
-
- if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;
-
- // kolowe
- {
- for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
- //Button[B].Y := 140 + 50 * ;
- end;
- }
-end;
-*)
-
-procedure TScreenSong.SetScroll3; // with slide
-var
- B: integer;
- //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- //Wsp2: real;
-begin
- SongTarget := Interaction;
-
- // liniowe
- for B := 0 to High(Button) do
- begin
- Button[B].X := 300 + (B - SongCurrent) * 260;
- if (Button[B].X < -Button[B].W) or (Button[B].X > 800) then
- Button[B].Visible := False
- else
- Button[B].Visible := True;
- end;
-
- {
- if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;
- }
-
- // kolowe
- {
- for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
- //Button[B].Y := 140 + 50 * ;
- end;
- }
-end;
-
-(**
- * Rotation
- *)
-procedure TScreenSong.SetScroll4;
-var
- B: integer;
- Angle: real;
- Z, Z2: real;
- VS: integer;
-begin
- VS := CatSongs.VisibleSongs();
-
- for B := 0 to High(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible;
- if Button[B].Visible then
- begin
- // angle between the cover and selected song-cover in radians
- Angle := 2*Pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS;
-
- // calc z-position from angle
- Z := (1 + cos(Angle)) / 2; // scaled to range [0..1]
- Z2 := (1 + 2*Z) / 3; // scaled to range [1/3..1]
-
- // adjust cover's width and height according its z-position
- // Note: Theme.Song.Cover.W is not used as width and height are equal
- // and Theme.Song.Cover.W is used as circle radius in Scroll5.
- Button[B].W := Theme.Song.Cover.H * Z2;
- Button[B].H := Button[B].W;
-
- // set cover position
- Button[B].X := Theme.Song.Cover.X +
- (0.185 * Theme.Song.Cover.H * VS * sin(Angle)) * Z2 -
- ((Button[B].H - Theme.Song.Cover.H)/2);
- Button[B].Y := Theme.Song.Cover.Y +
- (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7;
- Button[B].Z := Z / 2 + 0.3;
- end;
- end;
-end;
-
-(**
- * rotate
- *)
-procedure TScreenSong.SetScroll5;
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- Padding: real;
- X: Real;
- {
- Theme.Song.CoverW: circle radius
- Theme.Song.CoverX: x-pos. of the left edge of the selected cover
- Theme.Song.CoverY: y-pos. of the upper edge of the selected cover
- Theme.Song.CoverH: cover height
- }
-begin
- VS := CatSongs.VisibleSongs();
-
- // Update positions of all buttons
- for B := 0 to High(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; // adjust visibility
- if Button[B].Visible then // Only change pos for visible buttons
- begin
- // Pos is the distance to the centered cover in the range [-VS/2..+VS/2]
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- // Avoid overlapping of the front covers.
- // Use an alternate position for the five front covers.
- if (Abs(Pos) < 2.5) then
- begin
- Angle := Pi * (Pos / 5); // Range: (-1/4*Pi .. +1/4*Pi)
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));
- Button[B].W := Button[B].H;
-
- //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Padding := (Button[B].H - Theme.Song.Cover.H)/2;
- X := Sin(Angle*1.3) * 0.9;
-
- Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Padding;
- Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
- end
- else
- begin
- // Transform Pos to range [-1..-1/2, +1/2..+1]
- if Pos < 0 then
- Pos := Pos/VS - 0.5
- else
- Pos := Pos/VS + 0.5;
-
- // angle in radians [-2Pi..-Pi, +Pi..+2Pi]
- Angle := 2*Pi * Pos;
-
- Button[B].H := 0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));
- Button[B].W := Button[B].H;
-
- Padding := (Button[B].H - Theme.Song.Cover.H)/2;
-
- Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
- Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- end;
- end;
- end;
-end;
-
-procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- diff: real;
- X: Real;
- Wsp: real;
- Z, Z2: real;
-begin
- VS := CatSongs.VisibleSongs;
- if VS <= 5 then
- begin
- // kolowe
- for B := 0 to High(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
-
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2;
- Z2 := (1 + 2*Z) / 3;
-
-
- Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- Button[B].Z := Z / 2 + 0.3;
-
- Button[B].W := Theme.Song.Cover.H * Z2;
-
- //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
- Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
- Button[B].H := Button[B].W;
- end;
- end;
- end
- else
- begin
- //Change Pos of all Buttons
- for B := low(Button) to high(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
- if Button[B].Visible then //Only Change Pos for Visible Buttons
- begin
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- if (Abs(Pos) < 2.5) then {fixed Positions}
- begin
- Angle := Pi * (Pos / 5);
- //Button[B].Visible := False;
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
-
- Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
-
- Button[B].W := Button[B].H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
-
- X := Sin(Angle*1.3)*0.9;
-
- Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
- end
- else
- begin {Behind the Front Covers}
-
- // limit-bg-covers hack
- if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
- if VS > 25 then VS:=25;
- // end of limit-bg-covers hack
-
- if Pos < 0 then
- Pos := (Pos - VS/2)/VS
- else
- Pos := (Pos + VS/2)/VS;
-
- Angle := Pi * Pos*2;
-
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
-
- Button[B].W := Button[B].H;
-
- Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
-
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
- end;
- end;
- end;
- end;
-end;
-
-
-procedure TScreenSong.onShow;
-begin
- inherited;
-{**
- * Pause background music, so we can play it again on scorescreen
- *}
- SoundLib.PauseBgMusic;
-
- AudioPlayback.Stop;
-
- if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
- if Ini.Players = 4 then PlayersPlay := 6;
-
- //Cat Mod etc
- if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
- begin
- CatSongs.ShowCategoryList;
- FixSelected;
- //Show Cat in Top Left Mod
- HideCatTL;
- end;
-
- if Length(CatSongs.Song) > 0 then
- begin
- //Load Music only when Song Preview is activated
- if ( Ini.PreviewVolume <> 0 ) then
- StartMusicPreview();
-
- SetScroll;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- end;
-
- //Playlist Mode
- if (Mode = smNormal) then
- begin
- //If Playlist Shown -> Select Next automatically
- if (CatSongs.CatNumShow = -3) then
- begin
- SelectNext;
- ChangeMusic;
- end;
- end
- //Party Mode
- else if (Mode = smPartyMode) then
- begin
- SelectRandomSong;
- //Show Menu directly in PartyMode
- //But only if selected in Options
- if (Ini.PartyPopup = 1) then
- begin
- ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
- end;
-
- SetJoker;
- SetStatics;
-end;
-
-procedure TScreenSong.onHide;
-begin
- // turn music volume to 100%
- AudioPlayback.SetVolume(1.0);
-
- // if preview is deactivated: load musicfile now
- If (IPreviewVolumeVals[Ini.PreviewVolume] = 0) then
- AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
-
- // if hide then stop music (for party mode popup on exit)
- if (Display.NextScreen <> @ScreenSing) and
- (Display.NextScreen <> @ScreenSingModi) then
- begin
- StopMusicPreview();
- end;
-end;
-
-procedure TScreenSong.DrawExtensions;
-begin
- //Draw Song Menu
- if (ScreenSongMenu.Visible) then
- begin
- ScreenSongMenu.Draw;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- ScreenSongJumpto.Draw;
- end
-end;
-
-function TScreenSong.Draw: boolean;
-var
- dx: real;
- dt: real;
- I: Integer;
-begin
- dx := SongTarget-SongCurrent;
- dt := TimeSkip * 7;
-
- if dt > 1 then
- dt := 1;
-
- SongCurrent := SongCurrent + dx*dt;
-
- {
- if SongCurrent > Catsongs.VisibleSongs then begin
- SongCurrent := SongCurrent - Catsongs.VisibleSongs;
- SongTarget := SongTarget - Catsongs.VisibleSongs;
- end;
- }
-
- //Log.BenchmarkStart(5);
-
- SetScroll;
-
- //Log.BenchmarkEnd(5);
- //Log.LogBenchmark('SetScroll4', 5);
-
- //Fading Functions, Only if Covertime is under 5 Seconds
- if (CoverTime < 5) then
- begin
- // cover fade
- if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then
- begin
- // load new texture
- Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
- Button[Interaction].Texture.Alpha := 1;
- Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
- Button[Interaction].Texture2.Alpha := 1;
- end;
-
- //Update Fading Time
- CoverTime := CoverTime + TimeSkip;
-
- //Update Fading Texture
- Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
- if Button[Interaction].Texture2.Alpha > 1 then
- Button[Interaction].Texture2.Alpha := 1;
-
- end;
-
- //inherited Draw;
- //heres a little Hack, that causes the Statics
- //are Drawn after the Buttons because of some Blending Problems.
- //This should cause no Problems because all Buttons on this screen
- //Has Z Position.
- //Draw BG
- DrawBG;
-
- //Instead of Draw FG Procedure:
- //We draw Buttons for our own
- for I := 0 to Length(Button) - 1 do
- Button[I].Draw;
-
- // Statics
- for I := 0 to Length(Static) - 1 do
- Static[I].Draw;
-
- // and texts
- for I := 0 to Length(Text) - 1 do
- Text[I].Draw;
-
-
- //Draw Equalizer
- if Theme.Song.Equalizer.Visible then
- DrawEqualizer;
-
- DrawExtensions;
-
- Result := true;
-end;
-
-procedure TScreenSong.SelectNext;
-var
- Skip: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- // this 1 could be changed by CatSongs.FindNextVisible
- while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do
- Inc(Skip);
-
- SongTarget := SongTarget + 1;//Skip;
-
- Interaction := (Interaction + Skip) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget > VS-1 then begin
- SongTarget := SongTarget - VS;
- SongCurrent := SongCurrent - VS;
- end;
-
- end;
-
- // Interaction -> Button, ktorego okladke przeczytamy
- // show uncached texture
- //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
-end;
-
-procedure TScreenSong.SelectPrev;
-var
- Skip: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
- SongTarget := SongTarget - 1;//Skip;
-
- Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget < 0 then begin
- SongTarget := SongTarget + CatSongs.VisibleSongs;
- SongCurrent := SongCurrent + CatSongs.VisibleSongs;
- end;
-
- // show uncached texture
- //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
- end;
-end;
-
-(*
-procedure TScreenSong.UpdateLCD; //TODO: maybe LCD Support as Plugin?
-begin
- LCD.HideCursor;
- LCD.Clear;
- LCD.WriteText(1, Text[TextArtist].Text);
- LCD.WriteText(2, Text[TextTitle].Text);
-
-end;
-*)
-
-procedure TScreenSong.StartMusicPreview();
-var
- Song: TSong;
-begin
- AudioPlayback.Close();
-
- Song := CatSongs.Song[Interaction];
- if not assigned(Song) then
- Exit;
-
- if AudioPlayback.Open(Song.Path + Song.Mp3) then
- begin
- AudioPlayback.Position := AudioPlayback.Length / 4;
- // set preview volume
- if (Ini.PreviewFading = 0) then
- begin
- // music fade disabled: start with full volume
- AudioPlayback.SetVolume(IPreviewVolumeVals[Ini.PreviewVolume]);
- AudioPlayback.Play()
- end
- else
- begin
- // music fade enabled: start muted and fade-in
- AudioPlayback.SetVolume(0);
- AudioPlayback.FadeIn(Ini.PreviewFading, IPreviewVolumeVals[Ini.PreviewVolume]);
- end;
- end;
-end;
-
-procedure TScreenSong.StopMusicPreview();
-begin
- // Cancel pending preview requests
- SDL_RemoveTimer(MusicPreviewTimer);
-
- // Stop preview of previous song
- AudioPlayback.Stop;
-end;
-
-function MusicPreviewTimerCallback(interval: UInt32; param: Pointer): UInt32; cdecl;
-var
- ScreenSong: TScreenSong;
-begin
- ScreenSong := TScreenSong(param);
- if (ScreenSong <> nil) then
- ScreenSong.StartMusicPreview();
- Result := 0;
-end;
-
-// Changes previewed song
-procedure TScreenSong.ChangeMusic;
-begin
- StopMusicPreview();
-
- // Preview song if activated and current selection is not a category cover
- if (CatSongs.VisibleSongs > 0) and
- (not CatSongs.Song[Interaction].Main) and
- (Ini.PreviewVolume <> 0) then
- begin
- // Delay song fading to prevent the song from being played while scrolling
- MusicPreviewTimer := SDL_AddTimer(200, MusicPreviewTimerCallback, Self);
- end;
-end;
-
-procedure TScreenSong.SkipTo(Target: Cardinal);
-var
- i: integer;
-begin
- UnLoadDetailedCover;
-
- Interaction := High(CatSongs.Song);
- SongTarget := 0;
-
- for i := 1 to Target+1 do
- SelectNext;
-
- FixSelected2;
-end;
-
-procedure TScreenSong.DrawEqualizer;
-var
- I, J: Integer;
- ChansPerBand: byte; // channels per band
- MaxChannel: Integer;
- CurBand: Integer; // current band
- CurTime: Cardinal;
- PosX, PosY: Integer;
- Pos: Real;
-begin
- // Nothing to do if no music is played or an equalizer bar consists of no block
- if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then
- Exit;
-
- CurTime := SDL_GetTicks();
-
- // Evaluate FFT-data every 44 ms
- if (CurTime >= EqualizerTime) then
- begin
- EqualizerTime := CurTime + 44;
- AudioPlayback.GetFFTData(EqualizerData);
-
- Pos := 0;
- // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz
- ChansPerBand := ceil(92 / Theme.Song.Equalizer.Bands); // How much channels are used for one Band
- MaxChannel := ChansPerBand * Theme.Song.Equalizer.Bands - 1;
-
- // Change Lengths
- for i := 0 to MaxChannel do
- begin
- // Gain higher freq. data so that the bars are visible
- if i > 35 then
- EqualizerData[i] := EqualizerData[i] * 8
- else if i > 11 then
- EqualizerData[i] := EqualizerData[i] * 4.5
- else
- EqualizerData[i] := EqualizerData[i] * 1.1;
-
- // clamp data
- if (EqualizerData[i] > 1) then
- EqualizerData[i] := 1;
-
- // Get max. pos
- if (EqualizerData[i] * Theme.Song.Equalizer.Length > Pos) then
- Pos := EqualizerData[i] * Theme.Song.Equalizer.Length;
-
- // Check if this is the last channel in the band
- if ((i+1) mod ChansPerBand = 0) then
- begin
- CurBand := i div ChansPerBand;
-
- // Smooth delay if new equalizer is lower than the old one
- if ((EqualizerBands[CurBand] > Pos) and (EqualizerBands[CurBand] > 1)) then
- EqualizerBands[CurBand] := EqualizerBands[CurBand] - 1
- else
- EqualizerBands[CurBand] := Round(Pos);
-
- Pos := 0;
- end;
- end;
-
- end;
-
- // Draw equalizer bands
-
- // Setup OpenGL
- glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha);
- glDisable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- // Set position of the first equalizer bar
- PosY := Theme.Song.Equalizer.Y;
- PosX := Theme.Song.Equalizer.X;
-
- // Draw bars for each band
- for I := 0 to High(EqualizerBands) do
- begin
- // Reset to lower or left position depending on the drawing-direction
- if Theme.Song.Equalizer.Direction then // Vertical bars
- // FIXME: Is Theme.Song.Equalizer.Y the upper or lower coordinate?
- PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
- else // Horizontal bars
- PosX := Theme.Song.Equalizer.X;
-
- // Draw the bar as a stack of blocks
- for J := 1 to EqualizerBands[I] do
- begin
- // Draw block
- glBegin(GL_QUADS);
- glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
- glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
- glEnd;
-
- // Calc position of the bar's next block
- if Theme.Song.Equalizer.Direction then // Vertical bars
- PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
- else // Horizontal bars
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
- end;
-
- // Calc position of the next bar
- if Theme.Song.Equalizer.Direction then // Vertical bars
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
- else // Horizontal bars
- PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
- end;
-end;
-
-procedure TScreenSong.SelectRandomSong;
-var
- I, I2: Integer;
-begin
- case PlaylistMan.Mode of
- smNormal: //All Songs Just Select Random Song
- begin
- //When Tabs are activated then use Tab Method
- if (Ini.Tabs_at_startup = 1) then
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
- //In I ist jetzt die Kategorie in I2 der Song
- //I is the CatNum, I2 is the No of the Song within this Cat
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Choose Song
- SkipTo(I2-I);
- end
- //When Tabs are deactivated use easy Method
- else
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- smPartyMode: //One Category Select Category and Select Random Song
- begin
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
- ShowCatTL(PlaylistMan.CurPlayList);
-
- SelectNext;
- FixSelected2;
-
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- smPlaylistRandom: //Playlist: Select Playlist and Select Random Song
- begin
- PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
-
- SkipTo(Random(CatSongs.VisibleSongs));
- FixSelected2;
- end;
- end;
-
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
- SetScroll;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
-end;
-
-procedure TScreenSong.SetJoker;
-begin
- // If Party Mode
- // to-do : Party
- if Mode = smPartyMode then //Show Joker that are available
- begin
- (*
- if (PartySession.Teams.NumTeams >= 1) then
- begin
- Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
- Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
- Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
- Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
- Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
- Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
- Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
- Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
- Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
- Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
- Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
- Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
- Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
- *)
- end
- else
- begin //Hide all
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
-
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
-
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
-end;
-
-procedure TScreenSong.SetStatics;
-var
- I: Integer;
- Visible: Boolean;
-begin
- //Set Visibility of Party Statics and Text
- Visible := (Mode = smPartyMode);
-
- for I := 0 to high(StaticParty) do
- Static[StaticParty[I]].Visible := Visible;
-
- for I := 0 to high(TextParty) do
- Text[TextParty[I]].Visible := Visible;
-
- //Set Visibility of Non Party Statics and Text
- Visible := not Visible;
-
- for I := 0 to high(StaticNonParty) do
- Static[StaticNonParty[I]].Visible := Visible;
-
- for I := 0 to high(TextNonParty) do
- Text[TextNonParty[I]].Visible := Visible;
-end;
-
-//Procedures for Menu
-
-procedure TScreenSong.StartSong;
-begin
- CatSongs.Selected := Interaction;
- StopMusicPreview();
-
- //Party Mode
- if (Mode = smPartyMode) then
- begin
- FadeTo(@ScreenSingModi);
- end
- else
- begin
- FadeTo(@ScreenSing);
- end;
-end;
-
-procedure TScreenSong.SelectPlayers;
-begin
- CatSongs.Selected := Interaction;
- StopMusicPreview();
-
- ScreenName.Goto_SingScreen := True;
- FadeTo(@ScreenName);
-end;
-
-procedure TScreenSong.OpenEditor;
-begin
- if (Songs.SongList.Count > 0) and
- (not CatSongs.Song[Interaction].Main) and
- (Mode = smNormal) then
- begin
- StopMusicPreview();
- AudioPlayback.PlaySound(SoundLib.Start);
- CurrentSong := CatSongs.Song[Interaction];
- FadeTo(@ScreenEditSub);
- end;
-end;
-
-//Team No of Team (0-5)
-procedure TScreenSong.DoJoker (Team: Byte);
-begin
- {
- if (Mode = smPartyMode) and
- (PartySession.Teams.NumTeams >= Team + 1) and
- (PartySession.Teams.Teaminfo[Team].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[Team].Joker);
- SelectRandomSong;
- SetJoker;
- end;
- }
-end;
-
-//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
-procedure TScreenSong.UnloadDetailedCover;
-begin
- CoverTime := 0;
-
- // show cached texture
- Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true);
- Button[Interaction].Texture2.Alpha := 0;
-
- if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
- Texture.UnloadTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
-end;
-
-procedure TScreenSong.Refresh;
-begin
- {
- CatSongs.Refresh;
- CatSongs.ShowCategoryList;
- Interaction := 0;
- SelectNext;
- FixSelected;
- }
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenSongJumpto.pas b/Game/Code/Screens/UScreenSongJumpto.pas
deleted file mode 100644
index 89d198cc..00000000
--- a/Game/Code/Screens/UScreenSongJumpto.pas
+++ /dev/null
@@ -1,212 +0,0 @@
-unit UScreenSongJumpto;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenSongJumpto = class(TMenu)
- private
- //For ChangeMusic
- LastPlayed: Integer;
- VisibleBool: Boolean;
- public
- VisSongs: Integer;
-
- constructor Create; override;
-
- //Visible //Whether the Menu should be Drawn
- //Whether the Menu should be Drawn
- procedure SetVisible(Value: Boolean);
- property Visible: Boolean read VisibleBool write SetVisible;
-
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- function Draw: boolean; override;
-
- procedure SetTextFound(const Count: Cardinal);
- end;
-
-var
- IType: Array [0..2] of String;
- SelectType: Integer;
-
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, USongs, UScreenSong, ULog;
-
-function TScreenSongJumpto.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case CharCode of
- '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"',
- '[', '{', ';', ':':
- begin
- if Interaction = 0 then
- begin
- Button[0].Text[0].Text := Button[0].Text[0].Text + CharCode;
- SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
- end;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_BACKSPACE:
- begin
- if (Interaction = 0) AND (Length(Button[0].Text[0].Text) > 0) then
- begin
- Button[0].Text[0].DeleteLastL;
- SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
- end;
- end;
-
- SDLK_RETURN,
- SDLK_ESCAPE:
- begin
- Visible := False;
- AudioPlayback.PlaySound(SoundLib.Back);
- if (VisSongs = 0) AND (Length(Button[0].Text[0].Text) > 0) then
- begin
- ScreenSong.UnLoadDetailedCover;
- Button[0].Text[0].Text := '';
- CatSongs.SetFilter('', 0);
- SetTextFound(0);
- end;
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN:
- begin
- {SelectNext;
- Button[0].Text[0].Selected := (Interaction = 0);}
- end;
-
- SDLK_UP:
- begin
- {SelectPrev;
- Button[0].Text[0].Selected := (Interaction = 0); }
- end;
-
- SDLK_RIGHT:
- begin
- Interaction := 1;
- InteractInc;
- if (Length(Button[0].Text[0].Text) > 0) then
- SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
- Interaction := 0;
- end;
- SDLK_LEFT:
- begin
- Interaction := 1;
- InteractDec;
- if (Length(Button[0].Text[0].Text) > 0) then
- SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
- Interaction := 0;
- end;
- end;
- end;
-end;
-
-constructor TScreenSongJumpto.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- AddText(Theme.SongJumpto.TextFound);
-
- LoadFromTheme(Theme.SongJumpto);
-
- AddButton(Theme.SongJumpto.ButtonSearchText);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, '');
-
- SelectType := 0;
- AddSelectSlide(Theme.SongJumpto.SelectSlideType, SelectType, Theme.SongJumpto.IType);
-
-
- Interaction := 0;
- LastPlayed := 0;
-end;
-
-procedure TScreenSongJumpto.SetVisible(Value: Boolean);
-begin
-//If change from unvisible to Visible then OnShow
- if (VisibleBool = False) AND (Value = True) then
- OnShow;
-
- VisibleBool := Value;
-end;
-
-procedure TScreenSongJumpto.onShow;
-begin
- inherited;
-
- //Reset Screen if no Old Search is Displayed
- if (CatSongs.CatNumShow <> -2) then
- begin
- SelectsS[0].SetSelectOpt(0);
-
- Button[0].Text[0].Text := '';
- Text[0].Text := Theme.SongJumpto.NoSongsFound;
- end;
-
- //Select Input
- Interaction := 0;
- Button[0].Text[0].Selected := True;
-
- LastPlayed := ScreenSong.Interaction;
-end;
-
-function TScreenSongJumpto.Draw: boolean;
-begin
- Result := inherited Draw;
-end;
-
-procedure TScreenSongJumpto.SetTextFound(const Count: Cardinal);
-begin
- if (Count = 0) then
- begin
- Text[0].Text := Theme.SongJumpto.NoSongsFound;
- if (Length(Button[0].Text[0].Text) = 0) then
- ScreenSong.HideCatTL
- else
- ScreenSong.ShowCatTLCustom(Format(Theme.SongJumpto.CatText, [Button[0].Text[0].Text]));
- end
- else
- begin
- Text[0].Text := Format(Theme.SongJumpto.SongsFound, [Count]);
-
- //Set CatTopLeftText
- ScreenSong.ShowCatTLCustom(Format(Theme.SongJumpto.CatText, [Button[0].Text[0].Text]));
- end;
-
-
- //Set visSongs
- VisSongs := Count;
-
- //Fix SongSelection
- ScreenSong.Interaction := high(CatSongs.Song);
- ScreenSong.SelectNext;
- ScreenSong.FixSelected;
-
- //Play Correct Music
- if (ScreenSong.Interaction <> LastPlayed) then
- begin
- LastPlayed := ScreenSong.Interaction;
-
- ScreenSong.ChangeMusic;
- end;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas
deleted file mode 100644
index 74e2c3fc..00000000
--- a/Game/Code/Screens/UScreenSongMenu.pas
+++ /dev/null
@@ -1,641 +0,0 @@
-unit UScreenSongMenu;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- UDisplay,
- UMusic,
- UFiles,
- SysUtils,
- UThemes;
-
-type
- TScreenSongMenu = class(TMenu)
- private
- CurMenu: Byte; //Num of the cur. Shown Menu
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- function Draw: boolean; override;
- procedure MenuShow(sMenu: Byte);
- procedure HandleReturn;
- end;
-
-const
- SM_Main = 1;
-
- SM_PlayList = 64 or 1;
- SM_Playlist_Add = 64 or 2;
- SM_Playlist_New = 64 or 3;
-
- SM_Playlist_DelItem = 64 or 5;
-
- SM_Playlist_Load = 64 or 8 or 1;
- SM_Playlist_Del = 64 or 8 or 5;
-
-
- SM_Party_Main = 128 or 1;
- SM_Party_Joker = 128 or 2;
-
-var
- ISelections: Array of String;
- SelectValue: Integer;
-
-
-implementation
-
-uses UGraphic,
- UMain,
- UIni,
- UTexture,
- ULanguage,
- UParty,
- UPlaylist,
- USongs;
-
-function TScreenSongMenu.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- if (PressedDown) then
- begin // Key Down
- if (CurMenu = SM_Playlist_New) AND (Interaction=0) then
- begin
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- '0'..'9', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"':
- begin
- Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
- exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_BACKSPACE:
- begin
- Button[Interaction].Text[0].DeleteLastL;
- exit;
- end;
- end;
- end;
-
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- Visible := False;
- end;
-
- SDLK_RETURN:
- begin
- HandleReturn;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT:
- begin
- if (Interaction=3) then
- InteractInc;
- end;
- SDLK_LEFT:
- begin
- if (Interaction=3) then
- InteractDec;
- end;
-
- SDLK_1:
- begin //Jocker
- //Use Joker
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(0)
- end;
- end;
- end;
- SDLK_2:
- begin //Jocker
- //Use Joker
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(1)
- end;
- end;
- end;
- SDLK_3:
- begin //Jocker
- //Use Joker
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(2)
- end;
- end;
- end;
- end; // case
- end; // if
-end;
-
-constructor TScreenSongMenu.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- //Create Dummy SelectSlide Entrys
- SetLength(ISelections, 1);
- ISelections[0] := 'Dummy';
-
-
- AddText(Theme.SongMenu.TextMenu);
-
- LoadFromTheme(Theme.SongMenu);
-
- AddButton(Theme.SongMenu.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddButton(Theme.SongMenu.Button2);
- if (Length(Button[1].Text) = 0) then
- AddButtonText(14, 20, 'Button 2');
-
- AddButton(Theme.SongMenu.Button3);
- if (Length(Button[2].Text) = 0) then
- AddButtonText(14, 20, 'Button 3');
-
- AddSelectSlide(Theme.SongMenu.SelectSlide3, SelectValue, ISelections);
-
- AddButton(Theme.SongMenu.Button4);
- if (Length(Button[3].Text) = 0) then
- AddButtonText(14, 20, 'Button 4');
-
-
- Interaction := 0;
-end;
-
-function TScreenSongMenu.Draw: boolean;
-begin
- Result := inherited Draw;
-end;
-
-procedure TScreenSongMenu.onShow;
-begin
- inherited;
-
-end;
-
-procedure TScreenSongMenu.MenuShow(sMenu: Byte);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
- Case sMenu of
- SM_Main:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_MAIN');
-
- Button[0].Visible := True;
- Button[1].Visible := True;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
- end;
-
- SM_PlayList:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST');
-
- Button[0].Visible := True;
- Button[1].Visible := True;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DEL');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
- end;
-
- SM_Playlist_Add:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_ADD');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_NEW');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_EXISTING');
-
- SetLength(ISelections, Length(PlaylistMan.Playlists));
- PlaylistMan.GetNames(ISelections);
-
- if (Length(ISelections)>=1) then
- begin
- UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
- end
- else
- begin
- Button[3].Visible := False;
- SelectsS[0].Visible := False;
- Button[2].Visible := True;
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
- end;
- end;
-
- SM_Playlist_New:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_NEW');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_UNNAMED');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_CREATE');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
- SM_Playlist_DelItem:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DELITEM');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
- SM_Playlist_Load:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_LOAD');
-
- //Show Delete Curent Playlist Button when Playlist is opened
- Button[0].Visible := (CatSongs.CatNumShow = -3);
-
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DELCURRENT');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_LOAD');
-
- SetLength(ISelections, Length(PlaylistMan.Playlists));
- PlaylistMan.GetNames(ISelections);
-
- if (Length(ISelections)>=1) then
- begin
- UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
- Interaction := 3;
- end
- else
- begin
- Button[3].Visible := False;
- SelectsS[0].Visible := False;
- Button[2].Visible := True;
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
- Interaction := 2;
- end;
- end;
-
- SM_Playlist_Del:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DEL');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
-
- SM_Party_Main:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_MAIN');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- //Button[1].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
- //Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYMODI');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
- end;
-
- SM_Party_Joker:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_JOKER');
- // to-do : Party
- {Button[0].Visible := (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0);
- Button[1].Visible := (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0);
- Button[2].Visible := (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0);}
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- {Button[0].Text[0].Text := String(PartySession.Teams.Teaminfo[0].Name);
- Button[1].Text[0].Text := String(PartySession.Teams.Teaminfo[1].Name);
- Button[2].Text[0].Text := String(PartySession.Teams.Teaminfo[2].Name);}
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
-
- //Set right Interaction
- if (not Button[0].Visible) then
- begin
- if (not Button[1].Visible) then
- begin
- if (not Button[2].Visible) then
- begin
- Interaction := 4;
- end
- else Interaction := 2;
- end
- else Interaction := 1;
- end;
-
- end;
- end;
-end;
-
-procedure TScreenSongMenu.HandleReturn;
-begin
- Case CurMenu of
- SM_Main:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 1: //Button 2
- begin
- //Select New Players then Sing:
- ScreenSong.SelectPlayers;
- Visible := False;
- end;
-
- 2: //Button 3
- begin
- //Show add to Playlist Menu
- MenuShow(SM_Playlist_Add);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- ScreenSong.OpenEditor;
- Visible := False;
- end;
- end;
- end;
-
- SM_PlayList:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 1: //Button 2
- begin
- //Select New Players then Sing:
- ScreenSong.SelectPlayers;
- Visible := False;
- end;
-
- 2: //Button 3
- begin
- //Show add to Playlist Menu
- MenuShow(SM_Playlist_DelItem);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- ScreenSong.OpenEditor;
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_Add:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- MenuShow(SM_Playlist_New);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- PlaylistMan.AddItem(ScreenSong.Interaction, SelectValue);
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_New:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- //Nothing, Button for Entering Name
- end;
-
- 2: //Button 3
- begin
- //Create Playlist and Add Song
- PlaylistMan.AddItem(
- ScreenSong.Interaction,
- PlaylistMan.AddPlaylist(Button[0].Text[0].Text));
- Visible := False;
- end;
-
- 3: //SelectSlide 3
- begin
- //Cancel -> Go back to Add screen
- MenuShow(SM_Playlist_Add);
- end;
-
- 4: //Button 4
- begin
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_DelItem:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Delete
- PlayListMan.DelItem(PlayListMan.GetIndexbySongID(ScreenSong.Interaction));
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- MenuShow(SM_Playlist);
- end;
- end;
- end;
-
- SM_Playlist_Load:
- begin
- Case Interaction of
- 0: //Button 1 (Delete Playlist)
- begin
- MenuShow(SM_Playlist_Del);
- end;
- 4: //Button 4
- begin
- //Load Playlist
- PlaylistMan.SetPlayList(SelectValue);
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_Del:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Delete
- PlayListMan.DelPlaylist(PlaylistMan.CurPlayList);
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- MenuShow(SM_Playlist_Load);
- end;
- end;
- end;
-
- SM_Party_Main:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- //Start Singing
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- //Joker
- MenuShow(SM_Party_Joker);
- end;
- end;
- end;
-
- SM_Party_Joker:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Joker Team 1
- ScreenSong.DoJoker(0);
- end;
-
- 1: //Button 2
- begin
- //Joker Team 2
- ScreenSong.DoJoker(1);
- end;
-
- 2: //Button 3
- begin
- //Joker Team 3
- ScreenSong.DoJoker(2);
- end;
-
- 4: //Button 4
- begin
- //Cancel... (Fo back to old Menu)
- MenuShow(SM_Party_Main);
- end;
- end;
- end;
- end;
-end;
-
-end.
-
diff --git a/Game/Code/Screens/UScreenStatDetail.pas b/Game/Code/Screens/UScreenStatDetail.pas
deleted file mode 100644
index 891b108d..00000000
--- a/Game/Code/Screens/UScreenStatDetail.pas
+++ /dev/null
@@ -1,270 +0,0 @@
-unit UScreenStatDetail;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UDisplay,
- UMusic,
- UIni,
- UDataBase,
- UThemes;
-
-type
- TScreenStatDetail = class(TMenu)
- public
- Typ: TStatType;
- Page: Cardinal;
- Count: Byte;
- Reversed: Boolean;
-
- TotEntrys: Cardinal;
- TotPages: Cardinal;
-
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
-
- procedure SetTitle;
- Procedure SetPage(NewPage: Cardinal);
- end;
-
-implementation
-
-uses
- UGraphic,
- ULanguage,
- Math,
- Classes,
- ULog;
-
-function TScreenStatDetail.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenStatMain);
- end;
- SDLK_RETURN:
- begin
- if Interaction = 0 then begin
- //Next Page
- SetPage(Page+1);
- end;
-
- if Interaction = 1 then begin
- //Previous Page
- if (Page > 0) then
- SetPage(Page-1);
- end;
-
- if Interaction = 2 then begin
- //Reverse Order
- Reversed := not Reversed;
- SetPage(Page);
- end;
-
- if Interaction = 3 then begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenStatMain);
- end;
- end;
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
- SDLK_UP:
- begin
- InteractPrev;
- end;
- SDLK_DOWN:
- begin
- InteractNext;
- end;
- end;
- end;
-end;
-
-constructor TScreenStatDetail.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- for I := 0 to High(Theme.StatDetail.TextList) do
- AddText(Theme.StatDetail.TextList[I]);
-
- Count := Length(Theme.StatDetail.TextList);
-
- AddText(Theme.StatDetail.TextDescription);
- AddText(Theme.StatDetail.TextPage);
-
- LoadFromTheme(Theme.StatDetail);
-
- AddButton(Theme.StatDetail.ButtonNext);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Language.Translate('STAT_NEXT'));
-
- AddButton(Theme.StatDetail.ButtonPrev);
- if (Length(Button[1].Text)=0) then
- AddButtonText(14, 20, Language.Translate('STAT_PREV'));
-
- AddButton(Theme.StatDetail.ButtonReverse);
- if (Length(Button[2].Text)=0) then
- AddButtonText(14, 20, Language.Translate('STAT_REVERSE'));
-
- AddButton(Theme.StatDetail.ButtonExit);
- if (Length(Button[3].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
- Interaction := 0;
- Typ := TStatType(0);
-end;
-
-procedure TScreenStatDetail.onShow;
-begin
- inherited;
-
- //Set Tot Entrys and PAges
- TotEntrys := DataBase.GetTotalEntrys(Typ);
- TotPages := Ceil(TotEntrys / Count);
-
- //Show correct Title
- SetTitle;
-
- //Show First Page
- Reversed := False;
- SetPage(0);
-end;
-
-procedure TScreenStatDetail.SetTitle;
-begin
- if Reversed then
- Text[Count].Text := Theme.StatDetail.DescriptionR[Ord(Typ)]
- else
- Text[Count].Text := Theme.StatDetail.Description[Ord(Typ)];
-end;
-
-procedure TScreenStatDetail.SetPage(NewPage: Cardinal);
-var
- StatList: TList;
- I: Integer;
- FormatStr: String;
- PerPage: Byte;
-begin
- // fetch statistics
- StatList := Database.GetStats(Typ, Count, NewPage, Reversed);
- if ((StatList <> nil) and (StatList.Count > 0)) then
- begin
- Page := NewPage;
-
- // reset texts
- for I := 0 to Count-1 do
- Text[I].Text := '';
-
- FormatStr := Theme.StatDetail.FormatStr[Ord(Typ)];
-
- //refresh Texts
- for I := 0 to StatList.Count-1 do
- begin
- try
- case Typ of
- stBestScores: begin //Best Scores
- with TStatResultBestScores(StatList[I]) do
- begin
- //Set Texts
- if (Score > 0) then
- begin
- Text[I].Text := Format(FormatStr,
- [Singer, Score, Theme.ILevel[Difficulty], SongArtist, SongTitle]);
- end;
- end;
- end;
-
- stBestSingers: begin //Best Singers
- with TStatResultBestSingers(StatList[I]) do
- begin
- //Set Texts
- if (AverageScore > 0) then
- Text[I].Text := Format(FormatStr, [Player, AverageScore]);
- end;
- end;
-
- stMostSungSong: begin //Popular Songs
- with TStatResultMostSungSong(StatList[I]) do
- begin
- //Set Texts
- if (Artist <> '') then
- Text[I].Text := Format(FormatStr, [Artist, Title, TimesSung]);
- end;
- end;
-
- stMostPopBand: begin //Popular Bands
- with TStatResultMostPopBand(StatList[I]) do
- begin
- //Set Texts
- if (ArtistName <> '') then
- Text[I].Text := Format(FormatStr, [ArtistName, TimesSungtot]);
- end;
- end;
- end;
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString in UScreenStatDetail: ' + E.Message);
- end;
- end;
-
- if (Page + 1 = TotPages) and (TotEntrys mod Count <> 0) then
- PerPage := (TotEntrys mod Count)
- else
- PerPage := Count;
-
- try
- Text[Count+1].Text := Format(Theme.StatDetail.PageStr,
- [Page + 1, TotPages, PerPage, TotEntrys]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString in UScreenStatDetail: ' + E.Message);
- end;
-
- //Show correct Title
- SetTitle;
- end;
-
- Database.FreeStats(StatList);
-end;
-
-
-procedure TScreenStatDetail.SetAnimationProgress(Progress: real);
-var I: Integer;
-begin
- for I := 0 to High(Button) do
- Button[I].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas
deleted file mode 100644
index bec9d312..00000000
--- a/Game/Code/Screens/UScreenStatMain.pas
+++ /dev/null
@@ -1,301 +0,0 @@
-unit UScreenStatMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UDisplay,
- UMusic,
- UIni,
- UThemes;
-
-type
- TScreenStatMain = class(TMenu)
- private
- //Some Stat Value that don't need to be calculated 2 times
- SongsWithVid: Cardinal;
- function FormatOverviewIntro(FormatStr: string): string;
- function FormatSongOverview(FormatStr: string): string;
- function FormatPlayerOverview(FormatStr: string): string;
- public
- TextOverview: integer;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
-
- procedure SetOverview;
- end;
-
-implementation
-
-uses UGraphic,
- UDataBase,
- USongs,
- USong,
- ULanguage,
- UCommon,
- Classes,
- {$IFDEF win32}
- windows,
- {$ELSE}
- sysconst,
- {$ENDIF}
- ULog;
-
-function TScreenStatMain.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
- SDLK_RETURN:
- begin
- //Exit Button Pressed
- if Interaction = 4 then
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end
- else //One of the Stats Buttons Pressed
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- ScreenStatDetail.Typ := TStatType(Interaction);
- FadeTo(@ScreenStatDetail);
- end;
- end;
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
- SDLK_UP:
- begin
- InteractPrev;
- end;
- SDLK_DOWN:
- begin
- InteractNext;
- end;
- end;
- end;
-end;
-
-constructor TScreenStatMain.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- TextOverview := AddText(Theme.StatMain.TextOverview);
-
- LoadFromTheme(Theme.StatMain);
-
- AddButton(Theme.StatMain.ButtonScores);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[0]);
-
- AddButton(Theme.StatMain.ButtonSingers);
- if (Length(Button[1].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[1]);
-
- AddButton(Theme.StatMain.ButtonSongs);
- if (Length(Button[2].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[2]);
-
- AddButton(Theme.StatMain.ButtonBands);
- if (Length(Button[3].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[3]);
-
- AddButton(Theme.StatMain.ButtonExit);
- if (Length(Button[4].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[4]);
-
- Interaction := 0;
-
- //Set Songs with Vid
- SongsWithVid := 0;
- For I := 0 to Songs.SongList.Count -1 do
- if (TSong(Songs.SongList[I]).Video <> '') then
- Inc(SongsWithVid);
-end;
-
-procedure TScreenStatMain.onShow;
-begin
- inherited;
-
- //Set Overview Text:
- SetOverview;
-end;
-
-function TScreenStatMain.FormatOverviewIntro(FormatStr: string): string;
-var
- Year, Month, Day: Word;
-begin
- {Format:
- %0:d Ultrastar Version
- %1:d Day of Reset
- %2:d Month of Reset
- %3:d Year of Reset}
-
- Result := '';
-
- try
- DecodeDate(Database.GetStatReset(), Year, Month, Day);
- Result := Format(FormatStr, [Language.Translate('US_VERSION'), Day, Month, Year]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_INTRO": ' + E.Message);
- end;
-end;
-
-function TScreenStatMain.FormatSongOverview(FormatStr: string): string;
-var
- CntSongs, CntSungSongs, CntVidSongs: Integer;
- MostPopSongArtist, MostPopSongTitle: String;
- StatList: TList;
- MostSungSong: TStatResultMostSungSong;
-begin
- {Format:
- %0:d Count Songs
- %1:d Count of Sung Songs
- %2:d Count of UnSung Songs
- %3:d Count of Songs with Video
- %4:s Name of the most popular Song}
-
- CntSongs := Songs.SongList.Count;
- CntSungSongs := Database.GetTotalEntrys(stMostSungSong);
- CntVidSongs := SongsWithVid;
-
- StatList := Database.GetStats(stMostSungSong, 1, 0, False);
- if ((StatList <> nil) and (StatList.Count > 0)) then
- begin
- MostSungSong := StatList[0];
- MostPopSongArtist := MostSungSong.Artist;
- MostPopSongTitle := MostSungSong.Title;
- end
- else
- begin
- MostPopSongArtist := '-';
- MostPopSongTitle := '-';
- end;
- Database.FreeStats(StatList);
-
- Result := '';
-
- try
- Result := Format(FormatStr, [
- CntSongs, CntSungSongs, CntSongs-CntSungSongs, CntVidSongs,
- MostPopSongArtist, MostPopSongTitle]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_SONG": ' + E.Message);
- end;
-end;
-
-function TScreenStatMain.FormatPlayerOverview(FormatStr: string): string;
-var
- CntPlayers: Integer;
- BestScoreStat: TStatResultBestScores;
- BestSingerStat: TStatResultBestSingers;
- BestPlayer, BestScorePlayer: String;
- BestPlayerScore, BestScore: Integer;
- SingerStats, ScoreStats: TList;
-begin
- {Format:
- %0:d Count Players
- %1:s Best Player
- %2:d Best Players Score
- %3:s Best Score Player
- %4:d Best Score}
-
- CntPlayers := Database.GetTotalEntrys(stBestSingers);
-
- SingerStats := Database.GetStats(stBestSingers, 1, 0, False);
- if ((SingerStats <> nil) and (SingerStats.Count > 0)) then
- begin
- BestSingerStat := SingerStats[0];
- BestPlayer := BestSingerStat.Player;
- BestPlayerScore := BestSingerStat.AverageScore;
- end
- else
- begin
- BestPlayer := '-';
- BestPlayerScore := 0;
- end;
- Database.FreeStats(SingerStats);
-
- ScoreStats := Database.GetStats(stBestScores, 1, 0, False);
- if ((ScoreStats <> nil) and (ScoreStats.Count > 0)) then
- begin
- BestScoreStat := ScoreStats[0];
- BestScorePlayer := BestScoreStat.Singer;
- BestScore := BestScoreStat.Score;
- end
- else
- begin
- BestScorePlayer := '-';
- BestScore := 0;
- end;
- Database.FreeStats(ScoreStats);
-
- Result := '';
-
- try
- Result := Format(Formatstr, [
- CntPlayers, BestPlayer, BestPlayerScore,
- BestScorePlayer, BestScore]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_PLAYER": ' + E.Message);
- end;
-end;
-
-procedure TScreenStatMain.SetOverview;
-var
- Overview: String;
-begin
- // Format overview
- Overview := FormatOverviewIntro(Language.Translate('STAT_OVERVIEW_INTRO')) + '\n \n' +
- FormatSongOverview(Language.Translate('STAT_OVERVIEW_SONG')) + '\n \n' +
- FormatPlayerOverview(Language.Translate('STAT_OVERVIEW_PLAYER'));
- Text[0].Text := Overview;
-end;
-
-
-procedure TScreenStatMain.SetAnimationProgress(Progress: real);
-var I: Integer;
-begin
- For I := 0 to high(Button) do
- Button[I].Texture.ScaleW := Progress;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas
deleted file mode 100644
index f4be431f..00000000
--- a/Game/Code/Screens/UScreenTop5.pas
+++ /dev/null
@@ -1,175 +0,0 @@
-unit UScreenTop5;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, SysUtils, UDisplay, UMusic, USongs, UThemes;
-
-type
- TScreenTop5 = class(TMenu)
- public
- TextLevel: integer;
- TextArtistTitle: integer;
-
- StaticNumber: array[1..5] of integer;
- TextNumber: array[1..5] of integer;
- TextName: array[1..5] of integer;
- TextScore: array[1..5] of integer;
-
- Fadeout: boolean;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- function Draw: boolean; override;
- end;
-
-implementation
-
-uses UGraphic, UDataBase, UMain, UIni;
-
-function TScreenTop5.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then begin
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE,
- SDLK_RETURN:
- begin
- if (not Fadeout) then begin
- FadeTo(@ScreenSong);
- Fadeout := true;
- end;
- end;
- SDLK_SYSREQ:
- begin
- Display.SaveScreenShot;
- end;
- end;
- end;
-end;
-
-constructor TScreenTop5.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Top5);
-
-
- TextLevel := AddText(Theme.Top5.TextLevel);
- TextArtistTitle := AddText(Theme.Top5.TextArtistTitle);
-
- for I := 0 to 4 do
- StaticNumber[I+1] := AddStatic( Theme.Top5.StaticNumber[I] );
-
- for I := 0 to 4 do
- TextNumber[I+1] := AddText(Theme.Top5.TextNumber[I]);
- for I := 0 to 4 do
- TextName[I+1] := AddText(Theme.Top5.TextName[I]);
- for I := 0 to 4 do
- TextScore[I+1] := AddText(Theme.Top5.TextScore[I]);
-
-end;
-
-procedure TScreenTop5.onShow;
-var
- I: integer;
- PMax: integer;
-begin
- inherited;
-
- Fadeout := false;
-
- //ReadScore(CurrentSong);
-
- PMax := Ini.Players;
- if PMax = 4 then PMax := 5;
- for I := 0 to PMax do
- DataBase.AddScore(CurrentSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalInt));
-
- DataBase.WriteScore(CurrentSong);
- DataBase.ReadScore(CurrentSong);
-
- Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
-
- for I := 1 to Length(CurrentSong.Score[Ini.Difficulty]) do begin
- Static[StaticNumber[I]].Visible := true;
- Text[TextNumber[I]].Visible := true;
- Text[TextName[I]].Visible := true;
- Text[TextScore[I]].Visible := true;
-
- Text[TextName[I]].Text := CurrentSong.Score[Ini.Difficulty, I-1].Name;
- Text[TextScore[I]].Text := IntToStr(CurrentSong.Score[Ini.Difficulty, I-1].Score);
- end;
-
- for I := Length(CurrentSong.Score[Ini.Difficulty])+1 to 5 do begin
- Static[StaticNumber[I]].Visible := false;
- Text[TextNumber[I]].Visible := false;
- Text[TextName[I]].Visible := false;
- Text[TextScore[I]].Visible := false;
- end;
-
- Text[TextLevel].Text := IDifficulty[Ini.Difficulty];
-end;
-
-function TScreenTop5.Draw: boolean;
-//var
-{ Min: real;
- Max: real;
- Wsp: real;
- Wsp2: real;
- Pet: integer;}
-
-{ Item: integer;
- P: integer;
- C: integer;}
-begin
- // Singstar - let it be...... with 6 statics
-(* if PlayersPlay = 6 then begin
- for Item := 4 to 6 do begin
- if ScreenAct = 1 then P := Item-4;
- if ScreenAct = 2 then P := Item-1;
-
- FillPlayer(Item, P);
-
-{ if ScreenAct = 1 then begin
- LoadColor(
- Static[StaticBoxLightest[Item]].Texture.ColR,
- Static[StaticBoxLightest[Item]].Texture.ColG,
- Static[StaticBoxLightest[Item]].Texture.ColB,
- 'P1Dark');
- end;
-
- if ScreenAct = 2 then begin
- LoadColor(
- Static[StaticBoxLightest[Item]].Texture.ColR,
- Static[StaticBoxLightest[Item]].Texture.ColG,
- Static[StaticBoxLightest[Item]].Texture.ColB,
- 'P4Dark');
- end; }
-
- end;
- end; *)
-
- Result := inherited Draw;
-end;
-
-end.
diff --git a/Game/Code/Screens/UScreenWelcome.pas b/Game/Code/Screens/UScreenWelcome.pas
deleted file mode 100644
index 613f3a80..00000000
--- a/Game/Code/Screens/UScreenWelcome.pas
+++ /dev/null
@@ -1,122 +0,0 @@
-unit UScreenWelcome;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, SysUtils, UThemes;
-
-type
- TScreenWelcome = class(TMenu)
- public
- Animation: real;
- Fadeout: boolean;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, UTime, USkins, UTexture;
-
-function TScreenWelcome.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then begin
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Result := False;
- end;
- SDLK_RETURN:
- begin
- FadeTo(@ScreenMain);
- Fadeout := true;
- end;
- end;
- end;
-end;
-
-constructor TScreenWelcome.Create;
-begin
- inherited Create;
- AddStatic(-10, -10, 0, 0, 1, 1, 1, Skin.GetTextureFileName('ButtonAlt'), TEXTURE_TYPE_TRANSPARENT);
- AddStatic(-500, 440, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 472, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 504, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 536, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 568, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- Animation := 0;
- Fadeout := false;
-end;
-
-procedure TScreenWelcome.onShow;
-begin
- inherited;
-
- CountSkipTimeSet;
-end;
-
-function TScreenWelcome.Draw: boolean;
-var
- Min: real;
- Max: real;
- Wsp: real;
- Pet: integer;
-begin
- // star animation
- Animation := Animation + TimeSkip*1000;
-
- // draw nothing
- Min := 0; Max := 1000;
- if (Animation >= Min) and (Animation < Max) then begin
- end;
-
- // popup
- Min := 1000; Max := 1120;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
- Static[0].Texture.X := 600;
- Static[0].Texture.Y := 600 - Wsp * 230;
- Static[0].Texture.W := 200;
- Static[0].Texture.H := Wsp * 230;
- end;
-
- // bounce
- Min := 1120; Max := 1200;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
- Static[0].Texture.Y := 370 + Wsp * 50;
- Static[0].Texture.H := 230 - Wsp * 50;
- end;
-
- // run
- Min := 1500; Max := 3500;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
-
- Static[0].Texture.X := 600 - Wsp * 1400;
- Static[0].Texture.H := 180;
-
-
- for Pet := 1 to 5 do begin
- Static[Pet].Texture.X := 770 - Wsp * 1400;
- Static[Pet].Texture.W := 150 + Wsp * 200;
- Static[Pet].Texture.Alpha := Wsp * 0.5;
- end;
- end;
-
- Min := 3500;
- if (Animation >= Min) and (not Fadeout) then begin
- FadeTo(@ScreenMain);
- Fadeout := true;
- end;
-
- Result := inherited Draw;
-end;
-
-end.
diff --git a/Game/Code/UltraStar-linux.lpi b/Game/Code/UltraStar-linux.lpi
deleted file mode 100644
index d3866f94..00000000
--- a/Game/Code/UltraStar-linux.lpi
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
deleted file mode 100644
index c39f596c..00000000
--- a/Game/Code/UltraStar.dpr
+++ /dev/null
@@ -1,294 +0,0 @@
-program UltraStar;
-
-{$IFDEF MSWINDOWS}
- {$R 'UltraStar.res' 'UltraStar.rc'}
-{$ENDIF}
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-//{$DEFINE CONSOLE}
-
-// TODO: check if this is needed for MacOSX too
-{$IFDEF MSWINDOWS}
- // Set global application-type (GUI/CONSOLE) switch for Windows.
- // CONSOLE is the default for FPC, GUI for Delphi, so we have
- // to specify one of the two in any case.
- {$IFDEF CONSOLE}
- {$APPTYPE CONSOLE}
- {$ELSE}
- {$APPTYPE GUI}
- {$ENDIF}
-{$ENDIF}
-
-uses
- {$IFDEF Unix}
- cthreads, // THIS MUST be the first used unit in FPC if Threads are used!!
- // (see http://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial)
- {$IFNDEF DARWIN}
- cwstring, // Enable Unicode support. MacOSX misses some references to iconv.
- {$ENDIF}
- {$ENDIF}
-
- {$IFNDEF FPC}
- ctypes in 'lib\ctypes\ctypes.pas', // FPC compatibility types for C libs
- {$ENDIF}
-
- //------------------------------
- //Includes - 3rd Party Libraries
- //------------------------------
- moduleloader in 'lib\JEDI-SDL\SDL\Pas\moduleloader.pas',
- gl in 'lib\JEDI-SDL\OpenGL\Pas\gl.pas',
- glu in 'lib\JEDI-SDL\OpenGL\Pas\glu.pas',
- glext in 'lib\JEDI-SDL\OpenGL\Pas\glext.pas',
- sdl in 'lib\JEDI-SDL\SDL\Pas\sdl.pas',
- sdl_image in 'lib\JEDI-SDL\SDL_Image\Pas\sdl_image.pas',
- //sdl_ttf in 'lib\JEDI-SDL\SDL_ttf\Pas\sdl_ttf.pas',
- sdlutils in 'lib\JEDI-SDL\SDL\Pas\sdlutils.pas',
- UMediaCore_SDL in 'Classes\UMediaCore_SDL.pas',
-
- zlib in 'lib\zlib\zlib.pas',
- png in 'lib\libpng\png.pas',
-
- {$IFDEF UseBass}
- bass in 'lib\bass\delphi\bass.pas',
- UAudioCore_Bass in 'Classes\UAudioCore_Bass.pas',
- {$ENDIF}
- {$IFDEF UsePortaudio}
- portaudio in 'lib\portaudio\delphi\portaudio.pas',
- UAudioCore_Portaudio in 'Classes\UAudioCore_Portaudio.pas',
- {$ENDIF}
- {$IFDEF UsePortmixer}
- portmixer in 'lib\portmixer\delphi\portmixer.pas',
- {$ENDIF}
-
- {$IFDEF UseFFmpeg}
- avcodec in 'lib\ffmpeg\avcodec.pas',
- avformat in 'lib\ffmpeg\avformat.pas',
- avutil in 'lib\ffmpeg\avutil.pas',
- rational in 'lib\ffmpeg\rational.pas',
- opt in 'lib\ffmpeg\opt.pas',
- avio in 'lib\ffmpeg\avio.pas',
- mathematics in 'lib\ffmpeg\mathematics.pas',
- UMediaCore_FFmpeg in 'Classes\UMediaCore_FFmpeg.pas',
- {$IFDEF UseSWScale}
- swscale in 'lib\ffmpeg\swscale.pas',
- {$ENDIF}
- {$ENDIF}
-
- {$IFDEF UseSRCResample}
- samplerate in 'lib\samplerate\samplerate.pas',
- {$ENDIF}
-
- {$IFDEF UseProjectM}
- projectM in 'lib\projectM\projectM.pas',
- {$ENDIF}
-
- {$IFDEF MSWINDOWS}
- {$IFDEF FPC}
- // FPC compatibility file for Allocate/DeallocateHWnd
- WinAllocation in 'lib\other\WinAllocation.pas',
- {$ENDIF}
-
- midiout in 'lib\midi\midiout.pas',
- CIRCBUF in 'lib\midi\CIRCBUF.PAS',
- MidiType in 'lib\midi\MidiType.PAS',
- MidiDefs in 'lib\midi\MidiDefs.PAS',
- MidiCons in 'lib\midi\MidiCons.PAS',
- MidiFile in 'lib\midi\MidiFile.PAS',
- Delphmcb in 'lib\midi\Delphmcb.PAS',
-
- DirWatch in 'lib\other\DirWatch.pas',
- {$ENDIF}
-
- {$IFDEF DARWIN}
- PseudoThread in 'MacOSX/Wrapper/PseudoThread.pas',
- {$ENDIF}
-
- SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
- SQLite3 in 'lib\SQLite\SQLite3.pas',
-
-
- //------------------------------
- //Includes - Menu System
- //------------------------------
- UDisplay in 'Menu\UDisplay.pas',
- UMenu in 'Menu\UMenu.pas',
- UMenuStatic in 'Menu\UMenuStatic.pas',
- UMenuText in 'Menu\UMenuText.pas',
- UMenuButton in 'Menu\UMenuButton.pas',
- UMenuInteract in 'Menu\UMenuInteract.pas',
- UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas',
- UDrawTexture in 'Menu\UDrawTexture.pas',
- UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas',
-
- //------------------------------
- //Includes - Classes
- //------------------------------
- UConfig in 'Classes\UConfig.pas',
-
- UCommon in 'Classes\UCommon.pas',
- UGraphic in 'Classes\UGraphic.pas',
- UTexture in 'Classes\UTexture.pas',
- ULanguage in 'Classes\ULanguage.pas',
- UMain in 'Classes\UMain.pas',
- UDraw in 'Classes\UDraw.pas',
- URecord in 'Classes\URecord.pas',
- UTime in 'Classes\UTime.pas',
- TextGL in 'Classes\TextGL.pas',
- USong in 'Classes\USong.pas',
- UXMLSong in 'Classes\UXMLSong.pas',
- USongs in 'Classes\USongs.pas',
- UIni in 'Classes\UIni.pas',
- UImage in 'Classes\UImage.pas',
- ULyrics in 'Classes\ULyrics.pas',
- UEditorLyrics in 'Classes\UEditorLyrics.pas',
- USkins in 'Classes\USkins.pas',
- UThemes in 'Classes\UThemes.pas',
- ULog in 'Classes\ULog.pas',
- UJoystick in 'Classes\UJoystick.pas',
- //ULCD in 'Classes\ULCD.pas',
- //ULight in 'Classes\ULight.pas',
- UDataBase in 'Classes\UDataBase.pas',
- UCovers in 'Classes\UCovers.pas',
- UCatCovers in 'Classes\UCatCovers.pas',
- UFiles in 'Classes\UFiles.pas',
- UGraphicClasses in 'Classes\UGraphicClasses.pas',
- UDLLManager in 'Classes\UDLLManager.pas',
- UPlaylist in 'Classes\UPlaylist.pas',
- UCommandLine in 'Classes\UCommandLine.pas',
- URingBuffer in 'Classes\URingBuffer.pas',
- UTextClasses in 'Classes\UTextClasses.pas',
- USingScores in 'Classes\USingScores.pas',
- USingNotes in 'Classes\USingNotes.pas',
-
- UModules in 'Classes\UModules.pas', //List of Modules to Load
- UHooks in 'Classes\UHooks.pas', //Hook Managing
- UServices in 'Classes\UServices.pas', //Service Managing
- UCore in 'Classes\UCore.pas', //Core, Maybe remove this
- UCoreModule in 'Classes\UCoreModule.pas', //^
- UPluginInterface in 'Classes\UPluginInterface.pas', //Interface offered by Core to Plugins
- uPluginLoader in 'Classes\uPluginLoader.pas', //New Plugin Loader Module
-
- UParty in 'Classes\UParty.pas', // TODO: rewrite Party Manager as Module, reomplent ability to offer party Mody by Plugin
- UPlatform in 'Classes\UPlatform.pas',
-{$IFDEF MSWINDOWS}
- UPlatformWindows in 'Classes\UPlatformWindows.pas',
-{$ENDIF}
-{$IFDEF LINUX}
- UPlatformLinux in 'Classes\UPlatformLinux.pas',
-{$ENDIF}
-{$IFDEF DARWIN}
- UPlatformMacOSX in 'Classes/UPlatformMacOSX.pas',
-{$ENDIF}
-
- //------------------------------
- //Includes - Media
- //------------------------------
-
- UMusic in 'Classes\UMusic.pas',
- UAudioPlaybackBase in 'Classes\UAudioPlaybackBase.pas',
-{$IF Defined(UsePortaudioPlayback) or Defined(UseSDLPlayback)}
- UFFT in 'lib\fft\UFFT.pas',
- UAudioPlayback_Softmixer in 'Classes\UAudioPlayback_SoftMixer.pas',
-{$IFEND}
- UAudioConverter in 'Classes\UAudioConverter.pas',
-
- //******************************
- //Pluggable media modules
- // The modules are prioritized as in the include list below.
- // This means the first entry has highest priority, the last lowest.
- //******************************
-
- // TODO : these all should be moved to a media folder
-
-{$IFDEF UseFFmpegVideo}
- UVideo in 'Classes\UVideo.pas',
-{$ENDIF}
-{$IFDEF UseProjectM}
- // must be after UVideo, so it will not be the default video module
- UVisualizer in 'Classes\UVisualizer.pas',
-{$ENDIF}
-{$IFDEF UseBASSInput}
- UAudioInput_Bass in 'Classes\UAudioInput_Bass.pas',
-{$ENDIF}
-{$IFDEF UseBASSDecoder}
- // prefer Bass to FFmpeg if possible
- UAudioDecoder_Bass in 'Classes\UAudioDecoder_Bass.pas',
-{$ENDIF}
-{$IFDEF UseBASSPlayback}
- UAudioPlayback_Bass in 'Classes\UAudioPlayback_Bass.pas',
-{$ENDIF}
-{$IFDEF UseSDLPlayback}
- UAudioPlayback_SDL in 'Classes\UAudioPlayback_SDL.pas',
-{$ENDIF}
-{$IFDEF UsePortaudioInput}
- UAudioInput_Portaudio in 'Classes\UAudioInput_Portaudio.pas',
-{$ENDIF}
-{$IFDEF UsePortaudioPlayback}
- UAudioPlayback_Portaudio in 'Classes\UAudioPlayback_Portaudio.pas',
-{$ENDIF}
-{$IFDEF UseFFmpegDecoder}
- UAudioDecoder_FFmpeg in 'Classes\UAudioDecoder_FFmpeg.pas',
-{$ENDIF}
- // fallback dummy, must be last
- UMedia_dummy in 'Classes\UMedia_dummy.pas',
-
-
- //------------------------------
- //Includes - Screens
- //------------------------------
- UScreenLoading in 'Screens\UScreenLoading.pas',
- UScreenWelcome in 'Screens\UScreenWelcome.pas',
- UScreenMain in 'Screens\UScreenMain.pas',
- UScreenName in 'Screens\UScreenName.pas',
- UScreenLevel in 'Screens\UScreenLevel.pas',
- UScreenSong in 'Screens\UScreenSong.pas',
- UScreenSing in 'Screens\UScreenSing.pas',
- UScreenScore in 'Screens\UScreenScore.pas',
- UScreenOptions in 'Screens\UScreenOptions.pas',
- UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas',
- UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas',
- UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas',
- UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas',
- UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas',
- UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas',
- UScreenOptionsAdvanced in 'Screens\UScreenOptionsAdvanced.pas',
- UScreenEditSub in 'Screens\UScreenEditSub.pas',
- UScreenEdit in 'Screens\UScreenEdit.pas',
- UScreenEditConvert in 'Screens\UScreenEditConvert.pas',
- UScreenEditHeader in 'Screens\UScreenEditHeader.pas',
- UScreenOpen in 'Screens\UScreenOpen.pas',
- UScreenTop5 in 'Screens\UScreenTop5.pas',
- UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
- UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
- UScreenStatMain in 'Screens\UScreenStatMain.pas',
- UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
- UScreenCredits in 'Screens\UScreenCredits.pas',
- UScreenPopup in 'Screens\UScreenPopup.pas',
-
- //Includes - Screens PartyMode
- UScreenSingModi in 'Screens\UScreenSingModi.pas',
- UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas',
- UScreenPartyScore in 'Screens\UScreenPartyScore.pas',
- UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas',
- UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas',
- UScreenPartyWin in 'Screens\UScreenPartyWin.pas',
-
-
- //------------------------------
- //Includes - Modi SDK
- //------------------------------
- ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', //Old SDK, will be deleted soon
- UPluginDefs in '..\..\Modis\SDK\UPluginDefs.pas', //New SDK, not only Modis
- UPartyDefs in '..\..\Modis\SDK\UPartyDefs.pas', //Headers to register Party Modes
-
- SysUtils;
-
-begin
- Main;
-end.
-
diff --git a/Game/Code/UltraStar.lpi b/Game/Code/UltraStar.lpi
deleted file mode 100644
index e21d8786..00000000
--- a/Game/Code/UltraStar.lpi
+++ /dev/null
@@ -1,598 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Game/Code/UltraStar.lpr b/Game/Code/UltraStar.lpr
deleted file mode 100644
index 66badecb..00000000
--- a/Game/Code/UltraStar.lpr
+++ /dev/null
@@ -1,19 +0,0 @@
-// ***************************************************************************
-//
-// Developers PLEASE NOTE !!!!!!!
-//
-// As of september 2007, I am working towards porting Ultrastar-DX to run
-// on Linux. I will be modifiying the source to make it compile in lazarus
-// on windows & linux and I will make sure that it compiles in delphi still
-// To help me in this endevour, please can you make a point of remembering
-// that linux is CASE SENSATIVE, and file / unit names must be as per
-// the filename exactly.
-//
-// EG : opengl12.pas must not be OpenGL in the uses cluase.
-//
-// thanks for your help...
-//
-// ***************************************************************************
-
-{$I UltraStar.dpr}
-
diff --git a/Game/Code/UltraStar.rc b/Game/Code/UltraStar.rc
deleted file mode 100644
index f0f3b242..00000000
--- a/Game/Code/UltraStar.rc
+++ /dev/null
@@ -1,38 +0,0 @@
-Font TEX "../../Resources/Fonts/Normal/eurostar_regular.png"
-Font FNT "../../Resources/Fonts/Normal/eurostar_regular.dat"
-
-FontB TEX "../../Resources/Fonts/Bold/eurostar_regular_bold.png"
-FontB FNT "../../Resources/Fonts/Bold/eurostar_regular_bold.dat"
-
-FontO TEX "../../Resources/Fonts/Outline 1/Outline 1.png"
-FontO FNT "../../Resources/Fonts/Outline 1/Outline 1.dat"
-
-FontO2 TEX "../../Resources/Fonts/Outline 2/Outline 2.png"
-FontO2 FNT "../../Resources/Fonts/Outline 2/Outline 2.dat"
-
-MAINICON ICON "../../Resources/Graphics/ustar-icon_v01.ico"
-WINDOWICON TEX "../../Resources/Graphics/ustar-icon.png"
-
-CRDTS_BG TEX "../../Resources/Graphics/credits_v5_bg.png"
-CRDTS_OVL TEX "../../Resources/Graphics/credits_v5_overlay.png"
-CRDTS_blindguard TEX "../../Resources/Graphics/names_blindguard.png"
-CRDTS_blindy TEX "../../Resources/Graphics/names_blindy.png"
-CRDTS_canni TEX "../../Resources/Graphics/names_canni.png"
-CRDTS_commandio TEX "../../Resources/Graphics/names_commandio.png"
-CRDTS_lazyjoker TEX "../../Resources/Graphics/names_lazyjoker.png"
-CRDTS_mog TEX "../../Resources/Graphics/names_mog.png"
-CRDTS_mota TEX "../../Resources/Graphics/names_mota.png"
-CRDTS_skillmaster TEX "../../Resources/Graphics/names_skillmaster.png"
-CRDTS_whiteshark TEX "../../Resources/Graphics/names_whiteshark.png"
-INTRO_L01 TEX "../../Resources/Graphics/intro-l-01.png"
-INTRO_L02 TEX "../../Resources/Graphics/intro-l-02.png"
-INTRO_L03 TEX "../../Resources/Graphics/intro-l-03.png"
-INTRO_L04 TEX "../../Resources/Graphics/intro-l-04.png"
-INTRO_L05 TEX "../../Resources/Graphics/intro-l-05.png"
-INTRO_L06 TEX "../../Resources/Graphics/intro-l-06.png"
-INTRO_L07 TEX "../../Resources/Graphics/intro-l-07.png"
-INTRO_L08 TEX "../../Resources/Graphics/intro-l-08.png"
-INTRO_L09 TEX "../../Resources/Graphics/intro-l-09.png"
-OUTRO_BG TEX "../../Resources/Graphics/outro-bg.png"
-OUTRO_ESC TEX "../../Resources/Graphics/outro-esc.png"
-OUTRO_EXD TEX "../../Resources/Graphics/outro-exit-dark.png"
diff --git a/Game/Code/UnitTests/switches.inc b/Game/Code/UnitTests/switches.inc
deleted file mode 100644
index e69de29b..00000000
diff --git a/Game/Code/UnitTests/test_libraries.lpi b/Game/Code/UnitTests/test_libraries.lpi
deleted file mode 100644
index cc3a6ddf..00000000
--- a/Game/Code/UnitTests/test_libraries.lpi
+++ /dev/null
@@ -1,299 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Game/Code/UnitTests/test_libraries.lpr b/Game/Code/UnitTests/test_libraries.lpr
deleted file mode 100644
index 3e3ae380..00000000
--- a/Game/Code/UnitTests/test_libraries.lpr
+++ /dev/null
@@ -1,31 +0,0 @@
-program Test_Libraries;
-
-{$mode objfpc}{$H+}
-
-uses
- Classes,
- consoletestrunner,
- TestSQLLite,
- SQLite3 in '../lib/SQLite/SQLite3.pas',
-
- SQLiteTable3 in '../lib/SQLite/SQLiteTable3.pas';
-
-type
-
- { TLazTestRunner }
-
- TMyTestRunner = class(TTestRunner)
- protected
- // override the protected methods of TTestRunner to customize its behavior
- end;
-
-var
- Application: TMyTestRunner;
-
-begin
- Application := TMyTestRunner.Create(nil);
- Application.Initialize;
- Application.Title := 'FPCUnit Console test runner';
- Application.Run;
- Application.Free;
-end.
diff --git a/Game/Code/UnitTests/testsqllite.pas b/Game/Code/UnitTests/testsqllite.pas
deleted file mode 100644
index b1b682d2..00000000
--- a/Game/Code/UnitTests/testsqllite.pas
+++ /dev/null
@@ -1,84 +0,0 @@
-unit TestSQLLite;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, fpcunit, testutils, testregistry, SQLiteTable3, unix;
-
-type
-
- TTest_SqlLite= class(TTestCase)
- private
- fSQLLite : TSQLiteDatabase;
- fFileName : string;
- protected
- procedure SetUp; override;
- procedure TearDown; override;
- published
- procedure Test_Random_TableExists;
- procedure Test_Delete_NonExistant_Table;
- procedure Test_TableExists_On_0Length_File;
- end;
-
-implementation
-
-procedure TTest_SqlLite.Test_Random_TableExists;
-begin
- deletefile( fFileName );
- fSQLLite := TSQLiteDatabase.Create( fFileName );
-
- // Test if some random table exists
- check( not fSQLLite.TableExists( 'testTable'+floattostr(now()) ) , 'Randomly Named Table Should NOT Exists (In an empty database file)' );
-end;
-
-procedure TTest_SqlLite.Test_Delete_NonExistant_Table;
-var
- lSQL : String;
-begin
- deletefile( fFileName );
- fSQLLite := TSQLiteDatabase.Create( fFileName );
- try
- lSQL := 'DROP TABLE testtable';
- fSQLLite.execsql( lSQL );
- except
- exit;
- end;
-
- Fail('SQLLite did not except when trying to delete a non existant table' );
-end;
-
-procedure TTest_SqlLite.Test_TableExists_On_0Length_File;
-var
- lSQL : String;
-begin
- deletefile( fFileName );
- shell('cat /dev/null > '+fFileName);
-
- if not fileexists( fFileName ) then
- Fail('0 Length file was not created... oops' );
-
- fSQLLite := TSQLiteDatabase.Create( fFileName );
-
- check( not fSQLLite.TableExists( 'testTable' ) , 'Randomly Named Table Should NOT Exists' );
-end;
-
-
-procedure TTest_SqlLite.SetUp;
-begin
- fFileName := 'test.db';
-// fSQLLite := TSQLiteDatabase.Create( fFileName );
-end;
-
-
-procedure TTest_SqlLite.TearDown;
-begin
- freeandnil( fSQLLite );
-end;
-
-initialization
-
- RegisterTest(TTest_SqlLite);
-end.
-
diff --git a/Game/Code/autogen.sh b/Game/Code/autogen.sh
deleted file mode 100755
index 3f598d0b..00000000
--- a/Game/Code/autogen.sh
+++ /dev/null
@@ -1 +0,0 @@
-aclocal -I m4 && autoconf
diff --git a/Game/Code/bamboo-build-lin-laz.bat b/Game/Code/bamboo-build-lin-laz.bat
deleted file mode 100644
index bcaca539..00000000
--- a/Game/Code/bamboo-build-lin-laz.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-clear
-fpc -S2cgi -OG1 -gl -vewnhi -l -Filib/JEDI-SDLv1.0/SDL/Pas/ -Fu/usr/lib/lazarus/components/images/lib/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/gtk2/ -Fu/usr/lib/lazarus/packager/units/i386-linux/ -Fu. -oUltraStar -dLCL -dLCLgtk2 UltraStar.lpr
-
-#mv ./UltraStar /home/jay/src/ultrastardx/output/
diff --git a/Game/Code/bamboo-build-lin-laz.sh b/Game/Code/bamboo-build-lin-laz.sh
deleted file mode 100644
index ad8ef19f..00000000
--- a/Game/Code/bamboo-build-lin-laz.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-svn update
-
-clear
-fpc -S2cgi -OG1 -gl -vewnhi -l -Filib/JEDI-SDLv1.0/SDL/Pas/ -Fu/usr/lib/lazarus/components/images/lib/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/gtk2/ -Fu/usr/lib/lazarus/packager/units/i386-linux/ -Fu. -oUltraStar -dLCL -dLCLgtk2 UltraStar.lpr
-
-#mv ./UltraStar /home/jay/src/ultrastardx/output/
diff --git a/Game/Code/bamboo-build-win-delphi.bat b/Game/Code/bamboo-build-win-delphi.bat
deleted file mode 100644
index 8a6be942..00000000
--- a/Game/Code/bamboo-build-win-delphi.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-"C:\Program Files\Borland\BDS\4.0\Bin\brc32.exe" -r ./UltraStar.rc
-
-"C:\Program Files\Borland\BDS\4.0\Bin\dcc32.exe" -U"lib\JEDI-SDL\SDL\Pas" -O"lib\JEDI-SDL\SDL\Pas" -I"lib\JEDI-SDL\SDL\Pas" -R"lib\JEDI-SDL\SDL\Pas" UltraStar.dpr
-cp UltraStar.exe ..\..\
-
-rem cd ..\..\Installer
-rem "C:\Program Files\NSIS\makeNSIS.exe" UltraStarDeluxe.nsi
-
-rem cd ..\Game\Code
\ No newline at end of file
diff --git a/Game/Code/bamboo-build-win-laz.bat b/Game/Code/bamboo-build-win-laz.bat
deleted file mode 100644
index 1d096004..00000000
--- a/Game/Code/bamboo-build-win-laz.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-USDXResCompiler.exe UltraStar.rc
-
-C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fuc:\lazarus\components\jpeg\lib\i386-win32\ -Fuc:\lazarus\components\images\lib\i386-win32\ -Fuc:\lazarus\lcl\units\i386-win32\ -Fuc:\lazarus\lcl\units\i386-win32\win32\ -Fuc:\lazarus\packager\units\i386-win32\ -Fu. -oUltraStar.exe -dLCL -dLCLwin32 UltraStar.lpr
diff --git a/Game/Code/build.bat b/Game/Code/build.bat
deleted file mode 100644
index 59f465d5..00000000
--- a/Game/Code/build.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fu..\..\..\..\..\lazarus\components\jpeg\lib\i386-win32\ -Fu..\..\..\..\..\lazarus\components\images\lib\i386-win32\ -Fu..\..\..\..\..\lazarus\lcl\units\i386-win32\ -Fu..\..\..\..\..\lazarus\lcl\units\i386-win32\win32\ -Fu..\..\..\..\..\lazarus\packager\units\i386-win32\ -Fu. -oUltraStar.exe -dLCL -dLCLwin32 UltraStar.lpr
-rem C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fu. -oUltraStar.exe UltraStar.lpr
-
-move UltraStar.exe ..\..\
\ No newline at end of file
diff --git a/Game/Code/clean.bat b/Game/Code/clean.bat
deleted file mode 100644
index ef4ca243..00000000
--- a/Game/Code/clean.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-@ECHO OFF
-set OBJ_PATH=build\win32\fpc
-del %OBJ_PATH%\*.o
-del %OBJ_PATH%\*.ppu
-del %OBJ_PATH%\*.a
-del %OBJ_PATH%\*.rst
-del %OBJ_PATH%\*.compiled
diff --git a/Game/Code/config-darwin.inc b/Game/Code/config-darwin.inc
deleted file mode 100644
index 6b73ee24..00000000
--- a/Game/Code/config-darwin.inc
+++ /dev/null
@@ -1,59 +0,0 @@
-{*****************************************************************
- * Configuration file for UltraStar-Deluxe 1.1-alpha
- * config-darwin.inc. Generated from config.inc.in by configure.
- *****************************************************************}
-
-{* Paths *}
-
-{$DEFINE UseLocalDirs}
-{$IF (not Defined(UseLocalDirs)) and Defined(IncludeConstants)}
- PathSuffix = WideString('UltraStarDeluxe');
- LogPath = WideString('/var/log/'+PathSuffix);
- SharedPath = WideString('/usr/local/share/'+PathSuffix);
-{$IFEND}
-
-{* Libraries *}
-
-{$DEFINE HaveFFMpeg}
-{$IF Defined(HaveFFMpeg) and Defined(IncludeConstants)}
- av__codec = 'libavcodec';
- LIBAVCODEC_VERSION_MAJOR = 51;
- LIBAVCODEC_VERSION_MINOR = 49;
- LIBAVCODEC_VERSION_RELEASE = 0;
-
- av__format = 'libavformat';
- LIBAVFORMAT_VERSION_MAJOR = 52;
- LIBAVFORMAT_VERSION_MINOR = 2;
- LIBAVFORMAT_VERSION_RELEASE = 0;
-
- av__util = 'libavutil';
- LIBAVUTIL_VERSION_MAJOR = 49;
- LIBAVUTIL_VERSION_MINOR = 6;
- LIBAVUTIL_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$DEFINE HaveSWScale}
-{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
- sw__scale = 'libswscale';
- LIBSWSCALE_VERSION_MAJOR = 0;
- LIBSWSCALE_VERSION_MINOR = 5;
- LIBSWSCALE_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$UNDEF HaveProjectM}
-{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
- ProjectM_DataDir = '';
- PROJECTM_VERSION_MAJOR = 0;
- PROJECTM_VERSION_MINOR = 0;
- PROJECTM_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$DEFINE HavePortaudio}
-{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
- PORTAUDIO_VERSION_MAJOR = 19;
- PORTAUDIO_VERSION_MINOR = 0;
- PORTAUDIO_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$UNDEF HavePortmixer}
-
diff --git a/Game/Code/config-win.inc b/Game/Code/config-win.inc
deleted file mode 100644
index e3ca8840..00000000
--- a/Game/Code/config-win.inc
+++ /dev/null
@@ -1,56 +0,0 @@
-{*****************************************************************
- * Configuration file for UltraStar Deluxe 1.1
- *****************************************************************}
-
-{* Libraries *}
-
-{$DEFINE HaveFFmpeg}
-{$IF Defined(HaveFFmpeg) and Defined(IncludeConstants)}
- av__codec = 'avcodec-51';
- LIBAVCODEC_VERSION_MAJOR = 51;
- LIBAVCODEC_VERSION_MINOR = 16;
- LIBAVCODEC_VERSION_RELEASE = 0;
-
- av__format = 'avformat-50';
- LIBAVFORMAT_VERSION_MAJOR = 50;
- LIBAVFORMAT_VERSION_MINOR = 5;
- LIBAVFORMAT_VERSION_RELEASE = 0;
-
- av__util = 'avutil-49';
- LIBAVUTIL_VERSION_MAJOR = 49;
- LIBAVUTIL_VERSION_MINOR = 0;
- LIBAVUTIL_VERSION_RELEASE = 1;
-{$IFEND}
-
-{$UNDEF HaveSWScale}
-{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
- sw__scale = 'swscale-0';
- LIBSWSCALE_VERSION_MAJOR = 0;
- LIBSWSCALE_VERSION_MINOR = 5;
- LIBSWSCALE_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$DEFINE HaveProjectM}
-{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
- ProjectM_DataDir = 'Visuals\projectM';
- PROJECTM_VERSION_MAJOR = 1;
- PROJECTM_VERSION_MINOR = 10;
- PROJECTM_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$UNDEF HavePortaudio}
-{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
- PORTAUDIO_VERSION_MAJOR = 19;
- PORTAUDIO_VERSION_MINOR = 0;
- PORTAUDIO_VERSION_RELEASE = 0;
-{$IFEND}
-
-{$UNDEF HavePortmixer}
-
-{$UNDEF HaveLibsamplerate}
-{$IF Defined(HaveLibsamplerate) and Defined(IncludeConstants)}
- LIBSAMPLERATE_VERSION_MAJOR = 0;
- LIBSAMPLERATE_VERSION_MINOR = 1;
- LIBSAMPLERATE_VERSION_RELEASE = 3;
-{$IFEND}
-
diff --git a/Game/Code/config.inc.in b/Game/Code/config.inc.in
deleted file mode 100644
index 6bdf26b5..00000000
--- a/Game/Code/config.inc.in
+++ /dev/null
@@ -1,58 +0,0 @@
-{*****************************************************************
- * Configuration file for @PACKAGE_STRING@
- * @configure_input@
- *****************************************************************}
-
-{* Paths *}
-
-{$@DEFINE_USE_LOCAL_DIRS@ UseLocalDirs}
-{$IF (not Defined(UseLocalDirs)) and Defined(IncludeConstants)}
- PathSuffix = WideString('@suffix@');
- SharedPath = WideString('@sharerootdir@/'+PathSuffix);
-{$IFEND}
-
-{* Libraries *}
-
-{$@DEFINE_HAVE_FFMPEG@ HaveFFmpeg}
-{$IF Defined(HaveFFmpeg) and Defined(IncludeConstants)}
- av__codec = 'libavcodec';
- LIBAVCODEC_VERSION_MAJOR = @libavcodec_VERSION_MAJOR@;
- LIBAVCODEC_VERSION_MINOR = @libavcodec_VERSION_MINOR@;
- LIBAVCODEC_VERSION_RELEASE = @libavcodec_VERSION_RELEASE@;
-
- av__format = 'libavformat';
- LIBAVFORMAT_VERSION_MAJOR = @libavformat_VERSION_MAJOR@;
- LIBAVFORMAT_VERSION_MINOR = @libavformat_VERSION_MINOR@;
- LIBAVFORMAT_VERSION_RELEASE = @libavformat_VERSION_RELEASE@;
-
- av__util = 'libavutil';
- LIBAVUTIL_VERSION_MAJOR = @libavutil_VERSION_MAJOR@;
- LIBAVUTIL_VERSION_MINOR = @libavutil_VERSION_MINOR@;
- LIBAVUTIL_VERSION_RELEASE = @libavutil_VERSION_RELEASE@;
-{$IFEND}
-
-{$@DEFINE_HAVE_SWSCALE@ HaveSWScale}
-{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
- sw__scale = 'libswscale';
- LIBSWSCALE_VERSION_MAJOR = @libswscale_VERSION_MAJOR@;
- LIBSWSCALE_VERSION_MINOR = @libswscale_VERSION_MINOR@;
- LIBSWSCALE_VERSION_RELEASE = @libswscale_VERSION_RELEASE@;
-{$IFEND}
-
-{$@DEFINE_HAVE_PROJECTM@ HaveProjectM}
-{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
- ProjectM_DataDir = '@libprojectM_DATADIR@';
- PROJECTM_VERSION_MAJOR = @libprojectM_VERSION_MAJOR@;
- PROJECTM_VERSION_MINOR = @libprojectM_VERSION_MINOR@;
- PROJECTM_VERSION_RELEASE = @libprojectM_VERSION_RELEASE@;
-{$IFEND}
-
-{$@DEFINE_HAVE_PORTAUDIO@ HavePortaudio}
-{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
- PORTAUDIO_VERSION_MAJOR = @portaudio_VERSION_MAJOR@;
- PORTAUDIO_VERSION_MINOR = @portaudio_VERSION_MINOR@;
- PORTAUDIO_VERSION_RELEASE = @portaudio_VERSION_RELEASE@;
-{$IFEND}
-
-{$@DEFINE_HAVE_PORTMIXER@ HavePortmixer}
-
diff --git a/Game/Code/configure.ac b/Game/Code/configure.ac
deleted file mode 100644
index 4f1344f5..00000000
--- a/Game/Code/configure.ac
+++ /dev/null
@@ -1,494 +0,0 @@
-#
-# ultrastardx configure.ac script
-#
-# by UltraStar Deluxe Team
-#
-# Execute "autogen.sh" to create the configure script.
-#
-
-# Require autoconf >= 2.61
-AC_PREREQ(2.61)
-
-# Init autoconf
-AC_INIT([ultrastardx],
- [1.1-alpha],
- [http://sourceforge.net/tracker/?group_id=191560&atid=937872])
-# specify the website here
-PACKAGE_WEBSITE="http://www.ultrastardeluxe.org/"
-AC_SUBST(PACKAGE_WEBSITE)
-# specify the IRC-channel here
-PACKAGE_IRC="#ultrastardx at quakenet.org"
-AC_SUBST(PACKAGE_IRC)
-
-# Specify a source-file so autoconf can check if the source-dir exists
-AC_CONFIG_SRCDIR(UltraStar.dpr)
-
-# This one is not used by autoconf at the moment.
-# When it is used maybe we don't need aclocal's -I parameter anymore.
-AC_CONFIG_MACRO_DIR(m4)
-
-# show features and packages in one list
-AC_PRESERVE_HELP_ORDER
-
-# set root directory (= trunk dir)
-# ..resolved: used by configure.ac
-usdxroot=../..
-# ..unresolved: used by .in files
-usdxrootdir=\${top_srcdir}/../..
-AC_SUBST(usdxrootdir)
-
-# set sharerootdir to the resolved dataroot-dir for the config-*.inc file.
-# Pascal cannot handle shell-variables like ${prefix}
-AC_DEFINE_DIR(sharerootdir, datarootdir)
-
-# -----------------------------------------
-# find tools
-# -----------------------------------------
-
-# options for make command
-AC_PROG_MAKE_SET
-# find tool for ln -s (e.g. uses cp -p for FAT-filesystems)
-AC_LN_S
-# find a program for recursive dir creation
-AC_PROG_MKDIR_P
-# find the best install tool
-AC_PROG_INSTALL
-# some other useful tools
-#AC_PROG_AWK
-AC_PROG_SED
-AC_PROG_GREP
-#AC_PROG_EGREP
-
-# -----------------------------------------
-# macro declarations
-# -----------------------------------------
-
-# AC_TRIM(STRING)
-# removes surrounding whitespace
-# -------------------------------------------
-AC_DEFUN([AC_TRIM],
-[echo "[$1]" | $SED 's/^[[ \t]]*//' | $SED 's/[[ \t]]*$//'
-])
-
-# AC_SUBST_DEFINE(DEFINE_SUFFIX, IS_DEFINED)
-# used to enable/disable pascal defines
-AC_DEFUN([AC_SUBST_DEFINE],
-[
- if [[ x$2 = xyes ]]; then
- DEFINE_[$1]=DEFINE
- else
- DEFINE_[$1]=UNDEF
- fi
- AC_SUBST(DEFINE_[$1])
-])
-
-# AC_SUBST_COMMENT(DEFINE_SUFFIX, IS_ENABLED)
-# used to enable/disable lines in a Makefile
-AC_DEFUN([AC_SUBST_COMMENT],
-[
- if [[ x$2 = xyes ]]; then
- COMMENT_[$1]=""
- else
- COMMENT_[$1]="#"
- fi
- AC_SUBST(COMMENT_[$1])
-])
-
-# AC_SPLIT_VERSION(VARIABLE_PREFIX, VERSION)
-# Splits version number ("major.minor.release") into its components.
-# Sets
-# [$VARIABLE_PREFIX]_VERSION_MAJOR
-# [$VARIABLE_PREFIX]_VERSION_MINOR
-# [$VARIABLE_PREFIX]_VERSION_RELEASE
-# This function calls
-# AC_SUBST([$VARIABLE_PREFIX]_VERSION_type] for each type
-AC_DEFUN([AC_SPLIT_VERSION],
-[
- version=[$2]
-
- # strip leading non-numeric tokens
- # (necessary for some ffmpeg-packages in ubuntu)
- # example: 0d.51.1.0 -> 51.1.0
- version=`echo $version | $SED 's/^[[^.]]*[[^0-9.]][[^.]]*\.//'`
-
- # replace "." and "-" with " " and ignore trailing tokens.
- # 1.23.4-r2 will be splitted to [maj=1, min=23, rel=4].
- # In addition we delete every character which is not 0-9.
- # 1.3a4-r32 will be [maj=1, min=34, rel=32].
- read major minor release ignore <@)
- else
- [$1][_VERSION]="0.0.0"
- fi
- AC_SPLIT_VERSION([$1], $[$1][_VERSION])
-])
-
-# PKG_HAVE(VARIABLE_PREFIX, MODULE, [REQUIRED])
-# Checks with pkg-config if a package exists and retrieves information
-# about it.
-# Parameters:
-# - VARIABLE_PREFIX: the prefix for the variables storing information about the package.
-# - MODULE: package name according to pkg-config
-# - REQUIRED: if true, the configure-script is aborted if the package was not found
-# Uses:
-# with_[$VARIABLE_PREFIX]: whether and how the package should be checked for
-# "check": check for the package but do not abort if it does not exist (default)
-# "no": do not check for the package (sets _HAVE to "no" and _VERSION to "0.0.0")
-# "yes": check for the package and abort if it does not exist
-# "nocheck": do not check for the package (sets _HAVE to "yes")
-# Sets:
-# [$VARIABLE_PREFIX]_HAVE # package is available (values: "yes"|"no")
-# [$VARIABLE_PREFIX]_LIBS # linker flags (e.g. -Lmylibdir -lmylib)
-# [$VARIABLE_PREFIX]_LIBDIRS # library dirs (e.g. -Lmylibdir)
-AC_DEFUN([PKG_HAVE],
-[
- have_lib="no"
- AC_MSG_CHECKING([for $2])
- if test x"$with_[$1]" = xnocheck; then
- # do not call pkg-config, use user settings
- have_lib="yes"
- elif test x"$with_[$1]" != xno; then
- # check if package exists
- PKG_CHECK_EXISTS([$2], [
- have_lib="yes"
- [$1][_LIBS]=`$PKG_CONFIG --libs --silence-errors "$2"`
- [$1][_LIBDIRS]=`$PKG_CONFIG --libs-only-L --silence-errors "$2"`
- [$1][_LIBDIRS]=`AC_TRIM($[$1][_LIBDIRS])`
- # add library directories to LIBS (ignore *_LIBS for now)
- if test -n "$[$1][_LIBDIRS]"; then
- LIBS="$LIBS $[$1][_LIBDIRS]"
- fi
- ])
- fi
- if test x$have_lib = xyes; then
- [$1][_HAVE]="yes"
- if test -n "$[$1][_LIBDIRS]"; then
- # show additional lib-dirs
- AC_MSG_RESULT(yes [(]$[$1][_LIBDIRS][)])
- else
- AC_MSG_RESULT(yes)
- fi
- else
- [$1][_HAVE]="no"
- AC_MSG_RESULT(no)
-
- # check if package is required
- if test x$3 = xyes -o x"$with_[$1]" = xyes ; then
- # print error message and quit
- err_msg=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
- AC_MSG_ERROR(
-[
-
-$err_msg
-
-Alternatively, you may set --with-[$1]=nocheck and the environment
-variables [$1]_[[...]] (see configure --help)
-to appropriate values to avoid the need to call pkg-config.
-
-See the pkg-config man page for more details.
-])
- fi
- fi
-])
-
-
-# -----------------------------------------
-# define switches
-# -----------------------------------------
-
-# print library options header
-AC_ARG_WITH([cfg-dummy1], [
-External Libraries:])
-
-# add portmixer option
-AC_ARG_WITH([portmixer],
- [AS_HELP_STRING([--with-portmixer],
- [enable portmixer audio-mixer support @<:@default=check@:>@])],
- [with_portmixer=$withval], [with_portmixer="check"])
-
-# add projectM option
-AC_ARG_WITH([libprojectM],
- [AS_HELP_STRING([--with-libprojectM],
- [enable projectM visualization support @<:@default=no@:>@])],
- [with_libprojectM=$withval], [with_libprojectM="no"])
-
-# print path options header
-AC_ARG_WITH([cfg-dummy2], [
-Additional directories:])
-
-# add suffix option
-AC_ARG_WITH([suffix],
- [AS_HELP_STRING([--with-suffix=SUFFIX],
- [path suffix @<:@default=ultrastardx@:>@])],
- [suffix=$withval], [suffix="ultrastardx"])
-if [[ x$suffix = xno -o x$suffix = xyes ]] ; then
- AC_MSG_ERROR([Invalid suffix.]);
-fi
-AC_SUBST(suffix)
-
-# print misc options header
-AC_ARG_WITH([cfg-dummy3], [
-Development options:])
-
-LOCAL_BUILD="no"
-
-# add global option
-AC_ARG_ENABLE(global,
- [AS_HELP_STRING([--enable-global],
- [install into global folders (PREFIX/...) @<:@default=yes@:>@])],
- [test $enableval = "no" && LOCAL_BUILD="yes"], [])
-
-# add local option
-AC_ARG_ENABLE(local,
- [AS_HELP_STRING([--enable-local],
- [install into local folders (../../...) (same as --disable-global) @<:@default=no@:>@]))],
- [test $enableval = "yes" && LOCAL_BUILD="yes"], [])
-
-# add dev_layout option
-AC_ARG_ENABLE(dev-build,
- [AS_HELP_STRING([--enable-dev-build],
- [development build (implies local) @<:@default=no@:>@])],
- [enable_dev_build=$enableval], [enable_dev_build="no"])
-if [[ x$enable_dev_build = xyes ]]; then
- LOCAL_BUILD="yes"
-fi
-
-# set default Makefile install-target according to local/global build-type
-AC_SUBST_DEFINE(USE_LOCAL_DIRS, $LOCAL_BUILD)
-if [[ x$LOCAL_BUILD = xyes ]]; then
- AC_SUBST(install_type, ["local"])
-else
- AC_SUBST(install_type, ["global"])
-fi
-
-
-# -----------------------------------------
-# check for compilers
-# -----------------------------------------
-
-# find and test the freepascal compiler
-# sets PFLAGS, FPC_VERSION, FPC_DEBUG, etc.
-AC_PROG_FPC
-# FPC_VERSION is already defined by FPC, use
-# PPC as prefix instead.
-AC_SPLIT_VERSION(PPC, $FPC_VERSION)
-
-# find and test the C compiler (for C-libs and wrappers)
-AC_PROG_CC
-AC_LANG([C])
-
-# find and test the C++ compiler (for C-libs and wrappers)
-AC_PROG_CXX
-AC_LANG([C++])
-
-AC_PROG_RANLIB
-
-# find pkg-config
-PKG_PROG_PKG_CONFIG()
-if [[ x$PKG_CONFIG = x ]]; then
- AC_MSG_ERROR([
-!!! pkg-config was not found on your system.
-!!! It is needed to determine the versions of your libraries.
-!!! Install it and try again.])
-fi
-
-
-# -----------------------------------------
-# check for OS
-# -----------------------------------------
-
-if [[ x$FPC_PLATFORM = xdarwin ]]; then
- AC_MSG_CHECKING([for Mac OS X version])
- MACOSX_VERSION=`sw_vers -productVersion`
- AC_SPLIT_VERSION(MACOSX, $MACOSX_VERSION)
- AC_MSG_RESULT(@<:@$MACOSX_VERSION@:>@)
-fi
-
-# -----------------------------------------
-# check for libraries
-# -----------------------------------------
-
-# libpng
-PKG_HAVE([libpng], [libpng], yes)
-
-# find sdl
-PKG_HAVE([sdl], [sdl], yes)
-
-# find sqlite3
-PKG_HAVE([sqlite3], [sqlite3], yes)
-
-# find FFMpeg
-# Note: do not use the min/max version parameters with ffmpeg
-# otherwise it might fail in ubuntu due to a wrong version number
-# format in ffmpeg's .pc-files.
-# For example: 0d.51.1.2 instead of the correct 51.1.2.
-# A check for version >=52.0.0 will return version 0d.51.1.2
-# although it is lower because pkg-config is confused by the 0d.
-# Use [mylib]_VERSION_INT for version-checking instead
-PKG_HAVE([libavcodec], [libavcodec], yes)
-PKG_VERSION([libavcodec], [libavcodec])
-AC_CHECK_LIB([avcodec], [avcodec_decode_audio], [HAVE_AVCODEC_DECODE_AUDIO="yes"])
-AC_CHECK_LIB([avcodec], [avcodec_decode_audio2], [HAVE_AVCODEC_DECODE_AUDIO2="yes"])
-AC_CHECK_LIB([avcodec], [img_convert], [HAVE_IMG_CONVERT="yes"])
-PKG_HAVE([libavformat], [libavformat], yes)
-PKG_VERSION([libavformat], [libavformat])
-PKG_HAVE([libavutil], [libavutil], yes)
-PKG_VERSION([libavutil], [libavutil])
-if [[ x$libavcodec_HAVE = xyes -a x$libavformat_HAVE = xyes -a x$libavutil_HAVE = xyes ]]; then
- ffmpeg_HAVE=yes
-else
- ffmpeg_HAVE=no
-fi
-AC_SUBST_DEFINE(HAVE_FFMPEG, $ffmpeg_HAVE)
-
-# find FFMpeg's swscale lib (just if FFMpeg is compiled in GPL mode)
-PKG_HAVE([libswscale], [libswscale], no)
-PKG_VERSION([libswscale], [libswscale])
-AC_SUBST_DEFINE(HAVE_SWSCALE, $libswscale_HAVE)
-
-
-# find projectM version
-libprojectM_PKG="libprojectM >= 0.98"
-PKG_HAVE([libprojectM], [$libprojectM_PKG], no)
-PKG_VERSION([libprojectM], [$libprojectM_PKG])
-AC_SUBST_DEFINE(HAVE_PROJECTM, $libprojectM_HAVE)
-# get projectM include-dir
-PKG_VALUE([libprojectM], [INCLUDEDIR], [variable=includedir], [$libprojectM_PKG],
- [C-Header include-dir (e.g. /usr/include)])
-# get projectM data-dir (for preset- and font-dir)
-PKG_VALUE([libprojectM], [DATADIR], [variable=pkgdatadir], [$libprojectM_PKG],
- [projectM data-directory for presets etc. (e.g. /usr/share/projectM)])
-# check if we need the c-wrapper
-if [[ "$libprojectM_VERSION_MAJOR" -ge 1 ]]; then
- libprojectM_NEEDS_CWRAPPER=yes
-else
- libprojectM_NEEDS_CWRAPPER=no
-fi
-AC_SUBST_COMMENT(PROJECTM_CWRAPPER, $libprojectM_NEEDS_CWRAPPER)
-
-# find portaudio
-PKG_HAVE([portaudio], [portaudio-2.0], yes)
-PKG_VERSION([portaudio], [portaudio-2.0])
-AC_SUBST_DEFINE(HAVE_PORTAUDIO, $portaudio_HAVE)
-# find portmixer
-PKG_HAVE([portmixer], [portmixer], no)
-AC_SUBST_DEFINE(HAVE_PORTMIXER, $portmixer_HAVE)
-
-# determine linker-flags
-#LDFLAGS=
-#LIBS=
-AC_SUBST(LDFLAGS)
-AC_SUBST(LIBS)
-
-# -----------------------------------------
-# create output files
-# -----------------------------------------
-
-AC_CONFIG_FILES([config-$FPC_PLATFORM.inc:config.inc.in])
-AC_CONFIG_FILES([Makefile])
-AC_CONFIG_FILES([$usdxroot/Tools/ResourceExtractor/Makefile])
-if [[ x$libprojectM_NEEDS_CWRAPPER = xyes ]]; then
- AC_CONFIG_FILES([lib/projectM/cwrapper/Makefile])
-fi
-AC_OUTPUT
-
-# -----------------------------------------
-# show results
-# -----------------------------------------
-
-AC_MSG_NOTICE([
-
-!!!
-!!! Configuration of $PACKAGE_NAME $PACKAGE_VERSION done!
-!!!
-!!! Type "make" to compile and
-!!! "make install" to install it afterwards.
-!!!
-!!! For further information on $PACKAGE_NAME visit:
-!!! $PACKAGE_WEBSITE
-!!!
-!!! IMPORTANT:
-!!! This is an UNSUPPORTED ALPHA release for developers only.
-!!!
-!!! DO NOT EXPECT THE MAKEFILE OR THE PROGRAM ITSELF TO WORK
-!!!
-!!! If you want to contribute, visit the IRC-Channel instead:
-!!! $PACKAGE_IRC
-!!!
-!!! PLEASE DO NOT SEND BUGREPORTS FOR THIS VERSION.
-!!!
-])
-
-# TODO: insert this in the public beta release
-#!!! In case you find a bug send a bugreport to:
-#!!! $PACKAGE_BUGREPORT
-#!!! You might as well ask for help at the IRC-Channel
-#!!! $PACKAGE_IRC
-
-
diff --git a/Game/Code/developer_changelog.txt b/Game/Code/developer_changelog.txt
deleted file mode 100644
index 47a38aa1..00000000
--- a/Game/Code/developer_changelog.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Basic functionalty change log...
-------------------------------------------------------------------------------------
-developers, please update this document with functional changes
-( that have an effect on the user )
-so the packager can easily see whats been changed when doing a release changelog.
-------------------------------------------------------------------------------------
-
-
-2007-Sep-05 JayBinks Ultrastar-DX now has basic navigation compatibility with Windows Media Center Remote controls ( and possibly others ).
- ( Requires SDL.dll version 1.2 at shipping )
\ No newline at end of file
diff --git a/Game/Code/install-sh b/Game/Code/install-sh
deleted file mode 100755
index a5897de6..00000000
--- a/Game/Code/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/Game/Code/lazres-UltraStar.bat b/Game/Code/lazres-UltraStar.bat
deleted file mode 100644
index 39fc6a06..00000000
--- a/Game/Code/lazres-UltraStar.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-C:\lazarus\tools\lazres.exe UltraStar.lrs "..\Fonts\Normal\eurostar_regular.png" "..\Fonts\Normal\eurostar_regular.dat" "..\Fonts\Bold\eurostar_regular_bold.png" "..\Fonts\Bold\eurostar_regular_bold.dat" "..\Fonts\Outline 1\Outline 1.PNG" "..\Fonts\Outline 1\Outline 1.dat" "..\Fonts\Outline 2\Outline 2.PNG" "..\Fonts\Outline 2\Outline 2.dat" "..\Graphics\ustar-icon_v01.ico" "..\Graphics\credits_v5_bg.png" "..\Graphics\credits_v5_overlay.png" "..\Graphics\names_blindguard.png" "..\Graphics\names_blindy.png" "..\Graphics\names_canni.png" "..\Graphics\names_commandio.png" "..\Graphics\names_lazyjoker.png" "..\Graphics\names_mog.png" "..\Graphics\names_mota.png" "..\Graphics\names_skillmaster.png" "..\Graphics\names_whiteshark.png" "..\Graphics\intro-l-01.png" "..\Graphics\intro-l-02.png" "..\Graphics\intro-l-03.png" "..\Graphics\intro-l-04.png" "..\Graphics\intro-l-05.png" "..\Graphics\intro-l-06.png" "..\Graphics\intro-l-07.png" "..\Graphics\intro-l-08.png" "..\Graphics\intro-l-09.png" "..\Graphics\outro-bg.png" "..\Graphics\outro-esc.png" "..\Graphics\outro-exit-dark.png"
-
diff --git a/Game/Code/lib/FreeImage/FreeBitmap.pas b/Game/Code/lib/FreeImage/FreeBitmap.pas
deleted file mode 100644
index 4e5f50a4..00000000
--- a/Game/Code/lib/FreeImage/FreeBitmap.pas
+++ /dev/null
@@ -1,1742 +0,0 @@
-unit FreeBitmap;
-
-// ==========================================================
-//
-// Delphi wrapper for FreeImage 3
-//
-// Design and implementation by
-// - Anatoliy Pulyaevskiy (xvel84@rambler.ru)
-//
-// Contributors:
-// - Enzo Costantini (enzocostantini@libero.it)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-//
-// ==========================================================
-//
-// From begining all code of this file is based on C++ wrapper to
-// FreeImage - FreeImagePlus.
-//
-// ==========================================================
-
-{$IFDEF FPC}
- {$MODE Delphi}
- {$H+} // use AnsiString
-{$ENDIF}
-
-interface
-
-uses
- SysUtils, Classes, Windows, FreeImage;
-
-type
- { TFreeObject }
-
- TFreeObject = class(TObject)
- public
- function IsValid: Boolean; virtual;
- end;
-
- { TFreeTag }
-
- TFreeTag = class(TFreeObject)
- private
- // fields
- FTag: PFITAG;
-
- // getters & setters
- function GetCount: Cardinal;
- function GetDescription: string;
- function GetID: Word;
- function GetKey: string;
- function GetLength: Cardinal;
- function GetTagType: FREE_IMAGE_MDTYPE;
- function GetValue: Pointer;
- procedure SetCount(const Value: Cardinal);
- procedure SetDescription(const Value: string);
- procedure SetID(const Value: Word);
- procedure SetKey(const Value: string);
- procedure SetLength(const Value: Cardinal);
- procedure SetTagType(const Value: FREE_IMAGE_MDTYPE);
- procedure SetValue(const Value: Pointer);
- public
- // construction & destruction
- constructor Create(ATag: PFITAG = nil); virtual;
- destructor Destroy; override;
-
- // methods
- function Clone: TFreeTag;
- function IsValid: Boolean; override;
- function ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar = nil): string;
-
- // properties
- property Key: string read GetKey write SetKey;
- property Description: string read GetDescription write SetDescription;
- property ID: Word read GetID write SetID;
- property TagType: FREE_IMAGE_MDTYPE read GetTagType write SetTagType;
- property Count: Cardinal read GetCount write SetCount;
- property Length: Cardinal read GetLength write SetLength;
- property Value: Pointer read GetValue write SetValue;
- property Tag: PFITAG read FTag;
- end;
-
- { forward declarations }
-
- TFreeBitmap = class;
- TFreeMemoryIO = class;
-
- { TFreeBitmap }
-
- TFreeBitmapChangingEvent = procedure(Sender: TFreeBitmap; var OldDib, NewDib: PFIBITMAP; var Handled: Boolean) of object;
-
- TFreeBitmap = class(TFreeObject)
- private
- // fields
- FDib: PFIBITMAP;
- FOnChange: TNotifyEvent;
- FOnChanging: TFreeBitmapChangingEvent;
-
- procedure SetDib(Value: PFIBITMAP);
- protected
- function DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean; dynamic;
- function Replace(NewDib: PFIBITMAP): Boolean; dynamic;
- public
- constructor Create(ImageType: FREE_IMAGE_TYPE = FIT_BITMAP; Width: Integer = 0; Height: Integer = 0; Bpp: Integer = 0);
- destructor Destroy; override;
- function SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height, Bpp: Integer; RedMask: Cardinal = 0; GreenMask: Cardinal = 0; BlueMask: Cardinal = 0): Boolean;
- procedure Change; dynamic;
- procedure Assign(Source: TFreeBitmap);
- function CopySubImage(Left, Top, Right, Bottom: Integer; Dest: TFreeBitmap): Boolean;
- function PasteSubImage(Src: TFreeBitmap; Left, Top: Integer; Alpha: Integer = 256): Boolean;
- procedure Clear; virtual;
- function Load(const FileName: string; Flag: Integer = 0): Boolean;
- function LoadU(const FileName: WideString; Flag: Integer = 0): Boolean;
- function LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
- function LoadFromMemory(MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
- function LoadFromStream(Stream: TStream; Flag: Integer = 0): Boolean;
- // save functions
- function CanSave(fif: FREE_IMAGE_FORMAT): Boolean;
- function Save(const FileName: string; Flag: Integer = 0): Boolean;
- function SaveU(const FileName: WideString; Flag: Integer = 0): Boolean;
- function SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
- function SaveToMemory(fif: FREE_IMAGE_FORMAT; MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
- function SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream; Flag: Integer = 0): Boolean;
- // image information
- function GetImageType: FREE_IMAGE_TYPE;
- function GetWidth: Integer;
- function GetHeight: Integer;
- function GetScanWidth: Integer;
- function IsValid: Boolean; override;
- function GetInfo: PBitmapInfo;
- function GetInfoHeader: PBitmapInfoHeader;
- function GetImageSize: Cardinal;
- function GetBitsPerPixel: Integer;
- function GetLine: Integer;
- function GetHorizontalResolution: Double;
- function GetVerticalResolution: Double;
- procedure SetHorizontalResolution(Value: Double);
- procedure SetVerticalResolution(Value: Double);
- // palette operations
- function GetPalette: PRGBQUAD;
- function GetPaletteSize: Integer;
- function GetColorsUsed: Integer;
- function GetColorType: FREE_IMAGE_COLOR_TYPE;
- function IsGrayScale: Boolean;
- // pixels access
- function AccessPixels: PByte;
- function GetScanLine(ScanLine: Integer): PByte;
- function GetPixelIndex(X, Y: Cardinal; var Value: PByte): Boolean;
- function GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
- function SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean;
- function SetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
- // convertion
- function ConvertToStandardType(ScaleLinear: Boolean): Boolean;
- function ConvertToType(ImageType: FREE_IMAGE_TYPE; ScaleLinear: Boolean): Boolean;
- function Threshold(T: Byte): Boolean;
- function ConvertTo4Bits: Boolean;
- function ConvertTo8Bits: Boolean;
- function ConvertTo16Bits555: Boolean;
- function ConvertTo16Bits565: Boolean;
- function ConvertTo24Bits: Boolean;
- function ConvertTo32Bits: Boolean;
- function ConvertToGrayscale: Boolean;
- function ColorQuantize(Algorithm: FREE_IMAGE_QUANTIZE): Boolean;
- function Dither(Algorithm: FREE_IMAGE_DITHER): Boolean;
- function ConvertToRGBF: Boolean;
- function ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam, SecondParam: Double): Boolean;
- // transparency
- function IsTransparent: Boolean;
- function GetTransparencyCount: Cardinal;
- function GetTransparencyTable: PByte;
- procedure SetTransparencyTable(Table: PByte; Count: Integer);
- function HasFileBkColor: Boolean;
- function GetFileBkColor(var BkColor: PRGBQuad): Boolean;
- function SetFileBkColor(BkColor: PRGBQuad): Boolean;
- // channel processing routines
- function GetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
- function SetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
- function SplitChannels(RedChannel, GreenChannel, BlueChannel: TFreeBitmap): Boolean;
- function CombineChannels(Red, Green, Blue: TFreeBitmap): Boolean;
- // rotation and flipping
- function RotateEx(Angle, XShift, YShift, XOrigin, YOrigin: Double; UseMask: Boolean): Boolean;
- function Rotate(Angle: Double): Boolean;
- function FlipHorizontal: Boolean;
- function FlipVertical: Boolean;
- // color manipulation routines
- function Invert: Boolean;
- function AdjustCurve(Lut: PByte; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
- function AdjustGamma(Gamma: Double): Boolean;
- function AdjustBrightness(Percentage: Double): Boolean;
- function AdjustContrast(Percentage: Double): Boolean;
- function GetHistogram(Histo: PDWORD; Channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): Boolean;
- // upsampling / downsampling
- procedure MakeThumbnail(const Width, Height: Integer; DestBitmap: TFreeBitmap);
- function Rescale(NewWidth, NewHeight: Integer; Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap = nil): Boolean;
- // metadata routines
- function FindFirstMetadata(Model: FREE_IMAGE_MDMODEL; var Tag: TFreeTag): PFIMETADATA;
- function FindNextMetadata(MDHandle: PFIMETADATA; var Tag: TFreeTag): Boolean;
- procedure FindCloseMetadata(MDHandle: PFIMETADATA);
- function SetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; Tag: TFreeTag): Boolean;
- function GetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; var Tag: TFreeTag): Boolean;
- function GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal;
-
- // properties
- property Dib: PFIBITMAP read FDib write SetDib;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnChanging: TFreeBitmapChangingEvent read FOnChanging write FOnChanging;
- end;
-
- { TFreeWinBitmap }
-
-
- { TFreeMemoryIO }
-
- TFreeMemoryIO = class(TFreeObject)
- private
- FHMem: PFIMEMORY;
- public
- // construction and destruction
- constructor Create(Data: PByte = nil; SizeInBytes: DWORD = 0);
- destructor Destroy; override;
-
- function GetFileType: FREE_IMAGE_FORMAT;
- function Read(fif: FREE_IMAGE_FORMAT; Flag: Integer = 0): PFIBITMAP;
- function Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; Flag: Integer = 0): Boolean;
- function Tell: Longint;
- function Seek(Offset: Longint; Origin: Word): Boolean;
- function Acquire(var Data: PByte; var SizeInBytes: DWORD): Boolean;
- // overriden methods
- function IsValid: Boolean; override;
- end;
-
- { TFreeMultiBitmap }
-
- TFreeMultiBitmap = class(TFreeObject)
- private
- FMPage: PFIMULTIBITMAP;
- FMemoryCache: Boolean;
- public
- // constructor and destructor
- constructor Create(KeepCacheInMemory: Boolean = False);
- destructor Destroy; override;
-
- // methods
- function Open(const FileName: string; CreateNew, ReadOnly: Boolean; Flags: Integer = 0): Boolean;
- function Close(Flags: Integer = 0): Boolean;
- function GetPageCount: Integer;
- procedure AppendPage(Bitmap: TFreeBitmap);
- procedure InsertPage(Page: Integer; Bitmap: TFreeBitmap);
- procedure DeletePage(Page: Integer);
- function MovePage(Target, Source: Integer): Boolean;
- procedure LockPage(Page: Integer; DestBitmap: TFreeBitmap);
- procedure UnlockPage(Bitmap: TFreeBitmap; Changed: Boolean);
- function GetLockedPageNumbers(var Pages: Integer; var Count: Integer): Boolean;
- // overriden methods
- function IsValid: Boolean; override;
-
- // properties
- // change of this property influences only on the next opening of a file
- property MemoryCache: Boolean read FMemoryCache write FMemoryCache;
- end;
-
-implementation
-
-const
- ThumbSize = 150;
-
-// marker used for clipboard copy / paste
-
-procedure SetFreeImageMarker(bmih: PBitmapInfoHeader; dib: PFIBITMAP);
-begin
- // Windows constants goes from 0L to 5L
- // Add $FF to avoid conflicts
- bmih.biCompression := $FF + FreeImage_GetImageType(dib);
-end;
-
-function GetFreeImageMarker(bmih: PBitmapInfoHeader): FREE_IMAGE_TYPE;
-begin
- Result := FREE_IMAGE_TYPE(bmih.biCompression - $FF);
-end;
-
-{ TFreePersistent }
-
-function TFreeObject.IsValid: Boolean;
-begin
- Result := False
-end;
-
-{ TFreeBitmap }
-
-function TFreeBitmap.AccessPixels: PByte;
-begin
- Result := FreeImage_GetBits(FDib)
-end;
-
-function TFreeBitmap.AdjustBrightness(Percentage: Double): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_AdjustBrightness(FDib, Percentage);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.AdjustContrast(Percentage: Double): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_AdjustContrast(FDib, Percentage);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.AdjustCurve(Lut: PByte;
- Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_AdjustCurve(FDib, Lut, Channel);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.AdjustGamma(Gamma: Double): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_AdjustGamma(FDib, Gamma);
- Change;
- end
- else
- Result := False
-end;
-
-procedure TFreeBitmap.Assign(Source: TFreeBitmap);
-var
- SourceBmp: TFreeBitmap;
- Clone: PFIBITMAP;
-begin
- if Source = nil then
- begin
- Clear;
- Exit;
- end;
-
- if Source is TFreeBitmap then
- begin
- SourceBmp := TFreeBitmap(Source);
- if SourceBmp <> Self then
- begin
- if SourceBmp.IsValid then
- begin
- Clone := FreeImage_Clone(SourceBmp.FDib);
- Replace(Clone);
- end
- else
- Clear;
- end;
- end;
-end;
-
-function TFreeBitmap.CanSave(fif: FREE_IMAGE_FORMAT): Boolean;
-var
- ImageType: FREE_IMAGE_TYPE;
- Bpp: Word;
-begin
- Result := False;
- if not IsValid then Exit;
-
- if fif <> FIF_UNKNOWN then
- begin
- // check that the dib can be saved in this format
- ImageType := FreeImage_GetImageType(FDib);
- if ImageType = FIT_BITMAP then
- begin
- // standard bitmap type
- Bpp := FreeImage_GetBPP(FDib);
- Result := FreeImage_FIFSupportsWriting(fif)
- and FreeImage_FIFSupportsExportBPP(fif, Bpp);
- end
- else // special bitmap type
- Result := FreeImage_FIFSupportsExportType(fif, ImageType);
- end;
-end;
-
-procedure TFreeBitmap.Change;
-begin
- if Assigned(FOnChange) then FOnChange(Self)
-end;
-
-procedure TFreeBitmap.Clear;
-begin
- if FDib <> nil then
- begin
- FreeImage_Unload(FDib);
- FDib := nil;
- Change;
- end;
-end;
-
-function TFreeBitmap.ColorQuantize(
- Algorithm: FREE_IMAGE_QUANTIZE): Boolean;
-var
- dib8: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib8 := FreeImage_ColorQuantize(FDib, Algorithm);
- Result := Replace(dib8);
- end
- else
- Result := False;
-end;
-
-function TFreeBitmap.CombineChannels(Red, Green,
- Blue: TFreeBitmap): Boolean;
-var
- Width, Height: Integer;
-begin
- if FDib = nil then
- begin
- Width := Red.GetWidth;
- Height := Red.GetHeight;
- FDib := FreeImage_Allocate(Width, Height, 24, FI_RGBA_RED_MASK,
- FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- end;
-
- if FDib <> nil then
- begin
- Result := FreeImage_SetChannel(FDib, Red.FDib, FICC_RED) and
- FreeImage_SetChannel(FDib, Green.FDib, FICC_GREEN) and
- FreeImage_SetChannel(FDib, Blue.FDib, FICC_BLUE);
-
- Change
- end
- else
- Result := False;
-end;
-
-function TFreeBitmap.ConvertTo16Bits555: Boolean;
-var
- dib16_555: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib16_555 := FreeImage_ConvertTo16Bits555(FDib);
- Result := Replace(dib16_555);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ConvertTo16Bits565: Boolean;
-var
- dib16_565: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib16_565 := FreeImage_ConvertTo16Bits565(FDib);
- Result := Replace(dib16_565);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ConvertTo24Bits: Boolean;
-var
- dibRGB: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dibRGB := FreeImage_ConvertTo24Bits(FDib);
- Result := Replace(dibRGB);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ConvertTo32Bits: Boolean;
-var
- dib32: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib32 := FreeImage_ConvertTo32Bits(FDib);
- Result := Replace(dib32);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ConvertTo4Bits: Boolean;
-var
- dib4: PFIBITMAP;
-begin
- Result := False;
- if IsValid then
- begin
- dib4 := FreeImage_ConvertTo4Bits(FDib);
- Result := Replace(dib4);
- end;
-end;
-
-function TFreeBitmap.ConvertTo8Bits: Boolean;
-var
- dib8: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib8 := FreeImage_ConvertTo8Bits(FDib);
- Result := Replace(dib8);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ConvertToGrayscale: Boolean;
-var
- dib8: PFIBITMAP;
-begin
- Result := False;
-
- if IsValid then
- begin
- dib8 := FreeImage_ConvertToGreyscale(FDib);
- Result := Replace(dib8);
- end
-end;
-
-function TFreeBitmap.ConvertToRGBF: Boolean;
-var
- ImageType: FREE_IMAGE_TYPE;
- NewDib: PFIBITMAP;
-begin
- Result := False;
- if not IsValid then Exit;
-
- ImageType := GetImageType;
-
- if (ImageType = FIT_BITMAP) then
- begin
- if GetBitsPerPixel < 24 then
- if not ConvertTo24Bits then
- Exit
- end;
- NewDib := FreeImage_ConvertToRGBF(FDib);
- Result := Replace(NewDib);
-end;
-
-function TFreeBitmap.ConvertToStandardType(ScaleLinear: Boolean): Boolean;
-var
- dibStandard: PFIBITMAP;
-begin
- if IsValid then
- begin
- dibStandard := FreeImage_ConvertToStandardType(FDib, ScaleLinear);
- Result := Replace(dibStandard);
- end
- else
- Result := False;
-end;
-
-function TFreeBitmap.ConvertToType(ImageType: FREE_IMAGE_TYPE;
- ScaleLinear: Boolean): Boolean;
-var
- dib: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib := FreeImage_ConvertToType(FDib, ImageType, ScaleLinear);
- Result := Replace(dib)
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.CopySubImage(Left, Top, Right, Bottom: Integer;
- Dest: TFreeBitmap): Boolean;
-begin
- if FDib <> nil then
- begin
- Dest.FDib := FreeImage_Copy(FDib, Left, Top, Right, Bottom);
- Result := Dest.IsValid;
- end else
- Result := False;
-end;
-
-constructor TFreeBitmap.Create(ImageType: FREE_IMAGE_TYPE; Width, Height,
- Bpp: Integer);
-begin
- inherited Create;
-
- FDib := nil;
- if (Width > 0) and (Height > 0) and (Bpp > 0) then
- SetSize(ImageType, Width, Height, Bpp);
-end;
-
-destructor TFreeBitmap.Destroy;
-begin
- if FDib <> nil then
- FreeImage_Unload(FDib);
- inherited;
-end;
-
-function TFreeBitmap.Dither(Algorithm: FREE_IMAGE_DITHER): Boolean;
-var
- dib: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib := FreeImage_Dither(FDib, Algorithm);
- Result := Replace(dib);
- end
- else
- Result := False;
-end;
-
-function TFreeBitmap.DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean;
-begin
- Result := False;
- if (OldDib <> NewDib) and Assigned(FOnChanging) then
- FOnChanging(Self, OldDib, NewDib, Result);
-end;
-
-procedure TFreeBitmap.FindCloseMetadata(MDHandle: PFIMETADATA);
-begin
- FreeImage_FindCloseMetadata(MDHandle);
-end;
-
-function TFreeBitmap.FindFirstMetadata(Model: FREE_IMAGE_MDMODEL;
- var Tag: TFreeTag): PFIMETADATA;
-begin
- Result := FreeImage_FindFirstMetadata(Model, FDib, Tag.FTag);
-end;
-
-function TFreeBitmap.FindNextMetadata(MDHandle: PFIMETADATA;
- var Tag: TFreeTag): Boolean;
-begin
- Result := FreeImage_FindNextMetadata(MDHandle, Tag.FTag);
-end;
-
-function TFreeBitmap.FlipHorizontal: Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_FlipHorizontal(FDib);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.FlipVertical: Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_FlipVertical(FDib);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.GetBitsPerPixel: Integer;
-begin
- Result := FreeImage_GetBPP(FDib)
-end;
-
-function TFreeBitmap.GetChannel(Bitmap: TFreeBitmap;
- Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
-begin
- if FDib <> nil then
- begin
- Bitmap.Dib := FreeImage_GetChannel(FDib, Channel);
- Result := Bitmap.IsValid;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.GetColorsUsed: Integer;
-begin
- Result := FreeImage_GetColorsUsed(FDib)
-end;
-
-function TFreeBitmap.GetColorType: FREE_IMAGE_COLOR_TYPE;
-begin
- Result := FreeImage_GetColorType(FDib);
-end;
-
-function TFreeBitmap.GetFileBkColor(var BkColor: PRGBQuad): Boolean;
-begin
- Result := FreeImage_GetBackgroundColor(FDib, BkColor)
-end;
-
-function TFreeBitmap.GetHeight: Integer;
-begin
- Result := FreeImage_GetHeight(FDib)
-end;
-
-function TFreeBitmap.GetHistogram(Histo: PDWORD;
- Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
-begin
- if FDib <> nil then
- Result := FreeImage_GetHistogram(FDib, Histo, Channel)
- else
- Result := False
-end;
-
-function TFreeBitmap.GetHorizontalResolution: Double;
-begin
- Result := FreeImage_GetDotsPerMeterX(FDib) / 100
-end;
-
-function TFreeBitmap.GetImageSize: Cardinal;
-begin
- Result := FreeImage_GetDIBSize(FDib);
-end;
-
-function TFreeBitmap.GetImageType: FREE_IMAGE_TYPE;
-begin
- Result := FreeImage_GetImageType(FDib);
-end;
-
-function TFreeBitmap.GetInfo: PBitmapInfo;
-begin
- Result := FreeImage_GetInfo(FDib^)
-end;
-
-function TFreeBitmap.GetInfoHeader: PBITMAPINFOHEADER;
-begin
- Result := FreeImage_GetInfoHeader(FDib)
-end;
-
-function TFreeBitmap.GetLine: Integer;
-begin
- Result := FreeImage_GetLine(FDib)
-end;
-
-function TFreeBitmap.GetMetadata(Model: FREE_IMAGE_MDMODEL;
- const Key: string; var Tag: TFreeTag): Boolean;
-begin
- Result := FreeImage_GetMetaData(Model, FDib, PChar(Key), Tag.FTag);
-end;
-
-function TFreeBitmap.GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal;
-begin
- Result := FreeImage_GetMetadataCount(Model, FDib);
-end;
-
-function TFreeBitmap.GetPalette: PRGBQUAD;
-begin
- Result := FreeImage_GetPalette(FDib)
-end;
-
-function TFreeBitmap.GetPaletteSize: Integer;
-begin
- Result := FreeImage_GetColorsUsed(FDib) * SizeOf(RGBQUAD)
-end;
-
-function TFreeBitmap.GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
-begin
- Result := FreeImage_GetPixelColor(FDib, X, Y, Value)
-end;
-
-function TFreeBitmap.GetPixelIndex(X, Y: Cardinal;
- var Value: PByte): Boolean;
-begin
- Result := FreeImage_GetPixelIndex(FDib, X, Y, Value)
-end;
-
-function TFreeBitmap.GetScanLine(ScanLine: Integer): PByte;
-var
- H: Integer;
-begin
- H := FreeImage_GetHeight(FDib);
- if ScanLine < H then
- Result := FreeImage_GetScanLine(FDib, ScanLine)
- else
- Result := nil;
-end;
-
-function TFreeBitmap.GetScanWidth: Integer;
-begin
- Result := FreeImage_GetPitch(FDib)
-end;
-
-function TFreeBitmap.GetTransparencyCount: Cardinal;
-begin
- Result := FreeImage_GetTransparencyCount(FDib)
-end;
-
-function TFreeBitmap.GetTransparencyTable: PByte;
-begin
- Result := FreeImage_GetTransparencyTable(FDib)
-end;
-
-function TFreeBitmap.GetVerticalResolution: Double;
-begin
- Result := FreeImage_GetDotsPerMeterY(Fdib) / 100
-end;
-
-function TFreeBitmap.GetWidth: Integer;
-begin
- Result := FreeImage_GetWidth(FDib)
-end;
-
-function TFreeBitmap.HasFileBkColor: Boolean;
-begin
- Result := FreeImage_HasBackgroundColor(FDib)
-end;
-
-function TFreeBitmap.Invert: Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_Invert(FDib);
- Change;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.IsGrayScale: Boolean;
-begin
- Result := (FreeImage_GetBPP(FDib) = 8)
- and (FreeImage_GetColorType(FDib) = FIC_PALETTE);
-end;
-
-function TFreeBitmap.IsTransparent: Boolean;
-begin
- Result := FreeImage_IsTransparent(FDib);
-end;
-
-function TFreeBitmap.IsValid: Boolean;
-begin
- Result := FDib <> nil
-end;
-
-function TFreeBitmap.Load(const FileName: string; Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
-
- // check the file signature and get its format
- fif := FreeImage_GetFileType(PChar(Filename), 0);
- if fif = FIF_UNKNOWN then
- // no signature?
- // try to guess the file format from the file extention
- fif := FreeImage_GetFIFFromFilename(PChar(FileName));
-
- // check that the plugin has reading capabilities ...
- if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then
- begin
- // free the previous dib
- if FDib <> nil then
- FreeImage_Unload(dib);
-
- // load the file
- FDib := FreeImage_Load(fif, PChar(FileName), Flag);
-
- Change;
- Result := IsValid;
- end else
- Result := False;
-end;
-
-function TFreeBitmap.LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle;
- Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
- // check the file signature and get its format
- fif := FreeImage_GetFileTypeFromHandle(IO, Handle, 16);
- if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
- begin
- // free the previous dib
- if FDib <> nil then
- FreeImage_Unload(FDib);
-
- // load the file
- FDib := FreeImage_LoadFromHandle(fif, IO, Handle, Flag);
-
- Change;
- Result := IsValid;
- end else
- Result := False;
-end;
-
-function TFreeBitmap.LoadFromMemory(MemIO: TFreeMemoryIO;
- Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
-
- // check the file signature and get its format
- fif := MemIO.GetFileType;
- if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
- begin
- // free the previous dib
- if FDib <> nil then
- FreeImage_Unload(FDib);
-
- // load the file
- FDib := MemIO.Read(fif, Flag);
-
- Result := IsValid;
- Change;
- end else
- Result := False;
-end;
-
-function TFreeBitmap.LoadFromStream(Stream: TStream;
- Flag: Integer): Boolean;
-var
- MemIO: TFreeMemoryIO;
- Data: PByte;
- MemStream: TMemoryStream;
- Size: Cardinal;
-begin
- Size := Stream.Size;
-
- MemStream := TMemoryStream.Create;
- try
- MemStream.CopyFrom(Stream, Size);
- Data := MemStream.Memory;
-
- MemIO := TFreeMemoryIO.Create(Data, Size);
- try
- Result := LoadFromMemory(MemIO);
- finally
- MemIO.Free;
- end;
- finally
- MemStream.Free;
- end;
-end;
-
-function TFreeBitmap.LoadU(const FileName: WideString;
- Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
-
- // check the file signature and get its format
- fif := FreeImage_GetFileTypeU(PWideChar(Filename), 0);
- if fif = FIF_UNKNOWN then
- // no signature?
- // try to guess the file format from the file extention
- fif := FreeImage_GetFIFFromFilenameU(PWideChar(FileName));
-
- // check that the plugin has reading capabilities ...
- if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then
- begin
- // free the previous dib
- if FDib <> nil then
- FreeImage_Unload(dib);
-
- // load the file
- FDib := FreeImage_LoadU(fif, PWideChar(FileName), Flag);
-
- Change;
- Result := IsValid;
- end else
- Result := False;
-end;
-
-procedure TFreeBitmap.MakeThumbnail(const Width, Height: Integer;
- DestBitmap: TFreeBitmap);
-type
- PRGB24 = ^TRGB24;
- TRGB24 = packed record
- B: Byte;
- G: Byte;
- R: Byte;
- end;
-var
- x, y, ix, iy: integer;
- x1, x2, x3: integer;
-
- xscale, yscale: single;
- iRed, iGrn, iBlu, iRatio: Longword;
- p, c1, c2, c3, c4, c5: TRGB24;
- pt, pt1: PRGB24;
- iSrc, iDst, s1: integer;
- i, j, r, g, b, tmpY: integer;
-
- RowDest, RowSource, RowSourceStart: integer;
- w, h: Integer;
- dxmin, dymin: integer;
- ny1, ny2, ny3: integer;
- dx, dy: integer;
- lutX, lutY: array of integer;
-
- SrcBmp, DestBmp: PFIBITMAP;
-begin
- if not IsValid then Exit;
-
- if (GetWidth <= ThumbSize) and (GetHeight <= ThumbSize) then
- begin
- DestBitmap.Assign(Self);
- Exit;
- end;
-
- w := Width;
- h := Height;
-
- // prepare bitmaps
- if GetBitsPerPixel <> 24 then
- SrcBmp := FreeImage_ConvertTo24Bits(FDib)
- else
- SrcBmp := FDib;
- DestBmp := FreeImage_Allocate(w, h, 24);
- Assert(DestBmp <> nil, 'TFreeBitmap.MakeThumbnail error');
-
-{ iDst := (w * 24 + 31) and not 31;
- iDst := iDst div 8; //BytesPerScanline
- iSrc := (GetWidth * 24 + 31) and not 31;
- iSrc := iSrc div 8;
-}
- // BytesPerScanline
- iDst := FreeImage_GetPitch(DestBmp);
- iSrc := FreeImage_GetPitch(SrcBmp);
-
- xscale := 1 / (w / FreeImage_GetWidth(SrcBmp));
- yscale := 1 / (h / FreeImage_GetHeight(SrcBmp));
-
- // X lookup table
- SetLength(lutX, w);
- x1 := 0;
- x2 := trunc(xscale);
- for x := 0 to w - 1 do
- begin
- lutX[x] := x2 - x1;
- x1 := x2;
- x2 := trunc((x + 2) * xscale);
- end;
-
- // Y lookup table
- SetLength(lutY, h);
- x1 := 0;
- x2 := trunc(yscale);
- for x := 0 to h - 1 do
- begin
- lutY[x] := x2 - x1;
- x1 := x2;
- x2 := trunc((x + 2) * yscale);
- end;
-
- Dec(w);
- Dec(h);
- RowDest := integer(FreeImage_GetScanLine(DestBmp, 0));
- RowSourceStart := integer(FreeImage_GetScanLine(SrcBmp, 0));
- RowSource := RowSourceStart;
-
- for y := 0 to h do
- // resampling
- begin
- dy := lutY[y];
- x1 := 0;
- x3 := 0;
- for x := 0 to w do // loop through row
- begin
- dx:= lutX[x];
- iRed:= 0;
- iGrn:= 0;
- iBlu:= 0;
- RowSource := RowSourceStart;
- for iy := 1 to dy do
- begin
- pt := PRGB24(RowSource + x1);
- for ix := 1 to dx do
- begin
- iRed := iRed + pt.R;
- iGrn := iGrn + pt.G;
- iBlu := iBlu + pt.B;
- inc(pt);
- end;
- RowSource := RowSource + iSrc;
- end;
- iRatio := 65535 div (dx * dy);
- pt1 := PRGB24(RowDest + x3);
- pt1.R := (iRed * iRatio) shr 16;
- pt1.G := (iGrn * iRatio) shr 16;
- pt1.B := (iBlu * iRatio) shr 16;
- x1 := x1 + 3 * dx;
- inc(x3,3);
- end;
- RowDest := RowDest + iDst;
- RowSourceStart := RowSource;
- end; // resampling
-
- if FreeImage_GetHeight(DestBmp) >= 3 then
- // Sharpening...
- begin
- s1 := integer(FreeImage_GetScanLine(DestBmp, 0));
- iDst := integer(FreeImage_GetScanLine(DestBmp, 1)) - s1;
- ny1 := Integer(s1);
- ny2 := ny1 + iDst;
- ny3 := ny2 + iDst;
- for y := 1 to FreeImage_GetHeight(DestBmp) - 2 do
- begin
- for x := 0 to FreeImage_GetWidth(DestBmp) - 3 do
- begin
- x1 := x * 3;
- x2 := x1 + 3;
- x3 := x1 + 6;
-
- c1 := pRGB24(ny1 + x1)^;
- c2 := pRGB24(ny1 + x3)^;
- c3 := pRGB24(ny2 + x2)^;
- c4 := pRGB24(ny3 + x1)^;
- c5 := pRGB24(ny3 + x3)^;
-
- r := (c1.R + c2.R + (c3.R * -12) + c4.R + c5.R) div -8;
- g := (c1.G + c2.G + (c3.G * -12) + c4.G + c5.G) div -8;
- b := (c1.B + c2.B + (c3.B * -12) + c4.B + c5.B) div -8;
-
- if r < 0 then r := 0 else if r > 255 then r := 255;
- if g < 0 then g := 0 else if g > 255 then g := 255;
- if b < 0 then b := 0 else if b > 255 then b := 255;
-
- pt1 := pRGB24(ny2 + x2);
- pt1.R := r;
- pt1.G := g;
- pt1.B := b;
- end;
- inc(ny1, iDst);
- inc(ny2, iDst);
- inc(ny3, iDst);
- end;
- end; // sharpening
-
- if SrcBmp <> FDib then
- FreeImage_Unload(SrcBmp);
- DestBitmap.Replace(DestBmp);
-end;
-
-function TFreeBitmap.PasteSubImage(Src: TFreeBitmap; Left, Top,
- Alpha: Integer): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_Paste(FDib, Src.Dib, Left, Top, Alpha);
- Change;
- end else
- Result := False;
-end;
-
-function TFreeBitmap.Replace(NewDib: PFIBITMAP): Boolean;
-begin
- Result := False;
- if NewDib = nil then Exit;
-
- if not DoChanging(FDib, NewDib) and IsValid then
- FreeImage_Unload(FDib);
-
- FDib := NewDib;
- Result := True;
- Change;
-end;
-
-function TFreeBitmap.Rescale(NewWidth, NewHeight: Integer;
- Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap): Boolean;
-var
- Bpp: Integer;
- DstDib: PFIBITMAP;
-begin
- Result := False;
-
- if FDib <> nil then
- begin
- Bpp := FreeImage_GetBPP(FDib);
-
- if Bpp < 8 then
- if not ConvertToGrayscale then Exit
- else
- if Bpp = 16 then
- // convert to 24-bit
- if not ConvertTo24Bits then Exit;
-
- // perform upsampling / downsampling
- DstDib := FreeImage_Rescale(FDib, NewWidth, NewHeight, Filter);
- if Dest = nil then
- Result := Replace(DstDib)
- else
- Result := Dest.Replace(DstDib)
- end
-end;
-
-function TFreeBitmap.Rotate(Angle: Double): Boolean;
-var
- Bpp: Integer;
- Rotated: PFIBITMAP;
-begin
- Result := False;
- if IsValid then
- begin
- Bpp := FreeImage_GetBPP(FDib);
- if Bpp in [1, 8, 24, 32] then
- begin
- Rotated := FreeImage_RotateClassic(FDib, Angle);
- Result := Replace(Rotated);
- end
- end;
-end;
-
-function TFreeBitmap.RotateEx(Angle, XShift, YShift, XOrigin,
- YOrigin: Double; UseMask: Boolean): Boolean;
-var
- Rotated: PFIBITMAP;
-begin
- Result := False;
- if FDib <> nil then
- begin
- if FreeImage_GetBPP(FDib) >= 8 then
- begin
- Rotated := FreeImage_RotateEx(FDib, Angle, XShift, YShift, XOrigin, YOrigin, UseMask);
- Result := Replace(Rotated);
- end
- end;
-end;
-
-function TFreeBitmap.Save(const FileName: string; Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
- Result := False;
-
- // try to guess the file format from the file extension
- fif := FreeImage_GetFIFFromFilename(PChar(Filename));
- if CanSave(fif) then
- Result := FreeImage_Save(fif, FDib, PChar(FileName), Flag);
-end;
-
-function TFreeBitmap.SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO;
- Handle: fi_handle; Flag: Integer): Boolean;
-begin
- Result := False;
- if CanSave(fif) then
- Result := FreeImage_SaveToHandle(fif, FDib, IO, Handle, Flag)
-end;
-
-function TFreeBitmap.SaveToMemory(fif: FREE_IMAGE_FORMAT;
- MemIO: TFreeMemoryIO; Flag: Integer): Boolean;
-begin
- Result := False;
-
- if CanSave(fif) then
- Result := MemIO.Write(fif, FDib, Flag)
-end;
-
-function TFreeBitmap.SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream;
- Flag: Integer): Boolean;
-var
- MemIO: TFreeMemoryIO;
- Data: PByte;
- Size: Cardinal;
-begin
- MemIO := TFreeMemoryIO.Create;
- try
- Result := SaveToMemory(fif, MemIO, Flag);
- if Result then
- begin
- MemIO.Acquire(Data, Size);
- Stream.WriteBuffer(Data^, Size);
- end;
- finally
- MemIO.Free;
- end;
-end;
-
-function TFreeBitmap.SaveU(const FileName: WideString;
- Flag: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
- Result := False;
-
- // try to guess the file format from the file extension
- fif := FreeImage_GetFIFFromFilenameU(PWideChar(Filename));
- if CanSave(fif) then
- Result := FreeImage_SaveU(fif, FDib, PWideChar(FileName), Flag);
-end;
-
-function TFreeBitmap.SetChannel(Bitmap: TFreeBitmap;
- Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
-begin
- if FDib <> nil then
- begin
- Result := FreeImage_SetChannel(FDib, Bitmap.FDib, Channel);
- Change;
- end
- else
- Result := False
-end;
-
-procedure TFreeBitmap.SetDib(Value: PFIBITMAP);
-begin
- Replace(Value);
-end;
-
-function TFreeBitmap.SetFileBkColor(BkColor: PRGBQuad): Boolean;
-begin
- Result := FreeImage_SetBackgroundColor(FDib, BkColor);
- Change;
-end;
-
-procedure TFreeBitmap.SetHorizontalResolution(Value: Double);
-begin
- if IsValid then
- begin
- FreeImage_SetDotsPerMeterX(FDib, Trunc(Value * 100 + 0.5));
- Change;
- end;
-end;
-
-function TFreeBitmap.SetMetadata(Model: FREE_IMAGE_MDMODEL;
- const Key: string; Tag: TFreeTag): Boolean;
-begin
- Result := FreeImage_SetMetadata(Model, FDib, PChar(Key), Tag.Tag);
-end;
-
-function TFreeBitmap.SetPixelColor(X, Y: Cardinal;
- Value: PRGBQUAD): Boolean;
-begin
- Result := FreeImage_SetPixelColor(FDib, X, Y, Value);
- Change;
-end;
-
-function TFreeBitmap.SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean;
-begin
- Result := FreeImage_SetPixelIndex(FDib, X, Y, Value);
- Change;
-end;
-
-function TFreeBitmap.SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height,
- Bpp: Integer; RedMask, GreenMask, BlueMask: Cardinal): Boolean;
-var
- Pal: PRGBQuad;
- I: Cardinal;
-begin
- Result := False;
-
- if FDib <> nil then
- FreeImage_Unload(FDib);
-
- FDib := FreeImage_Allocate(Width, Height, Bpp, RedMask, GreenMask, BlueMask);
- if FDib = nil then Exit;
-
- if ImageType = FIT_BITMAP then
- case Bpp of
- 1, 4, 8:
- begin
- Pal := FreeImage_GetPalette(FDib);
- for I := 0 to FreeImage_GetColorsUsed(FDib) - 1 do
- begin
- Pal.rgbBlue := I;
- Pal.rgbGreen := I;
- Pal.rgbRed := I;
- Inc(Pal, SizeOf(RGBQUAD));
- end;
- end;
- end;
-
- Result := True;
- Change;
-end;
-
-procedure TFreeBitmap.SetTransparencyTable(Table: PByte; Count: Integer);
-begin
- FreeImage_SetTransparencyTable(FDib, Table, Count);
- Change;
-end;
-
-procedure TFreeBitmap.SetVerticalResolution(Value: Double);
-begin
- if IsValid then
- begin
- FreeImage_SetDotsPerMeterY(FDib, Trunc(Value * 100 + 0.5));
- Change;
- end;
-end;
-
-function TFreeBitmap.SplitChannels(RedChannel, GreenChannel,
- BlueChannel: TFreeBitmap): Boolean;
-begin
- if FDib <> nil then
- begin
- RedChannel.FDib := FreeImage_GetChannel(FDib, FICC_RED);
- GreenChannel.FDib := FreeImage_GetChannel(FDib, FICC_GREEN);
- BlueChannel.FDib := FreeImage_GetChannel(FDib, FICC_BLUE);
- Result := RedChannel.IsValid and GreenChannel.IsValid and BlueChannel.IsValid;
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.Threshold(T: Byte): Boolean;
-var
- dib1: PFIBITMAP;
-begin
- if FDib <> nil then
- begin
- dib1 := FreeImage_Threshold(FDib, T);
- Result := Replace(dib1);
- end
- else
- Result := False
-end;
-
-function TFreeBitmap.ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam,
- SecondParam: Double): Boolean;
-var
- NewDib: PFIBITMAP;
-begin
- Result := False;
- if not IsValid then Exit;
-
- NewDib := FreeImage_ToneMapping(Fdib, TMO, FirstParam, SecondParam);
- Result := Replace(NewDib);
-end;
-
-
-{ TFreeMultiBitmap }
-
-procedure TFreeMultiBitmap.AppendPage(Bitmap: TFreeBitmap);
-begin
- if IsValid then
- FreeImage_AppendPage(FMPage, Bitmap.FDib);
-end;
-
-function TFreeMultiBitmap.Close(Flags: Integer): Boolean;
-begin
- Result := FreeImage_CloseMultiBitmap(FMPage, Flags);
- FMPage := nil;
-end;
-
-constructor TFreeMultiBitmap.Create(KeepCacheInMemory: Boolean);
-begin
- inherited Create;
- FMemoryCache := KeepCacheInMemory;
-end;
-
-procedure TFreeMultiBitmap.DeletePage(Page: Integer);
-begin
- if IsValid then
- FreeImage_DeletePage(FMPage, Page);
-end;
-
-destructor TFreeMultiBitmap.Destroy;
-begin
- if FMPage <> nil then Close;
- inherited;
-end;
-
-function TFreeMultiBitmap.GetLockedPageNumbers(var Pages,
- Count: Integer): Boolean;
-begin
- Result := False;
- if not IsValid then Exit;
- Result := FreeImage_GetLockedPageNumbers(FMPage, Pages, Count)
-end;
-
-function TFreeMultiBitmap.GetPageCount: Integer;
-begin
- Result := 0;
- if IsValid then
- Result := FreeImage_GetPageCount(FMPage)
-end;
-
-procedure TFreeMultiBitmap.InsertPage(Page: Integer; Bitmap: TFreeBitmap);
-begin
- if IsValid then
- FreeImage_InsertPage(FMPage, Page, Bitmap.FDib);
-end;
-
-function TFreeMultiBitmap.IsValid: Boolean;
-begin
- Result := FMPage <> nil
-end;
-
-procedure TFreeMultiBitmap.LockPage(Page: Integer; DestBitmap: TFreeBitmap);
-begin
- if not IsValid then Exit;
-
- if Assigned(DestBitmap) then
- begin
- DestBitmap.Replace(FreeImage_LockPage(FMPage, Page));
- end;
-end;
-
-function TFreeMultiBitmap.MovePage(Target, Source: Integer): Boolean;
-begin
- Result := False;
- if not IsValid then Exit;
- Result := FreeImage_MovePage(FMPage, Target, Source);
-end;
-
-function TFreeMultiBitmap.Open(const FileName: string; CreateNew,
- ReadOnly: Boolean; Flags: Integer): Boolean;
-var
- fif: FREE_IMAGE_FORMAT;
-begin
- Result := False;
-
- // try to guess the file format from the filename
- fif := FreeImage_GetFIFFromFilename(PChar(FileName));
-
- // check for supported file types
- if (fif <> FIF_UNKNOWN) and (not fif in [FIF_TIFF, FIF_ICO, FIF_GIF]) then
- Exit;
-
- // open the stream
- FMPage := FreeImage_OpenMultiBitmap(fif, PChar(FileName), CreateNew, ReadOnly, FMemoryCache, Flags);
-
- Result := FMPage <> nil;
-end;
-
-procedure TFreeMultiBitmap.UnlockPage(Bitmap: TFreeBitmap;
- Changed: Boolean);
-begin
- if IsValid then
- begin
- FreeImage_UnlockPage(FMPage, Bitmap.FDib, Changed);
- // clear the image so that it becomes invalid.
- // don't use Bitmap.Clear method because it calls FreeImage_Unload
- // just clear the pointer
- Bitmap.FDib := nil;
- Bitmap.Change;
- end;
-end;
-
-{ TFreeMemoryIO }
-
-function TFreeMemoryIO.Acquire(var Data: PByte;
- var SizeInBytes: DWORD): Boolean;
-begin
- Result := FreeImage_AcquireMemory(FHMem, Data, SizeInBytes);
-end;
-
-constructor TFreeMemoryIO.Create(Data: PByte; SizeInBytes: DWORD);
-begin
- inherited Create;
- FHMem := FreeImage_OpenMemory(Data, SizeInBytes);
-end;
-
-destructor TFreeMemoryIO.Destroy;
-begin
- FreeImage_CloseMemory(FHMem);
- inherited;
-end;
-
-function TFreeMemoryIO.GetFileType: FREE_IMAGE_FORMAT;
-begin
- Result := FreeImage_GetFileTypeFromMemory(FHMem);
-end;
-
-function TFreeMemoryIO.IsValid: Boolean;
-begin
- Result := FHMem <> nil
-end;
-
-function TFreeMemoryIO.Read(fif: FREE_IMAGE_FORMAT;
- Flag: Integer): PFIBITMAP;
-begin
- Result := FreeImage_LoadFromMemory(fif, FHMem, Flag)
-end;
-
-function TFreeMemoryIO.Seek(Offset: Longint; Origin: Word): Boolean;
-begin
- Result := FreeImage_SeekMemory(FHMem, Offset, Origin)
-end;
-
-function TFreeMemoryIO.Tell: Longint;
-begin
- Result := FreeImage_TellMemory(FHMem)
-end;
-
-function TFreeMemoryIO.Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP;
- Flag: Integer): Boolean;
-begin
- Result := FreeImage_SaveToMemory(fif, dib, FHMem, Flag)
-end;
-
-{ TFreeTag }
-
-function TFreeTag.Clone: TFreeTag;
-var
- CloneTag: PFITAG;
-begin
- Result := nil;
- if not IsValid then Exit;
-
- CloneTag := FreeImage_CloneTag(FTag);
- Result := TFreeTag.Create(CloneTag);
-end;
-
-constructor TFreeTag.Create(ATag: PFITAG);
-begin
- inherited Create;
-
- if ATag <> nil then
- FTag := ATag
- else
- FTag := FreeImage_CreateTag;
-end;
-
-destructor TFreeTag.Destroy;
-begin
- if IsValid then
- FreeImage_DeleteTag(FTag);
-
- inherited;
-end;
-
-function TFreeTag.GetCount: Cardinal;
-begin
- Result := 0;
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagCount(FTag);
-end;
-
-function TFreeTag.GetDescription: string;
-begin
- Result := '';
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagDescription(FTag);
-end;
-
-function TFreeTag.GetID: Word;
-begin
- Result := 0;
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagID(FTag);
-end;
-
-function TFreeTag.GetKey: string;
-begin
- Result := '';
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagKey(FTag);
-end;
-
-function TFreeTag.GetLength: Cardinal;
-begin
- Result := 0;
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagLength(FTag);
-end;
-
-function TFreeTag.GetTagType: FREE_IMAGE_MDTYPE;
-begin
- Result := FIDT_NOTYPE;
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagType(FTag);
-end;
-
-function TFreeTag.GetValue: Pointer;
-begin
- Result := nil;
- if not IsValid then Exit;
-
- Result := FreeImage_GetTagValue(FTag);
-end;
-
-function TFreeTag.IsValid: Boolean;
-begin
- Result := FTag <> nil;
-end;
-
-procedure TFreeTag.SetCount(const Value: Cardinal);
-begin
- if IsValid then
- FreeImage_SetTagCount(FTag, Value);
-end;
-
-procedure TFreeTag.SetDescription(const Value: string);
-begin
- if IsValid then
- FreeImage_SetTagDescription(FTag, PChar(Value));
-end;
-
-procedure TFreeTag.SetID(const Value: Word);
-begin
- if IsValid then
- FreeImage_SetTagID(FTag, Value);
-end;
-
-procedure TFreeTag.SetKey(const Value: string);
-begin
- if IsValid then
- FreeImage_SetTagKey(FTag, PChar(Value));
-end;
-
-procedure TFreeTag.SetLength(const Value: Cardinal);
-begin
- if IsValid then
- FreeImage_SetTagLength(FTag, Value);
-end;
-
-procedure TFreeTag.SetTagType(const Value: FREE_IMAGE_MDTYPE);
-begin
- if IsValid then
- FreeImage_SetTagType(FTag, Value);
-end;
-
-procedure TFreeTag.SetValue(const Value: Pointer);
-begin
- if IsValid then
- FreeImage_SetTagValue(FTag, Value);
-end;
-
-function TFreeTag.ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar): string;
-begin
- Result := FreeImage_TagToString(Model, FTag, Make);
-end;
-
-end.
diff --git a/Game/Code/lib/FreeImage/FreeImage.pas b/Game/Code/lib/FreeImage/FreeImage.pas
deleted file mode 100644
index de05aca1..00000000
--- a/Game/Code/lib/FreeImage/FreeImage.pas
+++ /dev/null
@@ -1,773 +0,0 @@
-unit FreeImage;
-
-{$I switches.inc}
-
-
-// ==========================================================
-// Delphi wrapper for FreeImage 3
-//
-// Design and implementation by
-// - Simon Beavis
-// - Peter Byström
-// - Anatoliy Pulyaevskiy (xvel84@rambler.ru)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-interface
-
-uses
- {$IFDEF MSWINDOWS}
- Windows,
- {$ENDIF}
- ctypes;
-
-{$IFDEF FPC}
- {$MODE DELPHI}
- {$PACKENUM 4} (* use 4-byte enums *)
- {$PACKRECORDS C} (* C/C++-compatible record packing *)
-{$ELSE}
- {$MINENUMSIZE 4} (* use 4-byte enums *)
-{$ENDIF}
-
-{$IFDEF MSWINDOWS}
- {$DEFINE DLL_STDCALL}
-{$ELSE}
- {$DEFINE DLL_CDECL}
-{$ENDIF}
-
-const
-{$IFDEF MSWINDOWS}
- FIDLL = 'freeimage.dll';
-{$ENDIF}
-{$IFDEF LINUX}
- FIDLL = 'libfreeimage.so';
-{$ENDIF}
-{$IFDEF DARWIN}
- FIDLL = 'libfreeimage.dylib';
-{$ENDIF}
-
-{$IFNDEF MSWINDOWS}
-type
- // define portable types for 32-bit / 64-bit OS
- BOOL = cint32;
- BYTE = cuint8;
- WORD = cuint16;
- DWORD = cuint32;
- LONG = cint32;
-{$ENDIF}
-
-// --------------------------------------------------------------------------
-// Bitmap types -------------------------------------------------------------
-// --------------------------------------------------------------------------
-
-type
- FIBITMAP = record
- data : Pointer;
- end;
- PFIBITMAP = ^FIBITMAP;
-
- FIMULTIBITMAP = record
- data : Pointer;
- end;
- PFIMULTIBITMAP = ^FIMULTIBITMAP;
-
-// --------------------------------------------------------------------------
-// Indexes for byte arrays, masks and shifts for treating pixels as words ---
-// These coincide with the order of RGBQUAD and RGBTRIPLE -------------------
-// Little Endian (x86 / MS Windows, Linux) : BGR(A) order -------------------
-// --------------------------------------------------------------------------
-
-const
- FI_RGBA_RED = 2;
- FI_RGBA_GREEN = 1;
- FI_RGBA_BLUE = 0;
- FI_RGBA_ALPHA = 3;
- FI_RGBA_RED_MASK = $00FF0000;
- FI_RGBA_GREEN_MASK = $0000FF00;
- FI_RGBA_BLUE_MASK = $000000FF;
- FI_RGBA_ALPHA_MASK = $FF000000;
- FI_RGBA_RED_SHIFT = 16;
- FI_RGBA_GREEN_SHIFT = 8;
- FI_RGBA_BLUE_SHIFT = 0;
- FI_RGBA_ALPHA_SHIFT = 24;
-
-// --------------------------------------------------------------------------
-// The 16bit macros only include masks and shifts, --------------------------
-// since each color element is not byte aligned -----------------------------
-// --------------------------------------------------------------------------
-
-const
- FI16_555_RED_MASK = $7C00;
- FI16_555_GREEN_MASK = $03E0;
- FI16_555_BLUE_MASK = $001F;
- FI16_555_RED_SHIFT = 10;
- FI16_555_GREEN_SHIFT = 5;
- FI16_555_BLUE_SHIFT = 0;
- FI16_565_RED_MASK = $F800;
- FI16_565_GREEN_MASK = $07E0;
- FI16_565_BLUE_MASK = $001F;
- FI16_565_RED_SHIFT = 11;
- FI16_565_GREEN_SHIFT = 5;
- FI16_565_BLUE_SHIFT = 0;
-
-// --------------------------------------------------------------------------
-// ICC profile support ------------------------------------------------------
-// --------------------------------------------------------------------------
-
-const
- FIICC_DEFAULT = $0;
- FIICC_COLOR_IS_CMYK = $1;
-
-type
- FIICCPROFILE = record
- flags : WORD; // info flag
- size : DWORD; // profile's size measured in bytes
- data : Pointer; // points to a block of contiguous memory containing the profile
- end;
- PFIICCPROFILE = ^FIICCPROFILE;
-
-// --------------------------------------------------------------------------
-// Important enums ----------------------------------------------------------
-// --------------------------------------------------------------------------
-
-type
- FREE_IMAGE_FORMAT = cint;
- FREE_IMAGE_TYPE = cint;
- FREE_IMAGE_COLOR_TYPE = cint;
- FREE_IMAGE_QUANTIZE = cint;
- FREE_IMAGE_DITHER = cint;
- FREE_IMAGE_FILTER = cint;
- FREE_IMAGE_COLOR_CHANNEL = cint;
- FREE_IMAGE_MDTYPE = cint;
- FREE_IMAGE_MDMODEL = cint;
- FREE_IMAGE_JPEG_OPERATION = cint;
- FREE_IMAGE_TMO = cint;
-
-const
- // I/O image format identifiers.
- FIF_UNKNOWN = FREE_IMAGE_FORMAT(-1);
- FIF_BMP = FREE_IMAGE_FORMAT(0);
- FIF_ICO = FREE_IMAGE_FORMAT(1);
- FIF_JPEG = FREE_IMAGE_FORMAT(2);
- FIF_JNG = FREE_IMAGE_FORMAT(3);
- FIF_KOALA = FREE_IMAGE_FORMAT(4);
- FIF_LBM = FREE_IMAGE_FORMAT(5);
- FIF_IFF = FIF_LBM;
- FIF_MNG = FREE_IMAGE_FORMAT(6);
- FIF_PBM = FREE_IMAGE_FORMAT(7);
- FIF_PBMRAW = FREE_IMAGE_FORMAT(8);
- FIF_PCD = FREE_IMAGE_FORMAT(9);
- FIF_PCX = FREE_IMAGE_FORMAT(10);
- FIF_PGM = FREE_IMAGE_FORMAT(11);
- FIF_PGMRAW = FREE_IMAGE_FORMAT(12);
- FIF_PNG = FREE_IMAGE_FORMAT(13);
- FIF_PPM = FREE_IMAGE_FORMAT(14);
- FIF_PPMRAW = FREE_IMAGE_FORMAT(15);
- FIF_RAS = FREE_IMAGE_FORMAT(16);
- FIF_TARGA = FREE_IMAGE_FORMAT(17);
- FIF_TIFF = FREE_IMAGE_FORMAT(18);
- FIF_WBMP = FREE_IMAGE_FORMAT(19);
- FIF_PSD = FREE_IMAGE_FORMAT(20);
- FIF_CUT = FREE_IMAGE_FORMAT(21);
- FIF_XBM = FREE_IMAGE_FORMAT(22);
- FIF_XPM = FREE_IMAGE_FORMAT(23);
- FIF_DDS = FREE_IMAGE_FORMAT(24);
- FIF_GIF = FREE_IMAGE_FORMAT(25);
- FIF_HDR = FREE_IMAGE_FORMAT(26);
- FIF_FAXG3 = FREE_IMAGE_FORMAT(27);
- FIF_SGI = FREE_IMAGE_FORMAT(28);
-
- // Image type used in FreeImage.
- FIT_UNKNOWN = FREE_IMAGE_TYPE(0); // unknown type
- FIT_BITMAP = FREE_IMAGE_TYPE(1); // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
- FIT_UINT16 = FREE_IMAGE_TYPE(2); // array of unsigned short: unsigned 16-bit
- FIT_INT16 = FREE_IMAGE_TYPE(3); // array of short: signed 16-bit
- FIT_UINT32 = FREE_IMAGE_TYPE(4); // array of unsigned long: unsigned 32-bit
- FIT_INT32 = FREE_IMAGE_TYPE(5); // array of long: signed 32-bit
- FIT_FLOAT = FREE_IMAGE_TYPE(6); // array of float: 32-bit IEEE floating point
- FIT_DOUBLE = FREE_IMAGE_TYPE(7); // array of double: 64-bit IEEE floating point
- FIT_COMPLEX = FREE_IMAGE_TYPE(8); // array of FICOMPLEX: 2 x 64-bit IEEE floating point
- FIT_RGB16 = FREE_IMAGE_TYPE(9); // 48-bit RGB image: 3 x 16-bit
- FIT_RGBA16 = FREE_IMAGE_TYPE(10); // 64-bit RGBA image: 4 x 16-bit
- FIT_RGBF = FREE_IMAGE_TYPE(11); // 96-bit RGB float image: 3 x 32-bit IEEE floating point
- FIT_RGBAF = FREE_IMAGE_TYPE(12); // 128-bit RGBA float image: 4 x 32-bit IEEE floating point
-
- // Image color type used in FreeImage.
- FIC_MINISWHITE = FREE_IMAGE_COLOR_TYPE(0); // min value is white
- FIC_MINISBLACK = FREE_IMAGE_COLOR_TYPE(1); // min value is black
- FIC_RGB = FREE_IMAGE_COLOR_TYPE(2); // RGB color model
- FIC_PALETTE = FREE_IMAGE_COLOR_TYPE(3); // color map indexed
- FIC_RGBALPHA = FREE_IMAGE_COLOR_TYPE(4); // RGB color model with alpha channel
- FIC_CMYK = FREE_IMAGE_COLOR_TYPE(5); // CMYK color model
-
- // Color quantization algorithms. Constants used in FreeImage_ColorQuantize.
- FIQ_WUQUANT = FREE_IMAGE_QUANTIZE(0); // Xiaolin Wu color quantization algorithm
- FIQ_NNQUANT = FREE_IMAGE_QUANTIZE(1); // NeuQuant neural-net quantization algorithm by Anthony Dekker
-
- // Dithering algorithms. Constants used FreeImage_Dither.
- FID_FS = FREE_IMAGE_DITHER(0); // Floyd & Steinberg error diffusion
- FID_BAYER4x4 = FREE_IMAGE_DITHER(1); // Bayer ordered dispersed dot dithering (order 2 dithering matrix)
- FID_BAYER8x8 = FREE_IMAGE_DITHER(2); // Bayer ordered dispersed dot dithering (order 3 dithering matrix)
- FID_CLUSTER6x6 = FREE_IMAGE_DITHER(3); // Ordered clustered dot dithering (order 3 - 6x6 matrix)
- FID_CLUSTER8x8 = FREE_IMAGE_DITHER(4); // Ordered clustered dot dithering (order 4 - 8x8 matrix)
- FID_CLUSTER16x16 = FREE_IMAGE_DITHER(5); // Ordered clustered dot dithering (order 8 - 16x16 matrix)
-
- // Lossless JPEG transformations Constants used in FreeImage_JPEGTransform
- FIJPEG_OP_NONE = FREE_IMAGE_JPEG_OPERATION(0); // no transformation
- FIJPEG_OP_FLIP_H = FREE_IMAGE_JPEG_OPERATION(1); // horizontal flip
- FIJPEG_OP_FLIP_V = FREE_IMAGE_JPEG_OPERATION(2); // vertical flip
- FIJPEG_OP_TRANSPOSE = FREE_IMAGE_JPEG_OPERATION(3); // transpose across UL-to-LR axis
- FIJPEG_OP_TRANSVERSE = FREE_IMAGE_JPEG_OPERATION(4); // transpose across UR-to-LL axis
- FIJPEG_OP_ROTATE_90 = FREE_IMAGE_JPEG_OPERATION(5); // 90-degree clockwise rotation
- FIJPEG_OP_ROTATE_180 = FREE_IMAGE_JPEG_OPERATION(6); // 180-degree rotation
- FIJPEG_OP_ROTATE_270 = FREE_IMAGE_JPEG_OPERATION(7); // 270-degree clockwise (or 90 ccw)
-
- // Tone mapping operators. Constants used in FreeImage_ToneMapping.
- FITMO_DRAGO03 = FREE_IMAGE_TMO(0); // Adaptive logarithmic mapping (F. Drago, 2003)
- FITMO_REINHARD05 = FREE_IMAGE_TMO(1); // Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005)
-
- // Upsampling / downsampling filters. Constants used in FreeImage_Rescale.
- FILTER_BOX = FREE_IMAGE_FILTER(0); // Box, pulse, Fourier window, 1st order (constant) b-spline
- FILTER_BICUBIC = FREE_IMAGE_FILTER(1); // Mitchell & Netravali's two-param cubic filter
- FILTER_BILINEAR = FREE_IMAGE_FILTER(2); // Bilinear filter
- FILTER_BSPLINE = FREE_IMAGE_FILTER(3); // 4th order (cubic) b-spline
- FILTER_CATMULLROM = FREE_IMAGE_FILTER(4); // Catmull-Rom spline, Overhauser spline
- FILTER_LANCZOS3 = FREE_IMAGE_FILTER(5); // Lanczos3 filter
-
- // Color channels. Constants used in color manipulation routines.
- FICC_RGB = FREE_IMAGE_COLOR_CHANNEL(0); // Use red, green and blue channels
- FICC_RED = FREE_IMAGE_COLOR_CHANNEL(1); // Use red channel
- FICC_GREEN = FREE_IMAGE_COLOR_CHANNEL(2); // Use green channel
- FICC_BLUE = FREE_IMAGE_COLOR_CHANNEL(3); // Use blue channel
- FICC_ALPHA = FREE_IMAGE_COLOR_CHANNEL(4); // Use alpha channel
- FICC_BLACK = FREE_IMAGE_COLOR_CHANNEL(5); // Use black channel
- FICC_REAL = FREE_IMAGE_COLOR_CHANNEL(6); // Complex images: use real part
- FICC_IMAG = FREE_IMAGE_COLOR_CHANNEL(7); // Complex images: use imaginary part
- FICC_MAG = FREE_IMAGE_COLOR_CHANNEL(8); // Complex images: use magnitude
- FICC_PHASE = FREE_IMAGE_COLOR_CHANNEL(9); // Complex images: use phase
-
- // Tag data type information (based on TIFF specifications)
- FIDT_NOTYPE = FREE_IMAGE_MDTYPE(0); // placeholder
- FIDT_BYTE = FREE_IMAGE_MDTYPE(1); // 8-bit unsigned integer
- FIDT_ASCII = FREE_IMAGE_MDTYPE(2); // 8-bit bytes w/ last byte null
- FIDT_SHORT = FREE_IMAGE_MDTYPE(3); // 16-bit unsigned integer
- FIDT_LONG = FREE_IMAGE_MDTYPE(4); // 32-bit unsigned integer
- FIDT_RATIONAL = FREE_IMAGE_MDTYPE(5); // 64-bit unsigned fraction
- FIDT_SBYTE = FREE_IMAGE_MDTYPE(6); // 8-bit signed integer
- FIDT_UNDEFINED = FREE_IMAGE_MDTYPE(7); // 8-bit untyped data
- FIDT_SSHORT = FREE_IMAGE_MDTYPE(8); // 16-bit signed integer
- FIDT_SLONG = FREE_IMAGE_MDTYPE(9); // 32-bit signed integer
- FIDT_SRATIONAL = FREE_IMAGE_MDTYPE(10); // 64-bit signed fraction
- FIDT_FLOAT = FREE_IMAGE_MDTYPE(11); // 32-bit IEEE floating point
- FIDT_DOUBLE = FREE_IMAGE_MDTYPE(12); // 64-bit IEEE floating point
- FIDT_IFD = FREE_IMAGE_MDTYPE(13); // 32-bit unsigned integer (offset)
- FIDT_PALETTE = FREE_IMAGE_MDTYPE(14); // 32-bit RGBQUAD
-
- // Metadata models supported by FreeImage
- FIMD_NODATA = FREE_IMAGE_MDMODEL(-1);
- FIMD_COMMENTS = FREE_IMAGE_MDMODEL(0); // single comment or keywords
- FIMD_EXIF_MAIN = FREE_IMAGE_MDMODEL(1); // Exif-TIFF metadata
- FIMD_EXIF_EXIF = FREE_IMAGE_MDMODEL(2); // Exif-specific metadata
- FIMD_EXIF_GPS = FREE_IMAGE_MDMODEL(3); // Exif GPS metadata
- FIMD_EXIF_MAKERNOTE = FREE_IMAGE_MDMODEL(4); // Exif maker note metadata
- FIMD_EXIF_INTEROP = FREE_IMAGE_MDMODEL(5); // Exif interoperability metadata
- FIMD_IPTC = FREE_IMAGE_MDMODEL(6); // IPTC/NAA metadata
- FIMD_XMP = FREE_IMAGE_MDMODEL(7); // Abobe XMP metadata
- FIMD_GEOTIFF = FREE_IMAGE_MDMODEL(8); // GeoTIFF metadata (to be implemented)
- FIMD_ANIMATION = FREE_IMAGE_MDMODEL(9); // Animation metadata
- FIMD_CUSTOM = FREE_IMAGE_MDMODEL(10); // Used to attach other metadata types to a dib
-
-//{$endif}
-
-type
- // Handle to a metadata model
- FIMETADATA = record
- data: Pointer;
- end;
- PFIMETADATA = ^FIMETADATA;
-
- // Handle to a metadata tag
- FITAG = record
- data: Pointer;
- end;
- PFITAG = ^FITAG;
-
-// --------------------------------------------------------------------------
-// File IO routines ---------------------------------------------------------
-// --------------------------------------------------------------------------
-
-type
- FI_Handle = Pointer;
-
- FI_ReadProc = function(buffer : pointer; size : cuint; count : cuint; handle : fi_handle) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_WriteProc = function(buffer : pointer; size, count : cuint; handle : FI_Handle) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_SeekProc = function(handle : fi_handle; offset : clong; origin : cint) : cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_TellProc = function(handle : fi_handle) : clong; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
-
- FreeImageIO = packed record
- read_proc : FI_ReadProc; // pointer to the function used to read data
- write_proc: FI_WriteProc; // pointer to the function used to write data
- seek_proc : FI_SeekProc; // pointer to the function used to seek
- tell_proc : FI_TellProc; // pointer to the function used to aquire the current position
- end;
- PFreeImageIO = ^FreeImageIO;
-
- // Handle to a memory I/O stream
- FIMEMORY = record
- data: Pointer;
- end;
- PFIMEMORY = ^FIMEMORY;
-
-const
- // constants used in FreeImage_Seek for Origin parameter
- SEEK_SET = 0;
- SEEK_CUR = 1;
- SEEK_END = 2;
-
-// --------------------------------------------------------------------------
-// Plugin routines ----------------------------------------------------------
-// --------------------------------------------------------------------------
-
-type
- PPluginStruct = ^PluginStruct;
-
- FI_InitProc = procedure(Plugin: PPluginStruct; Format_ID: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_FormatProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_DescriptionProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_ExtensionListProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_RegExprProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_OpenProc = function(IO: PFreeImageIO; Handle: FI_Handle; Read: BOOL): Pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_CloseProc = procedure(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_PageCountProc = function(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_PageCapabilityProc = function(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_LoadProc = function(IO: PFreeImageIO; Handle: FI_Handle; Page, Flags: cint; data: pointer): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_SaveProc = function(IO: PFreeImageIO; Dib: PFIBITMAP; Handle: FI_Handle; Page, Flags: cint; Data: Pointer): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_ValidateProc = function(IO: PFreeImageIO; Handle: FI_Handle): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_MimeProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_SupportsExportBPPProc = function(Bpp: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_SupportsExportTypeProc = function(AType: FREE_IMAGE_TYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
- FI_SupportsICCProfilesProc = function: BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
-
- PluginStruct = record
- format_proc: FI_FormatProc;
- description_proc: FI_DescriptionProc;
- extension_proc: FI_ExtensionListProc;
- regexpr_proc: FI_RegExprProc;
- open_proc: FI_OpenProc;
- close_proc: FI_CloseProc;
- pagecount_proc: FI_PageCountProc;
- pagecapability_proc: FI_PageCapabilityProc;
- load_proc: FI_LoadProc;
- save_proc: FI_SaveProc;
- validate_proc: FI_ValidateProc;
- mime_proc: FI_MimeProc;
- supports_export_bpp_proc: FI_SupportsExportBPPProc;
- supports_export_type_proc: FI_SupportsExportTypeProc;
- supports_icc_profiles_proc: FI_SupportsICCProfilesProc;
- end;
-
-// --------------------------------------------------------------------------
-// Load/Save flag constants -------------------------------------------------
-// --------------------------------------------------------------------------
-
-const
- BMP_DEFAULT = 0;
- BMP_SAVE_RLE = 1;
- CUT_DEFAULT = 0;
- DDS_DEFAULT = 0;
- FAXG3_DEFAULT = 0;
- GIF_DEFAULT = 0;
- ICO_DEFAULT = 0;
- ICO_MAKEALPHA = 0; // convert to 32bpp and create an alpha channel from the AND-mask when loading
- IFF_DEFAULT = 0;
- JPEG_DEFAULT = 0;
- JPEG_FAST = 1;
- JPEG_ACCURATE = 2;
- JPEG_QUALITYSUPERB = $0080;
- JPEG_QUALITYGOOD = $0100;
- JPEG_QUALITYNORMAL = $0200;
- JPEG_QUALITYAVERAGE = $0400;
- JPEG_QUALITYBAD = $0800;
- JPEG_CMYK = $1000; // load separated CMYK "as is" (use | to combine with other flags)
- KOALA_DEFAULT = 0;
- LBM_DEFAULT = 0;
- MNG_DEFAULT = 0;
- PCD_DEFAULT = 0;
- PCD_BASE = 1; // load the bitmap sized 768 x 512
- PCD_BASEDIV4 = 2; // load the bitmap sized 384 x 256
- PCD_BASEDIV16 = 3; // load the bitmap sized 192 x 128
- PCX_DEFAULT = 0;
- PNG_DEFAULT = 0;
- PNG_IGNOREGAMMA = 1; // avoid gamma correction
- PNM_DEFAULT = 0;
- PNM_SAVE_RAW = 0; // If set the writer saves in RAW format (i.e. P4, P5 or P6)
- PNM_SAVE_ASCII = 1; // If set the writer saves in ASCII format (i.e. P1, P2 or P3)
- PSD_DEFAULT = 0;
- RAS_DEFAULT = 0;
- SGI_DEFAULT = 0;
- TARGA_DEFAULT = 0;
- TARGA_LOAD_RGB888 = 1; // If set the loader converts RGB555 and ARGB8888 -> RGB888.
- TIFF_DEFAULT = 0;
- TIFF_CMYK = $0001; // reads/stores tags for separated CMYK (use | to combine with compression flags)
- TIFF_PACKBITS = $0100; // save using PACKBITS compression
- TIFF_DEFLATE = $0200; // save using DEFLATE compression
- TIFF_ADOBE_DEFLATE = $0400; // save using ADOBE DEFLATE compression
- TIFF_NONE = $0800; // save without any compression
- TIFF_CCITTFAX = $1000; // save using CCITT Group 3 fax encoding
- TIFF_CCITTFAX4 = $2000; // save using CCITT Group 4 fax encoding
- TIFF_LZW = $4000; // save using LZW compression
- TIFF_JPEG = $8000; // save using JPEG compression
- WBMP_DEFAULT = 0;
- XBM_DEFAULT = 0;
- XPM_DEFAULT = 0;
-
-// --------------------------------------------------------------------------
-// Init/Error routines ------------------------------------------------------
-// --------------------------------------------------------------------------
-
-procedure FreeImage_Initialise(load_local_plugins_only : BOOL = False); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_DeInitialise; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Version routines ---------------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetVersion : PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetCopyrightMessage : PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Message output functions -------------------------------------------------
-// --------------------------------------------------------------------------
-
-procedure FreeImage_OutPutMessageProc(fif: cint; fmt: PChar); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-type FreeImage_OutputMessageFunction = function(fif: FREE_IMAGE_FORMAT; msg: PChar): pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
-procedure FreeImage_SetOutputMessage(omf: FreeImage_OutputMessageFunction); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Allocate/Unload routines -------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_Allocate(width, height, bpp: cint; red_mask: cuint = 0; green_mask: cuint = 0; blue_mask: cuint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_AllocateT(Atype: FREE_IMAGE_TYPE; Width, Height: cint; bpp: cint = 8; red_mask: cuint = 0; green_mask: cuint = 0; blue_mask: cuint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Clone(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_Unload(dib: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Load / Save routines -----------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_Load(fif: FREE_IMAGE_FORMAT; const filename: PChar; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LoadU(fif: FREE_IMAGE_FORMAT; const filename: PWideChar; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LoadFromHandle(fif: FREE_IMAGE_FORMAT; io: PFreeImageIO; handle: fi_handle; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Save(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; filename: PChar; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SaveU(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; const filename: PWideChar; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SaveToHandle(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; io : PFreeImageIO; handle : fi_handle; flags : cint = 0) : BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Memory I/O stream routines -----------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_OpenMemory(data: PByte = nil; size_in_bytes: DWORD = 0): PFIMEMORY; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_CloseMemory(stream: PFIMEMORY); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LoadFromMemory(fif: FREE_IMAGE_FORMAT; stream: PFIMEMORY; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SaveToMemory(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; stream: PFIMEMORY; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_TellMemory(stream: PFIMEMORY): clong; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SeekMemory(stream: PFIMEMORY; offset: clong; origin: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_AcquireMemory(stream: PFIMEMORY; var data: PByte; var size_in_bytes: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Plugin Interface ---------------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_RegisterLocalPlugin(proc_address: FI_InitProc; format, description, extension, regexpr: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_RegisterExternalPlugin(path, format, description, extension, regexpr: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFCount: cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_SetPluginEnabled(fif: FREE_IMAGE_FORMAT; enable: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_IsPluginEnabled(fif: FREE_IMAGE_FORMAT): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFFromFormat(const format: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFFromMime(const format: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFormatFromFIF(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFExtensionList(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFDescription(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFRegExpr(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFFromFilename(const fname: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFIFFromFilenameU(const fname:PWideChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FIFSupportsReading(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FIFSupportsWriting(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FIFSupportsExportBPP(fif: FREE_IMAGE_FORMAT; bpp: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FIFSupportsICCProfiles(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FIFSupportsExportType(fif: FREE_IMAGE_FORMAT; image_type: FREE_IMAGE_TYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Multipaging interface ----------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_OpenMultiBitmap(fif: FREE_IMAGE_FORMAT; filename: PChar; create_new, read_only, keep_cache_in_memory: BOOL; flags: cint = 0): PFIMULTIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_CloseMultiBitmap(bitmap: PFIMULTIBITMAP; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetPageCount(bitmap: PFIMULTIBITMAP): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_AppendPage(bitmap: PFIMULTIBITMAP; data: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_InsertPage(bitmap: PFIMULTIBITMAP; page: cint; data: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_DeletePage(bitmap: PFIMULTIBITMAP; page: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LockPage(bitmap: PFIMULTIBITMAP; page: cint): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_UnlockPage(bitmap: PFIMULTIBITMAP; page: PFIBITMAP; changed: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_MovePage(bitmap: PFIMULTIBITMAP; target, source: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetLockedPageNumbers(bitmap: PFIMULTIBITMAP; var pages: cint; var count : cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Filetype request routines ------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetFileType(const filename: PChar; size: cint): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFileTypeU(const filename: PWideChar; size: cint): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFileTypeFromHandle(io: PFreeImageIO; handle: FI_Handle; size: cint = 0): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetFileTypeFromMemory(stream: PFIMEMORY; size: cint = 0): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// ImageType request routine ------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetImageType(dib: PFIBITMAP): FREE_IMAGE_TYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// FreeImage helper routines ------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_IsLittleEndian: BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LookupX11Color(const szColor: PChar; var nRed, nGreen, nBlue: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_LookupSVGColor(const szColor: PChar; var nRed, nGreen, nBlue: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Pixels access routines ---------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetBits(dib: PFIBITMAP): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetScanLine(dib: PFIBITMAP; scanline: cint): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_GetPixelIndex(dib: PFIBITMAP; X, Y: cuint; Value: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetPixelColor(dib: PFIBITMAP; X, Y: cuint; Value: PRGBQuad): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetPixelIndex(dib: PFIBITMAP; X, Y: cuint; Value: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetPixelColor(dib: PFIBITMAP; X, Y: cuint; Value: PRGBQuad): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// DIB info routines --------------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetColorsUsed(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetBPP(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetWidth(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetHeight(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetLine(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetPitch(dib : PFIBITMAP) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetDIBSize(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetPalette(dib: PFIBITMAP): PRGBQUAD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_GetDotsPerMeterX(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetDotsPerMeterY(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_SetDotsPerMeterX(dib: PFIBITMAP; res: cuint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_SetDotsPerMeterY(dib: PFIBITMAP; res: cuint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_GetInfoHeader(dib: PFIBITMAP): PBITMAPINFOHEADER; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetInfo(var dib: FIBITMAP): PBITMAPINFO; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetColorType(dib: PFIBITMAP): FREE_IMAGE_COLOR_TYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_GetRedMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetGreenMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetBlueMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_GetTransparencyCount(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTransparencyTable(dib: PFIBITMAP): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_SetTransparent(dib: PFIBITMAP; enabled: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_SetTransparencyTable(dib: PFIBITMAP; table: PByte; count: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_IsTransparent(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_HasBackgroundColor(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetBackgroundColor(dib: PFIBITMAP; var bkcolor: PRGBQUAD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetBackgroundColor(dib: PFIBITMAP; bkcolor: PRGBQUAD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// ICC profile routines -----------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_GetICCProfile(var dib: FIBITMAP): PFIICCPROFILE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_CreateICCProfile(var dib: FIBITMAP; data: Pointer; size: clong): PFIICCPROFILE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_DestroyICCProfile(var dib : FIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Line conversion routines -------------------------------------------------
-// --------------------------------------------------------------------------
-
-procedure FreeImage_ConvertLine1To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine8To4(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQuad); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To4_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To4_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine24To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine32To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-procedure FreeImage_ConvertLine1To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine4To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To8_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To8_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine24To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine32To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-procedure FreeImage_ConvertLine1To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine4To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine8To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16_565_To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine24To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine32To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-procedure FreeImage_ConvertLine1To16_565(target, source : PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine4To16_565(target, source : PBYTE; width_in_pixels : cint; palette : PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine8To16_565(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16_555_To16_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine24To16_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine32To16_565(target, source : PBYTE; width_in_pixels : cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-procedure FreeImage_ConvertLine1To24(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine4To24(target, source : PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine8To24(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To24_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To24_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine32To24(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-procedure FreeImage_ConvertLine1To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine4To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine8To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To32_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine16To32_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertLine24To32(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Smart conversion routines ------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_ConvertTo4Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertTo8Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertToGreyscale(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertTo16Bits555(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertTo16Bits565(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertTo24Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertTo32Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ColorQuantize(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ColorQuantizeEx(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE = FIQ_WUQUANT; PaletteSize: cint = 256; ReserveSize: cint = 0; ReservePalette: PRGBQuad = nil): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Threshold(dib: PFIBITMAP; T: Byte): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Dither(dib: PFIBITMAP; algorithm: FREE_IMAGE_DITHER): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_ConvertFromRawBits(bits: PBYTE; width, height, pitch: cint; bpp, red_mask, green_mask, blue_mask: cuint; topdown: BOOL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_ConvertToRawBits(bits: PBYTE; dib: PFIBITMAP; pitch: cint; bpp, red_mask, green_mask, blue_mask: cuint; topdown: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_ConvertToRGBF(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_ConvertToStandardType(src: PFIBITMAP; scale_linear: BOOL = True): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ConvertToType(src: PFIBITMAP; dst_type: FREE_IMAGE_TYPE; scale_linear: BOOL = True): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// tone mapping operators
-function FreeImage_ToneMapping(dib: PFIBITMAP; tmo: FREE_IMAGE_TMO; first_param: cdouble = 0; second_param: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_TmoDrago03(src: PFIBITMAP; gamma: cdouble = 2.2; exposure: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_TmoReinhard05(src: PFIBITMAP; intensity: cdouble = 0; contrast: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// ZLib interface -----------------------------------------------------------
-// --------------------------------------------------------------------------
-
-function FreeImage_ZLibCompress(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ZLibUncompress(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_ZLibGZip(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ZLibGUnzip(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_ZLibCRC32(crc: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Metadata routines --------------------------------------------------------
-// --------------------------------------------------------------------------
-
-// tag creation / destruction
-function FreeImage_CreateTag: PFITAG; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_DeleteTag(tag: PFITAG); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_CloneTag(tag: PFITAG): PFITAG; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// tag getters and setters
-function FreeImage_GetTagKey(tag: PFITAG): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagDescription(tag: PFITAG): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagID(tag: PFITAG): Word; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagType(tag: PFITAG): FREE_IMAGE_MDTYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagCount(tag: PFITAG): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagLength(tag: PFITAG): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetTagValue(tag: PFITAG): Pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-function FreeImage_SetTagKey(tag: PFITAG; const key: PChar): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagDescription(tag: PFITAG; const description: PChar): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagID(tag: PFITAG; id: Word): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagType(tag: PFITAG; atype: FREE_IMAGE_MDTYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagCount(tag: PFITAG; count: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagLength(tag: PFITAG; length: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetTagValue(tag: PFITAG; const value: Pointer): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// iterator
-function FreeImage_FindFirstMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; var tag: PFITAG): PFIMETADATA; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FindNextMetadata(mdhandle: PFIMETADATA; var tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-procedure FreeImage_FindCloseMetadata(mdhandle: PFIMETADATA); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// metadata setter and getter
-function FreeImage_SetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; const key: PChar; tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; const key: PChar; var tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// helpers
-function FreeImage_GetMetadataCount(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// tag to C string conversion
-function FreeImage_TagToString(model: FREE_IMAGE_MDMODEL; tag: PFITAG; Make: PChar = nil): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// --------------------------------------------------------------------------
-// Image manipulation toolkit -----------------------------------------------
-// --------------------------------------------------------------------------
-
-// rotation and flipping
-function FreeImage_RotateClassic(dib: PFIBITMAP; angle: cdouble): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_RotateEx(dib: PFIBITMAP; angle, x_shift, y_shift, x_origin, y_origin: cdouble; use_mask: BOOL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FlipHorizontal(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_FlipVertical(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_JPEGTransform(const src_file: PChar; const dst_file: PChar; operation: FREE_IMAGE_JPEG_OPERATION; perfect: BOOL = False): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// upsampling / downsampling
-function FreeImage_Rescale(dib: PFIBITMAP; dst_width, dst_height: cint; filter: FREE_IMAGE_FILTER): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_MakeThumbnail(dib: PFIBITMAP; max_pixel_size: cint; convert:BOOL = TRUE): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// color manipulation routines (point operations)
-function FreeImage_AdjustCurve(dib: PFIBITMAP; LUT: PBYTE; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_AdjustGamma(dib: PFIBITMAP; gamma: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_AdjustBrightness(dib: PFIBITMAP; percentage: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_AdjustContrast(dib: PFIBITMAP; percentage: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Invert(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetHistogram(dib: PFIBITMAP; histo: PDWORD; channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// channel processing routines
-function FreeImage_GetChannel(dib: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetChannel(dib, dib8: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_GetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_SetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-// copy / paste / composite routines
-
-function FreeImage_Copy(dib: PFIBITMAP; left, top, right, bottom: cint): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Paste(dst, src: PFIBITMAP; left, top, alpha: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-function FreeImage_Composite(fg: PFIBITMAP; useFileBkg: BOOL = False; appBkColor: PRGBQUAD = nil; bg: PFIBITMAP = nil): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
-
-{$MINENUMSIZE 1}
-implementation
-
-end.
diff --git a/Game/Code/lib/JEDI-SDL/JEDI-SDL-README.txt b/Game/Code/lib/JEDI-SDL/JEDI-SDL-README.txt
deleted file mode 100644
index 8e0d25f9..00000000
--- a/Game/Code/lib/JEDI-SDL/JEDI-SDL-README.txt
+++ /dev/null
@@ -1,244 +0,0 @@
-This is the based on the SDL ( http://www.libsdl.org ) headers, and has been converted, comments and all, to the Pascal unit called sdl.pas.
-Other conversions that have also been done are SDL_Mixer.h, SDL_Net.h, SDL_Image.h, SDL_ttf, SMPEG.h, SDL_sound and the SFont library,
-which are all included in this distribution.
-
-It allows you to access all the functions within the SDL libraries under Windows, Linux and FreeBSD, so you can write cross-platform games or multimedia applications.
-
-Installation Instructions
--------------------------
-Windows - We now have a semi-automated setup under Windows ( thanks to David House and the Jedi JCL team ).
- Once you have extracted the zip file, simply double click on the "JEDISDLWin32Installer.exe" to have the correct paths added to your respective
- IDEs. All IDEs from Delphi 4 - 7 are supported and it also adds a link to the .CHM help file under the Tools menu.
-
-Linux - Alternatively if you use Linux or want to to manually install the paths, then make sure you read the "Getting Started.html" file ( ideal for those who are new to JEDI-SDL ) and is now included as a guide to help getting everything setup for smooth compilation.
-
-Also included is a guide of how to use Sourceforge using TortoiseCVS under Windows ( Linux guide is under development ).
-Both documents can be found in the "documentation" directory.
-
-
-Release History
----------------
-1.0 : Yeah!! The Official v1.0 Release of JEDI-SDL!!
- JEDI-SDL now updated to SDL v1.2.11, SDL_Image v1.2.5, SDL_Mixer v1.2.7, SDL_Net v1.2.6 & SDL_ttf v2.0.8
- Added Improved FreePascal, TMT Pascal and GnuPascal support as well as maintaining Delphi/Kylix support.
- Fixed Various bugs as pointed out on the JEDI-SDL mailing list.
- Added SDL_GL_STEREO, SDL_GL_MULTISAMPLEBUFFERS, SDL_GL_MULTISAMPLESAMPLES
-
-Now works on MacOS X and a MacOS X disk image is available for download.
-
-// DLL/Shared object functions
-function SDL_LoadObject( const sofile : PChar ) : Pointer;
-
-function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer;
-
-procedure SDL_UnloadObject( handle : Pointer );
-
-//Added function to create RWops from const memory: SDL_RWFromConstMem()
-function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops;
-
-//Added support for environment variables SDL_VIDEO_WINDOW_POS and SDL_VIDEO_CENTERED on Windows
-
- New Units :
- -----------
- sdl_cpuinfo.pas - ported SDL_cpuinfo.h so Now you can test for Specific CPU types.
- sdlinput.pas - Input wrapper class
- sdlwindow.pas - Window wrapper class
- sdltruetypefont.pas - True Type Font wrapper class
- tcputils.pas - SDL_Net utility functions
- sdlweb.pas - SDL_Net Web class
- sdlwebhttp.pas - SDL_Net http protocol wrapper class
- sdlwebftp.pas - SDL_Net ftp protocol wrapper class
-
- New 2D Demos :
- --------------
-
-
- New 3D Demos :
- --------------
-
-
- Other New Stuff :
- -----------------
-
-
-
-0.5 : The JEDI-SDL project is now also set up on Sourceforge ( http://sf.net/projects/jedi-sdl/ ) so the latest code is available from there.
- Improved FreePascal support has been added.
- Various bug fixes as pointed out on the JEDI-SDL mailing list.
- SDL_Mixer has been updated to version 1.2.1 and includes an Effects API.
- Demo directories are now split into 2D and 3D related sub-directories.
- There are now both Kylix ( K prefix ) and Delphi ( D prefix ) project groups for all the demos.
- They can be found in Demos and the 2D and 3D directories.
-
- New Units
- ---------
- SDLStreams.pas - Chris Bruner has created a wrapper that uses Streams to load BMPs
- SDLUtils.pas - Pascal only version of some Utility functions
- SDLi386Utils.pas - Intel Assembler versions of the SDLUtils.pas functions.
- SDL_ttf.pas - Port of the SDL True Type font support unit.
- SDL_Sound.pas - Port of the SDL Sound library ( untested ).
-
- New 2D Demos :
- --------------
- Pan and Zoom Demo - How to Pan and Zoom an SDL surface.
- Isometric Demo - I ported my old DelphiX isometric demo over to SDL.
- TestTimer demo - Shows hows how to use AddTimer and RemoveTimer.
- MpegPlayer - I have updated and improved Anders Ohlsson's CLX MPegPlayer and component and it now works
- and installs into D4, D5, D6, D7, K1, K2 & K3.
- Showfont - Demo to show how to us SDL_ttf.dll
- SmpegPlayer - is a console MPEG player that use smpeg and SDL_Mixer
-
- New 3D Demos :
- --------------
- DeathTruckTion 1.1 - A slightly updated version of this fully functional 3D network game.
- TerrainDemo - Terrain demo ported from the book "OpenGL Game programming" by Hawkins and Astle.
- TestGL - the standard SDL/OpenGL Test demo. Shows how to mix 2D and 3D rendering using OpenGL.
- glfont - Demo to show how to us SDL_ttf with OpenGL.
- Particle Engine - Ariel's OpenGL Particle Engine.
- Picking - Phil Freeman's Picking Demo
- Motion Blur - Phil Freeman's Motion Blur Demo
- Dynamic Light - Phil Freeman's Dynamic Light Demo
- Environment Map - Phil Freeman's Environment Map Demo
- GLMovie - is an MPEG Player that uses OpenGL to render the movie.
- NeHe - Quite a few more NeHe demos are now included.
-
- New Network Demos :
- -------------------
- There are now 3 SDL_Net Server demos and 4 SDL_Client demos as submitted by Dean Ellis.
-
-
-Beta 4 : The JEDI-SDL home page is now located @ http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME
- All Demos ( including OpenGL Demos ) now compile under both Kylix and Delphi.
- I have added quite a few more OpenGL examples, we are now up to Nehe tutorial 12.
- All OpenGL demos also show how to handle Window resizing.
- Included an OpenGL demo called Puntos by Gustavo Maximo.
- Ported Jan Horn's OpenGL MetaBalls and also SkyBox demo to SDL.
- Ported Ilkka Tuomioja's OpenGL Quake 2 Model Viewer/Animator to SDL.
- NOTE : All OpenGL demos require OpenGL12.pas which can be found at...
- http://www.lischke-online.de/Graphics.html#OpenGL12
- I also fixed a conversion bug to do with SDL_MustLock and also a conversion omission to do with various events.
- Fixed a conversion bug with SDL_CDOpen ( as suggested on the mailing list ).
- Added the GetPixel and PuxPixel functions to the SDLUtils.pas file.
- Jason Farmer has donated SFont, a simple, yet effective Font library he converted for JEDI-SDL.
- It contains 4 Demos show how to best use it.
- Added TUInt8Array and PUIntArray to SDL.pas after suggestions from Matthias Thoma and Eric Grange.
- In the file area of the JEDI-SDL mailing list ( http://groups.yahoo.com/group/JEDI-SDL/files/DTTSrc/ there
- is a fully functional 3D network game called DeathTruckTion v1.0 written by the TNTeam that makes use of
- JEDI-SDL and is just too big to include with this distribution but is well worth looking at as it works under Windows and Linux!
- Gustavo Maxima is working on translating the JEDI-SDL Documentation to Spanish and Portugese.
- The Mouse Demo has now been speeded up considerably and it is very responsive now.
- Dean Ellis will provide steps on how to compile the demos using the Free Pascal compiler.
- Jason Farmer and I are working on a series of Tutorials that should hopefully be out soon.
- David Aclan has donated a SMpeg component that should work under Kylix.
- Róbert Kisnémeth, has been hard at work, and has donated some new demos he has created with a SpriteEngine ( which he also donated ).
- He has also donated a couple of games called BlitzBomber and Oxygene ( which uses the SpriteEngine ) and added a couple of useful
- functions to SDLUtils.pas.
- The Functions added are SDL_FlipV, SDL_FlipH, SDL_NewPutPixel ( assembler version ), SDL_AddPixel, SDL_SubPixel, SDL_DrawLine, SDL_AddLine,
- SDL_SubLine, SDL_AddSurface, SDL_SubSurface, SDL_MonoSurface & SDL_TexturedSurface.
- He has also donated a Font Blitting class and demo called SDL_MonoFonts which supports alignment like Left, Right and Center.
- He and Thomas are also working on a GUI library.
- Jason Farmer has donated a set of Image Filtering functions which add quite a few interesting effects. Check the SDL_Filter sub-directory for more
- info.
- Christian Hackbart also donated an OpenGL BlockOut clone.
-
-
-Beta 3 : I have added conversions for SDL_env.h, SDL_Mixer.h and SDL_Net.h while Matthias Thoma has added conversions for SDL_Image.h and SMPEG.h.
- This version is also SDL version 1.2.0 compliant.
- This release also adds demos for the SDL_Image, SDL_Mixer and SDL_Net libraries.
- There are now also some OpenGL demos that make some use of SDL as well as a demo on how to use the Mouse with Clickable regions.
- A conversion bug, that was pointed out by Clem Vasseur, has also been fixed.
- There is now a mailing list that has been set up at http://groups.yahoo.com/group/JEDI-SDL/join/ so we can all learn from each other how to use
- these libraries.
- Demos have not been unified into single .dpr files for each demo, thus showing how you would write a crossplatform game using only 1 .dpr file.
- There is also a documentation directory that is currently in HTML format. All code examples in the documentation have been converted to Object
- Pascal but are untested.
- I Also fixed a few conversion bugs which I came across while converting the documentation.
-
-Beta 2 : I have added conversions for SDL_active.h, SDL_thread.h, SDL_mutex.h and
- SDL_error.h, Matthias Thoma has added Linux Support and JEDI compliancy so these
- units and examples are now x-platform and x-compiler compilable.
- I also added Tom Jones' SDLUtils.pas file;
- Matthias also cleaned up the 2 new demos and made them work on both Linux and
- Windows.
-
-Beta 1 : Initial Release;
-
-
-There are now 5 examples included with this JEDI-SDL distribution.
-1. Is the TestWin application, which is based on the testwin application that comes with the SDL SDK, only my version has a gui front end to the options available and has been compiled under Delphi 4.03. It should be compatible with Delphi 3.0 onwards ( though Delphi 2 compatibility has not been tested ).
-
-2. A Plasma example which was converted from one found on the Demos page of the SDL site.
-
-3. A Voxel terrain following demo, which was converted from one found on the Demos page of the SDL site. This one should be of interest to others as it shows how to handle keyboard events when using SDL.
-
-4. A Mouse handling demo that shows how to use transparency and clickable regions.
-
-5. A Space Invaders style game called Aliens which shows the use of SDL, SDL_Image and SDL_Mixer. This game shows how to handle sound, keyboards and some basic collision detection. It is a conversion of one found on the SDL Demos page.
-
-There are also 14 OpenGL demos that are based on the NeHe tutorials . The other 3 OpenGL demos are Jan Horns' OpenGL demo, A Quake 2 Model viewer that I ported and a Demo by Gustavo Maxima called Puntos.
-
-If writing your own, just make sure that the SDL.pas file is in your projects path for compiling and that the SDL.dll file is in your path when running the compiled app.
-
-Please test these units and report problems to the JEDI-SDL mailing list @ http://groups.yahoo.com/group/JEDI-SDL/ outlining steps under which the error occurred. If you convert any more demos please send them to me so that I can
-include them in the ditribution for others to learn from.
-
-Also if you are using these Units to write any games
-please let me know about it so that I can post the information to the http://www.DelphiGamer.com site.
-
-The plan is to have this unit JEDI certified at some point so that it can be included on the Delphi and Kylix CDs, so all feedback is greatly welcomed.
-
-Compilers supported Tested
-------------------- ------
-Delphi Yes
-Kylix Yes
-FreePascal Yes
-TMT Pascal compiler Not Yet.
-Virtual Pascal No
-Gnu Pascal No
-
-
-
-Credits
--------
-Matthias Thoma for is endless help with my conversion bugs.
-Jason Farmer for donating the SFont Font Library.
-Gustavo Maximo for the Puntos OpenGL Demo and work he is doing on the documentation
-Róbert Kisnémeth for his numerous contributions
-Chris Bruner for testing under Kylix
-August Logan Bear Jr. for testing under Kylix
-Dean Ellis for FreePascal Compiler compatability testing and SDL_Net demos and testing
-David House for Windows Insaller and testing.
-Romi Kuntsman for helping out on some OpenGL issues.
-Everyone on the JEDI-SDL mailing list for their feedback and support.
-Everyone on the Delphi-JEDI mailing for answering my conversion questions.
-Tom Jones for inspiring this conversion.
-
-The JEDI-SDL Home page can be found @ http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME
-
-The JEDI-SDL source code archive can be found @ http://www.sf.net/projects/jedi-sdl/
-
-The JEDI-SDL mailing list can be found @ http://groups.yahoo.com/group/JEDI-SDL/join/
-
-The Latest Stable Release version of the JEDI-SDL.zip file can always be found on the Delphi-JEDI site
-
-The Latest Alpha/Unstable version can always be grabbed from the SourceForge CVS http://sourceforge.net/cvs/?group_id=43805
-
-
-Sincerely,
-
-
-
-Dominique Louis
-Delphi Game Developer.
-*********************************************************
-** To Do Nothing is to Collaborate with the oppressor **
-** -------------------------------------------------- **
-*********************************************************
-=========================================================
-From . . . . . . . : Dominique Louis
-Email. . . . . . . : Dominique@SavageSoftware.com.au
-Company. . . . . . : Savage Software Solutions
-Delphi Games Site. : http://www.DelphiGamer.com
-Delphi JEDI Site . : http://www.delphi-jedi.org
-=========================================================
-
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL-Set8087CW.patch b/Game/Code/lib/JEDI-SDL/OpenGL-Set8087CW.patch
deleted file mode 100644
index e08ca63e..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL-Set8087CW.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Index: OpenGL/Pas/gl.pas
-===================================================================
---- OpenGL/Pas/gl.pas (revision 961)
-+++ OpenGL/Pas/gl.pas (working copy)
-@@ -2287,9 +2287,9 @@
- end;
-
- initialization
-- {$ifdef x86}
-+ {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
- Set8087CW($133F);
-- {$endif x86}
-+ {$IFEND}
-
- LoadOpenGL( GLLibName );
-
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/geometry.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
deleted file mode 100644
index 166ec811..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
+++ /dev/null
@@ -1,1994 +0,0 @@
-unit geometry;
-{
- $Id: geometry.pas,v 1.1 2004/03/30 21:53:54 savage Exp $
-
-}
-
-// This unit contains many needed types, functions and procedures for
-// quaternion, vector and matrix arithmetics. It is specifically designed
-// for geometric calculations within R3 (affine vector space)
-// and R4 (homogeneous vector space).
-//
-// Note: The terms 'affine' or 'affine coordinates' are not really correct here
-// because an 'affine transformation' describes generally a transformation which leads
-// to a uniquely solvable system of equations and has nothing to do with the dimensionality
-// of a vector. One could use 'projective coordinates' but this is also not really correct
-// and since I haven't found a better name (or even any correct one), 'affine' is as good
-// as any other one.
-//
-// Identifiers containing no dimensionality (like affine or homogeneous)
-// and no datatype (integer..extended) are supposed as R4 representation
-// with 'single' floating point type (examples are TVector, TMatrix,
-// and TQuaternion). The default data type is 'single' ('GLFloat' for OpenGL)
-// and used in all routines (except conversions and trigonometric functions).
-//
-// Routines with an open array as argument can either take Func([1,2,3,4,..]) or Func(Vect).
-// The latter is prefered, since no extra stack operations is required.
-// Note: Be careful while passing open array elements! If you pass more elements
-// than there's room in the result the behaviour will be unpredictable.
-//
-// If not otherwise stated, all angles are given in radians
-// (instead of degrees). Use RadToDeg or DegToRad to convert between them.
-//
-// Geometry.pas was assembled from different sources (like GraphicGems)
-// and relevant books or based on self written code, respectivly.
-//
-// Note: Some aspects need to be considered when using Delphi and pure
-// assembler code. Delphi ensures that the direction flag is always
-// cleared while entering a function and expects it cleared on return.
-// This is in particular important in routines with (CPU) string commands (MOVSD etc.)
-// The registers EDI, ESI and EBX (as well as the stack management
-// registers EBP and ESP) must not be changed! EAX, ECX and EDX are
-// freely available and mostly used for parameter.
-//
-// Version 2.5
-// last change : 04. January 2000
-//
-// (c) Copyright 1999, Dipl. Ing. Mike Lischke (public@lischke-online.de)
-{
- $Log: geometry.pas,v $
- Revision 1.1 2004/03/30 21:53:54 savage
- Moved to it's own folder.
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-type
- // data types needed for 3D graphics calculation,
- // included are 'C like' aliases for each type (to be
- // conformal with OpenGL types)
-
- PByte = ^Byte;
- PWord = ^Word;
- PInteger = ^Integer;
- PFloat = ^Single;
- PDouble = ^Double;
- PExtended = ^Extended;
- PPointer = ^Pointer;
-
- // types to specify continous streams of a specific type
- // switch off range checking to access values beyond the limits
- PByteVector = ^TByteVector;
- PByteArray = PByteVector;
- TByteVector = array[0..0] of Byte;
-
- PWordVector = ^TWordVector;
- PWordArray = PWordVector; // note: there's a same named type in SysUtils
- TWordVector = array[0..0] of Word;
-
- PIntegerVector = ^TIntegerVector;
- PIntegerArray = PIntegerVector;
- TIntegerVector = array[0..0] of Integer;
-
- PFloatVector = ^TFloatVector;
- PFloatArray = PFloatVector;
- TFloatVector = array[0..0] of Single;
-
- PDoubleVector = ^TDoubleVector;
- PDoubleArray = PDoubleVector;
- TDoubleVector = array[0..0] of Double;
-
- PExtendedVector = ^TExtendedVector;
- PExtendedArray = PExtendedVector;
- TExtendedVector = array[0..0] of Extended;
-
- PPointerVector = ^TPointerVector;
- PPointerArray = PPointerVector;
- TPointerVector = array[0..0] of Pointer;
-
- PCardinalVector = ^TCardinalVector;
- PCardinalArray = PCardinalVector;
- TCardinalVector = array[0..0] of Cardinal;
-
- // common vector and matrix types with predefined limits
- // indices correspond like: x -> 0
- // y -> 1
- // z -> 2
- // w -> 3
-
- PHomogeneousByteVector = ^THomogeneousByteVector;
- THomogeneousByteVector = array[0..3] of Byte;
- TVector4b = THomogeneousByteVector;
-
- PHomogeneousWordVector = ^THomogeneousWordVector;
- THomogeneousWordVector = array[0..3] of Word;
- TVector4w = THomogeneousWordVector;
-
- PHomogeneousIntVector = ^THomogeneousIntVector;
- THomogeneousIntVector = array[0..3] of Integer;
- TVector4i = THomogeneousIntVector;
-
- PHomogeneousFltVector = ^THomogeneousFltVector;
- THomogeneousFltVector = array[0..3] of Single;
- TVector4f = THomogeneousFltVector;
-
- PHomogeneousDblVector = ^THomogeneousDblVector;
- THomogeneousDblVector = array[0..3] of Double;
- TVector4d = THomogeneousDblVector;
-
- PHomogeneousExtVector = ^THomogeneousExtVector;
- THomogeneousExtVector = array[0..3] of Extended;
- TVector4e = THomogeneousExtVector;
-
- PHomogeneousPtrVector = ^THomogeneousPtrVector;
- THomogeneousPtrVector = array[0..3] of Pointer;
- TVector4p = THomogeneousPtrVector;
-
- PAffineByteVector = ^TAffineByteVector;
- TAffineByteVector = array[0..2] of Byte;
- TVector3b = TAffineByteVector;
-
- PAffineWordVector = ^TAffineWordVector;
- TAffineWordVector = array[0..2] of Word;
- TVector3w = TAffineWordVector;
-
- PAffineIntVector = ^TAffineIntVector;
- TAffineIntVector = array[0..2] of Integer;
- TVector3i = TAffineIntVector;
-
- PAffineFltVector = ^TAffineFltVector;
- TAffineFltVector = array[0..2] of Single;
- TVector3f = TAffineFltVector;
-
- PAffineDblVector = ^TAffineDblVector;
- TAffineDblVector = array[0..2] of Double;
- TVector3d = TAffineDblVector;
-
- PAffineExtVector = ^TAffineExtVector;
- TAffineExtVector = array[0..2] of Extended;
- TVector3e = TAffineExtVector;
-
- PAffinePtrVector = ^TAffinePtrVector;
- TAffinePtrVector = array[0..2] of Pointer;
- TVector3p = TAffinePtrVector;
-
- // some simplified names
- PVector = ^TVector;
- TVector = THomogeneousFltVector;
-
- PHomogeneousVector = ^THomogeneousVector;
- THomogeneousVector = THomogeneousFltVector;
-
- PAffineVector = ^TAffineVector;
- TAffineVector = TAffineFltVector;
-
- // arrays of vectors
- PVectorArray = ^TVectorArray;
- TVectorArray = array[0..0] of TAffineVector;
-
- // matrices
- THomogeneousByteMatrix = array[0..3] of THomogeneousByteVector;
- TMatrix4b = THomogeneousByteMatrix;
-
- THomogeneousWordMatrix = array[0..3] of THomogeneousWordVector;
- TMatrix4w = THomogeneousWordMatrix;
-
- THomogeneousIntMatrix = array[0..3] of THomogeneousIntVector;
- TMatrix4i = THomogeneousIntMatrix;
-
- THomogeneousFltMatrix = array[0..3] of THomogeneousFltVector;
- TMatrix4f = THomogeneousFltMatrix;
-
- THomogeneousDblMatrix = array[0..3] of THomogeneousDblVector;
- TMatrix4d = THomogeneousDblMatrix;
-
- THomogeneousExtMatrix = array[0..3] of THomogeneousExtVector;
- TMatrix4e = THomogeneousExtMatrix;
-
- TAffineByteMatrix = array[0..2] of TAffineByteVector;
- TMatrix3b = TAffineByteMatrix;
-
- TAffineWordMatrix = array[0..2] of TAffineWordVector;
- TMatrix3w = TAffineWordMatrix;
-
- TAffineIntMatrix = array[0..2] of TAffineIntVector;
- TMatrix3i = TAffineIntMatrix;
-
- TAffineFltMatrix = array[0..2] of TAffineFltVector;
- TMatrix3f = TAffineFltMatrix;
-
- TAffineDblMatrix = array[0..2] of TAffineDblVector;
- TMatrix3d = TAffineDblMatrix;
-
- TAffineExtMatrix = array[0..2] of TAffineExtVector;
- TMatrix3e = TAffineExtMatrix;
-
- // some simplified names
- PMatrix = ^TMatrix;
- TMatrix = THomogeneousFltMatrix;
-
- PHomogeneousMatrix = ^THomogeneousMatrix;
- THomogeneousMatrix = THomogeneousFltMatrix;
-
- PAffineMatrix = ^TAffineMatrix;
- TAffineMatrix = TAffineFltMatrix;
-
- // q = ([x, y, z], w)
- TQuaternion = record
- case Integer of
- 0:
- (ImagPart: TAffineVector;
- RealPart: Single);
- 1:
- (Vector: TVector4f);
- end;
-
- TRectangle = record
- Left,
- Top,
- Width,
- Height: Integer;
- end;
-
- TTransType = (ttScaleX, ttScaleY, ttScaleZ,
- ttShearXY, ttShearXZ, ttShearYZ,
- ttRotateX, ttRotateY, ttRotateZ,
- ttTranslateX, ttTranslateY, ttTranslateZ,
- ttPerspectiveX, ttPerspectiveY, ttPerspectiveZ, ttPerspectiveW);
-
- // used to describe a sequence of transformations in following order:
- // [Sx][Sy][Sz][ShearXY][ShearXZ][ShearZY][Rx][Ry][Rz][Tx][Ty][Tz][P(x,y,z,w)]
- // constants are declared for easier access (see MatrixDecompose below)
- TTransformations = array[TTransType] of Single;
-
-
-const
- // useful constants
-
- // standard vectors
- XVector: TAffineVector = (1, 0, 0);
- YVector: TAffineVector = (0, 1, 0);
- ZVector: TAffineVector = (0, 0, 1);
- NullVector: TAffineVector = (0, 0, 0);
-
- IdentityMatrix: TMatrix = ((1, 0, 0, 0),
- (0, 1, 0, 0),
- (0, 0, 1, 0),
- (0, 0, 0, 1));
- EmptyMatrix: TMatrix = ((0, 0, 0, 0),
- (0, 0, 0, 0),
- (0, 0, 0, 0),
- (0, 0, 0, 0));
- // some very small numbers
- EPSILON = 1e-100;
- EPSILON2 = 1e-50;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// vector functions
-function VectorAdd(V1, V2: TVector): TVector;
-function VectorAffineAdd(V1, V2: TAffineVector): TAffineVector;
-function VectorAffineCombine(V1, V2: TAffineVector; F1, F2: Single): TAffineVector;
-function VectorAffineDotProduct(V1, V2: TAffineVector): Single;
-function VectorAffineLerp(V1, V2: TAffineVector; t: Single): TAffineVector;
-function VectorAffineSubtract(V1, V2: TAffineVector): TAffineVector;
-function VectorAngle(V1, V2: TAffineVector): Single;
-function VectorCombine(V1, V2: TVector; F1, F2: Single): TVector;
-function VectorCrossProduct(V1, V2: TAffineVector): TAffineVector;
-function VectorDotProduct(V1, V2: TVector): Single;
-function VectorLength(V: array of Single): Single;
-function VectorLerp(V1, V2: TVector; t: Single): TVector;
-procedure VectorNegate(V: array of Single);
-function VectorNorm(V: array of Single): Single;
-function VectorNormalize(V: array of Single): Single;
-function VectorPerpendicular(V, N: TAffineVector): TAffineVector;
-function VectorReflect(V, N: TAffineVector): TAffineVector;
-procedure VectorRotate(var Vector: TVector4f; Axis: TVector3f; Angle: Single);
-procedure VectorScale(V: array of Single; Factor: Single);
-function VectorSubtract(V1, V2: TVector): TVector;
-
-// matrix functions
-function CreateRotationMatrixX(Sine, Cosine: Single): TMatrix;
-function CreateRotationMatrixY(Sine, Cosine: Single): TMatrix;
-function CreateRotationMatrixZ(Sine, Cosine: Single): TMatrix;
-function CreateScaleMatrix(V: TAffineVector): TMatrix;
-function CreateTranslationMatrix(V: TVector): TMatrix;
-procedure MatrixAdjoint(var M: TMatrix);
-function MatrixAffineDeterminant(M: TAffineMatrix): Single;
-procedure MatrixAffineTranspose(var M: TAffineMatrix);
-function MatrixDeterminant(M: TMatrix): Single;
-procedure MatrixInvert(var M: TMatrix);
-function MatrixMultiply(M1, M2: TMatrix): TMatrix;
-procedure MatrixScale(var M: TMatrix; Factor: Single);
-procedure MatrixTranspose(var M: TMatrix);
-
-// quaternion functions
-function QuaternionConjugate(Q: TQuaternion): TQuaternion;
-function QuaternionFromPoints(V1, V2: TAffineVector): TQuaternion;
-function QuaternionMultiply(qL, qR: TQuaternion): TQuaternion;
-function QuaternionSlerp(QStart, QEnd: TQuaternion; Spin: Integer; t: Single): TQuaternion;
-function QuaternionToMatrix(Q: TQuaternion): TMatrix;
-procedure QuaternionToPoints(Q: TQuaternion; var ArcFrom, ArcTo: TAffineVector);
-
-// mixed functions
-function ConvertRotation(Angles: TAffineVector): TVector;
-function CreateRotationMatrix(Axis: TVector3f; Angle: Single): TMatrix;
-function MatrixDecompose(M: TMatrix; var Tran: TTransformations): Boolean;
-function VectorAffineTransform(V: TAffineVector; M: TAffineMatrix): TAffineVector;
-function VectorTransform(V: TVector4f; M: TMatrix): TVector4f; overload;
-function VectorTransform(V: TVector3f; M: TMatrix): TVector3f; overload;
-
-// miscellaneous functions
-function MakeAffineDblVector(V: array of Double): TAffineDblVector;
-function MakeDblVector(V: array of Double): THomogeneousDblVector;
-function MakeAffineVector(V: array of Single): TAffineVector;
-function MakeQuaternion(Imag: array of Single; Real: Single): TQuaternion;
-function MakeVector(V: array of Single): TVector;
-function PointInPolygon(xp, yp : array of Single; x, y: Single): Boolean;
-function VectorAffineDblToFlt(V: TAffineDblVector): TAffineVector;
-function VectorDblToFlt(V: THomogeneousDblVector): THomogeneousVector;
-function VectorAffineFltToDbl(V: TAffineVector): TAffineDblVector;
-function VectorFltToDbl(V: TVector): THomogeneousDblVector;
-
-// trigonometric functions
-function ArcCos(X: Extended): Extended;
-function ArcSin(X: Extended): Extended;
-function ArcTan2(Y, X: Extended): Extended;
-function CoTan(X: Extended): Extended;
-function DegToRad(Degrees: Extended): Extended;
-function RadToDeg(Radians: Extended): Extended;
-procedure SinCos(Theta: Extended; var Sin, Cos: Extended);
-function Tan(X: Extended): Extended;
-
-// coordinate system manipulation functions
-function Turn(Matrix: TMatrix; Angle: Single): TMatrix; overload;
-function Turn(Matrix: TMatrix; MasterUp: TAffineVector; Angle: Single): TMatrix; overload;
-function Pitch(Matrix: TMatrix; Angle: Single): TMatrix; overload;
-function Pitch(Matrix: TMatrix; MasterRight: TAffineVector; Angle: Single): TMatrix; overload;
-function Roll(Matrix: TMatrix; Angle: Single): TMatrix; overload;
-function Roll(Matrix: TMatrix; MasterDirection: TAffineVector; Angle: Single): TMatrix; overload;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-implementation
-
-const
- // FPU status flags (high order byte)
- C0 = 1;
- C1 = 2;
- C2 = 4;
- C3 = $40;
-
- // to be used as descriptive indices
- X = 0;
- Y = 1;
- Z = 2;
- W = 3;
-
-//----------------- trigonometric helper functions ---------------------------------------------------------------------
-
-function DegToRad(Degrees: Extended): Extended;
-
-begin
- Result := Degrees * (PI / 180);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function RadToDeg(Radians: Extended): Extended;
-
-begin
- Result := Radians * (180 / PI);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure SinCos(Theta: Extended; var Sin, Cos: Extended); assembler; register;
-
-// calculates sine and cosine from the given angle Theta
-// EAX contains address of Sin
-// EDX contains address of Cos
-// Theta is passed over the stack
-
-asm
- FLD Theta
- FSINCOS
- FSTP TBYTE PTR [EDX] // cosine
- FSTP TBYTE PTR [EAX] // sine
- FWAIT
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function ArcCos(X: Extended): Extended;
-
-begin
- Result := ArcTan2(Sqrt(1 - X * X), X);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function ArcSin(X: Extended): Extended;
-
-begin
- Result := ArcTan2(X, Sqrt(1 - X * X))
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function ArcTan2(Y, X: Extended): Extended;
-
-asm
- FLD Y
- FLD X
- FPATAN
- FWAIT
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Tan(X: Extended): Extended;
-
-asm
- FLD X
- FPTAN
- FSTP ST(0) // FPTAN pushes 1.0 after result
- FWAIT
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CoTan(X: Extended): Extended;
-
-asm
- FLD X
- FPTAN
- FDIVRP
- FWAIT
-end;
-
-//----------------- miscellaneous vector functions ---------------------------------------------------------------------
-
-function MakeAffineDblVector(V: array of Double): TAffineDblVector; assembler;
-
-// creates a vector from given values
-// EAX contains address of V
-// ECX contains address to result vector
-// EDX contains highest index of V
-
-asm
- PUSH EDI
- PUSH ESI
- MOV EDI, ECX
- MOV ESI, EAX
- MOV ECX, EDX
- ADD ECX, 2
- REP MOVSD
- POP ESI
- POP EDI
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MakeDblVector(V: array of Double): THomogeneousDblVector; assembler;
-
-// creates a vector from given values
-// EAX contains address of V
-// ECX contains address to result vector
-// EDX contains highest index of V
-
-asm
- PUSH EDI
- PUSH ESI
- MOV EDI, ECX
- MOV ESI, EAX
- MOV ECX, EDX
- ADD ECX, 2
- REP MOVSD
- POP ESI
- POP EDI
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MakeAffineVector(V: array of Single): TAffineVector; assembler;
-
-// creates a vector from given values
-// EAX contains address of V
-// ECX contains address to result vector
-// EDX contains highest index of V
-
-asm
- PUSH EDI
- PUSH ESI
- MOV EDI, ECX
- MOV ESI, EAX
- MOV ECX, EDX
- INC ECX
- CMP ECX, 3
- JB @@1
- MOV ECX, 3
-@@1: REP MOVSD // copy given values
- MOV ECX, 2
- SUB ECX, EDX // determine missing entries
- JS @@Finish
- XOR EAX, EAX
- REP STOSD // set remaining fields to 0
-@@Finish: POP ESI
- POP EDI
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MakeQuaternion(Imag: array of Single; Real: Single): TQuaternion; assembler;
-
-// creates a quaternion from the given values
-// EAX contains address of Imag
-// ECX contains address to result vector
-// EDX contains highest index of Imag
-// Real part is passed on the stack
-
-asm
- PUSH EDI
- PUSH ESI
- MOV EDI, ECX
- MOV ESI, EAX
- MOV ECX, EDX
- INC ECX
- REP MOVSD
- MOV EAX, [Real]
- MOV [EDI], EAX
- POP ESI
- POP EDI
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MakeVector(V: array of Single): TVector; assembler;
-
-// creates a vector from given values
-// EAX contains address of V
-// ECX contains address to result vector
-// EDX contains highest index of V
-
-asm
- PUSH EDI
- PUSH ESI
- MOV EDI, ECX
- MOV ESI, EAX
- MOV ECX, EDX
- INC ECX
- CMP ECX, 4
- JB @@1
- MOV ECX, 4
-@@1: REP MOVSD // copy given values
- MOV ECX, 3
- SUB ECX, EDX // determine missing entries
- JS @@Finish
- XOR EAX, EAX
- REP STOSD // set remaining fields to 0
-@@Finish: POP ESI
- POP EDI
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorLength(V: array of Single): Single; assembler;
-
-// calculates the length of a vector following the equation: sqrt(x * x + y * y + ...)
-// Note: The parameter of this function is declared as open array. Thus
-// there's no restriction about the number of the components of the vector.
-//
-// EAX contains address of V
-// EDX contains the highest index of V
-// the result is returned in ST(0)
-
-asm
- FLDZ // initialize sum
-@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
- FMUL ST, ST
- FADDP
- SUB EDX, 1
- JNL @@Loop
- FSQRT
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAngle(V1, V2: TAffineVector): Single; assembler;
-
-// calculates the cosine of the angle between Vector1 and Vector2
-// Result = DotProduct(V1, V2) / (Length(V1) * Length(V2))
-//
-// EAX contains address of Vector1
-// EDX contains address of Vector2
-
-asm
- FLD DWORD PTR [EAX] // V1[0]
- FLD ST // double V1[0]
- FMUL ST, ST // V1[0]^2 (prep. for divisor)
- FLD DWORD PTR [EDX] // V2[0]
- FMUL ST(2), ST // ST(2) := V1[0] * V2[0]
- FMUL ST, ST // V2[0]^2 (prep. for divisor)
- FLD DWORD PTR [EAX + 4] // V1[1]
- FLD ST // double V1[1]
- FMUL ST, ST // ST(0) := V1[1]^2
- FADDP ST(3), ST // ST(2) := V1[0]^2 + V1[1] * * 2
- FLD DWORD PTR [EDX + 4] // V2[1]
- FMUL ST(1), ST // ST(1) := V1[1] * V2[1]
- FMUL ST, ST // ST(0) := V2[1]^2
- FADDP ST(2), ST // ST(1) := V2[0]^2 + V2[1]^2
- FADDP ST(3), ST // ST(2) := V1[0] * V2[0] + V1[1] * V2[1]
- FLD DWORD PTR [EAX + 8] // load V2[1]
- FLD ST // same calcs go here
- FMUL ST, ST // (compare above)
- FADDP ST(3), ST
- FLD DWORD PTR [EDX + 8]
- FMUL ST(1), ST
- FMUL ST, ST
- FADDP ST(2), ST
- FADDP ST(3), ST
- FMULP // ST(0) := (V1[0]^2 + V1[1]^2 + V1[2]) *
- // (V2[0]^2 + V2[1]^2 + V2[2])
- FSQRT // sqrt(ST(0))
- FDIVP // ST(0) := Result := ST(1) / ST(0)
- // the result is expected in ST(0), if it's invalid, an error is raised
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorNorm(V: array of Single): Single; assembler; register;
-
-// calculates norm of a vector which is defined as norm = x * x + y * y + ...
-// EAX contains address of V
-// EDX contains highest index in V
-// result is passed in ST(0)
-
-asm
- FLDZ // initialize sum
-@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
- FMUL ST, ST // make square
- FADDP // add previous calculated sum
- SUB EDX, 1
- JNL @@Loop
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorNormalize(V: array of Single): Single; assembler; register;
-
-// transforms a vector to unit length and return length
-// EAX contains address of V
-// EDX contains the highest index in V
-// return former length of V in ST
-
-asm
- PUSH EBX
- MOV ECX, EDX // save size of V
- CALL VectorLength // calculate length of vector
- FTST // test if length = 0
- MOV EBX, EAX // save parameter address
- FSTSW AX // get test result
- TEST AH, C3 // check the test result
- JNZ @@Finish
- SUB EBX, 4 // simplyfied address calculation
- INC ECX
- FLD1 // calculate reciprocal of length
- FDIV ST, ST(1)
-@@1: FLD ST // double reciprocal
- FMUL DWORD PTR [EBX + 4 * ECX] // scale component
- WAIT
- FSTP DWORD PTR [EBX + 4 * ECX] // store result
- LOOP @@1
- FSTP ST // remove reciprocal from FPU stack
-@@Finish: POP EBX
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineSubtract(V1, V2: TAffineVector): TAffineVector; assembler; register;
-
-// returns v1 minus v2
-// EAX contains address of V1
-// EDX contains address of V2
-// ECX contains address of the result
-
-asm
- {Result[X] := V1[X]-V2[X];
- Result[Y] := V1[Y]-V2[Y];
- Result[Z] := V1[Z]-V2[Z];}
-
- FLD DWORD PTR [EAX]
- FSUB DWORD PTR [EDX]
- FSTP DWORD PTR [ECX]
- FLD DWORD PTR [EAX + 4]
- FSUB DWORD PTR [EDX + 4]
- FSTP DWORD PTR [ECX + 4]
- FLD DWORD PTR [EAX + 8]
- FSUB DWORD PTR [EDX + 8]
- FSTP DWORD PTR [ECX + 8]
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorReflect(V, N: TAffineVector): TAffineVector; assembler; register;
-
-// reflects vector V against N (assumes N is normalized)
-// EAX contains address of V
-// EDX contains address of N
-// ECX contains address of the result
-
-//var Dot : Single;
-
-asm
- {Dot := VectorAffineDotProduct(V, N);
- Result[X] := V[X]-2 * Dot * N[X];
- Result[Y] := V[Y]-2 * Dot * N[Y];
- Result[Z] := V[Z]-2 * Dot * N[Z];}
-
- CALL VectorAffineDotProduct // dot is now in ST(0)
- FCHS // -dot
- FADD ST, ST // -dot * 2
- FLD DWORD PTR [EDX] // ST := N[X]
- FMUL ST, ST(1) // ST := -2 * dot * N[X]
- FADD DWORD PTR[EAX] // ST := V[X] - 2 * dot * N[X]
- FSTP DWORD PTR [ECX] // store result
- FLD DWORD PTR [EDX + 4] // etc.
- FMUL ST, ST(1)
- FADD DWORD PTR[EAX + 4]
- FSTP DWORD PTR [ECX + 4]
- FLD DWORD PTR [EDX + 8]
- FMUL ST, ST(1)
- FADD DWORD PTR[EAX + 8]
- FSTP DWORD PTR [ECX + 8]
- FSTP ST // clean FPU stack
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure VectorRotate(var Vector: TVector4f; Axis: TVector3f; Angle: Single);
-
-// rotates Vector about Axis with Angle radiants
-
-var RotMatrix : TMatrix4f;
-
-begin
- RotMatrix := CreateRotationMatrix(Axis, Angle);
- Vector := VectorTransform(Vector, RotMatrix);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure VectorScale(V: array of Single; Factor: Single); assembler; register;
-
-// returns a vector scaled by a factor
-// EAX contains address of V
-// EDX contains highest index in V
-// Factor is located on the stack
-
-asm
- {for I := Low(V) to High(V) do V[I] := V[I] * Factor;}
-
- FLD DWORD PTR [Factor] // load factor
-@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
- FMUL ST, ST(1) // multiply it with the factor
- WAIT
- FSTP DWORD PTR [EAX + 4 * EDX] // store the result
- DEC EDX // do the entire array
- JNS @@Loop
- FSTP ST(0) // clean the FPU stack
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure VectorNegate(V: array of Single); assembler; register;
-
-// returns a negated vector
-// EAX contains address of V
-// EDX contains highest index in V
-
-asm
- {V[X] := -V[X];
- V[Y] := -V[Y];
- V[Z] := -V[Z];}
-
-@@Loop: FLD DWORD PTR [EAX + 4 * EDX]
- FCHS
- WAIT
- FSTP DWORD PTR [EAX + 4 * EDX]
- DEC EDX
- JNS @@Loop
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAdd(V1, V2: TVector): TVector; register;
-
-// returns the sum of two vectors
-
-begin
- Result[X] := V1[X] + V2[X];
- Result[Y] := V1[Y] + V2[Y];
- Result[Z] := V1[Z] + V2[Z];
- Result[W] := V1[W] + V2[W];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineAdd(V1, V2: TAffineVector): TAffineVector; register;
-
-// returns the sum of two vectors
-
-begin
- Result[X] := V1[X] + V2[X];
- Result[Y] := V1[Y] + V2[Y];
- Result[Z] := V1[Z] + V2[Z];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorSubtract(V1, V2: TVector): TVector; register;
-
-// returns the difference of two vectors
-
-begin
- Result[X] := V1[X] - V2[X];
- Result[Y] := V1[Y] - V2[Y];
- Result[Z] := V1[Z] - V2[Z];
- Result[W] := V1[W] - V2[W];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorDotProduct(V1, V2: TVector): Single; register;
-
-begin
- Result := V1[X] * V2[X] + V1[Y] * V2[Y] + V1[Z] * V2[Z] + V1[W] * V2[W];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineDotProduct(V1, V2: TAffineVector): Single; assembler; register;
-
-// calculates the dot product between V1 and V2
-// EAX contains address of V1
-// EDX contains address of V2
-// result is stored in ST(0)
-
-asm
- //Result := V1[X] * V2[X] + V1[Y] * V2[Y] + V1[Z] * V2[Z];
-
- FLD DWORD PTR [EAX]
- FMUL DWORD PTR [EDX]
- FLD DWORD PTR [EAX + 4]
- FMUL DWORD PTR [EDX + 4]
- FADDP
- FLD DWORD PTR [EAX + 8]
- FMUL DWORD PTR [EDX + 8]
- FADDP
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorCrossProduct(V1, V2: TAffineVector): TAffineVector;
-
-// calculates the cross product between vector 1 and 2, Temp is necessary because
-// either V1 or V2 could also be the result vector
-//
-// EAX contains address of V1
-// EDX contains address of V2
-// ECX contains address of result
-
-var Temp: TAffineVector;
-
-asm
- {Temp[X] := V1[Y] * V2[Z]-V1[Z] * V2[Y];
- Temp[Y] := V1[Z] * V2[X]-V1[X] * V2[Z];
- Temp[Z] := V1[X] * V2[Y]-V1[Y] * V2[X];
- Result := Temp;}
-
- PUSH EBX // save EBX, must be restored to original value
- LEA EBX, [Temp]
- FLD DWORD PTR [EDX + 8] // first load both vectors onto FPU register stack
- FLD DWORD PTR [EDX + 4]
- FLD DWORD PTR [EDX + 0]
- FLD DWORD PTR [EAX + 8]
- FLD DWORD PTR [EAX + 4]
- FLD DWORD PTR [EAX + 0]
-
- FLD ST(1) // ST(0) := V1[Y]
- FMUL ST, ST(6) // ST(0) := V1[Y] * V2[Z]
- FLD ST(3) // ST(0) := V1[Z]
- FMUL ST, ST(6) // ST(0) := V1[Z] * V2[Y]
- FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
- FSTP DWORD [EBX] // Temp[X] := ST(0)
- FLD ST(2) // ST(0) := V1[Z]
- FMUL ST, ST(4) // ST(0) := V1[Z] * V2[X]
- FLD ST(1) // ST(0) := V1[X]
- FMUL ST, ST(7) // ST(0) := V1[X] * V2[Z]
- FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
- FSTP DWORD [EBX + 4] // Temp[Y] := ST(0)
- FLD ST // ST(0) := V1[X]
- FMUL ST, ST(5) // ST(0) := V1[X] * V2[Y]
- FLD ST(2) // ST(0) := V1[Y]
- FMUL ST, ST(5) // ST(0) := V1[Y] * V2[X]
- FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
- FSTP DWORD [EBX + 8] // Temp[Z] := ST(0)
- FSTP ST(0) // clear FPU register stack
- FSTP ST(0)
- FSTP ST(0)
- FSTP ST(0)
- FSTP ST(0)
- FSTP ST(0)
- MOV EAX, [EBX] // copy Temp to Result
- MOV [ECX], EAX
- MOV EAX, [EBX + 4]
- MOV [ECX + 4], EAX
- MOV EAX, [EBX + 8]
- MOV [ECX + 8], EAX
- POP EBX
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorPerpendicular(V, N: TAffineVector): TAffineVector;
-
-// calculates a vector perpendicular to N (N is assumed to be of unit length)
-// subtract out any component parallel to N
-
-var Dot: Single;
-
-begin
- Dot := VectorAffineDotProduct(V, N);
- Result[X] := V[X]-Dot * N[X];
- Result[Y] := V[Y]-Dot * N[Y];
- Result[Z] := V[Z]-Dot * N[Z];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorTransform(V: TVector4f; M: TMatrix): TVector4f; register;
-
-// transforms a homogeneous vector by multiplying it with a matrix
-
-var TV: TVector4f;
-
-begin
- TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X] + V[W] * M[W, X];
- TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y] + V[W] * M[W, Y];
- TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z] + V[W] * M[W, Z];
- TV[W] := V[X] * M[X, W] + V[Y] * M[Y, W] + V[Z] * M[Z, W] + V[W] * M[W, W];
- Result := TV
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorTransform(V: TVector3f; M: TMatrix): TVector3f;
-
-// transforms an affine vector by multiplying it with a (homogeneous) matrix
-
-var TV: TVector3f;
-
-begin
- TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X] + M[W, X];
- TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y] + M[W, Y];
- TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z] + M[W, Z];
- Result := TV;
-end;
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineTransform(V: TAffineVector; M: TAffineMatrix): TAffineVector; register;
-
-// transforms an affine vector by multiplying it with a matrix
-
-var TV: TAffineVector;
-
-begin
- TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X];
- TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y];
- TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z];
- Result := TV;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function PointInPolygon(xp, yp : array of Single; x, y: Single): Boolean;
-
-// The code below is from Wm. Randolph Franklin
-// with some minor modifications for speed. It returns 1 for strictly
-// interior points, 0 for strictly exterior, and 0 or 1 for points on
-// the boundary.
-// This code is not yet tested!
-
-var I, J: Integer;
-
-begin
- Result := False;
- if High(XP) <> High(YP) then Exit;
- J := High(XP);
- for I := 0 to High(XP) do
- begin
- if ((((yp[I] <= y) and (y < yp[J])) or ((yp[J] <= y) and (y < yp[I]))) and
- (x < (xp[J] - xp[I]) * (y - yp[I]) / (yp[J] - yp[I]) + xp[I]))
- then Result := not Result;
- J := I + 1;
- end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function QuaternionConjugate(Q: TQuaternion): TQuaternion; assembler;
-
-// returns the conjugate of a quaternion
-// EAX contains address of Q
-// EDX contains address of result
-
-asm
- FLD DWORD PTR [EAX]
- FCHS
- WAIT
- FSTP DWORD PTR [EDX]
- FLD DWORD PTR [EAX + 4]
- FCHS
- WAIT
- FSTP DWORD PTR [EDX + 4]
- FLD DWORD PTR [EAX + 8]
- FCHS
- WAIT
- FSTP DWORD PTR [EDX + 8]
- MOV EAX, [EAX + 12]
- MOV [EDX + 12], EAX
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function QuaternionFromPoints(V1, V2: TAffineVector): TQuaternion; assembler;
-
-// constructs a unit quaternion from two points on unit sphere
-// EAX contains address of V1
-// ECX contains address to result
-// EDX contains address of V2
-
-asm
- {Result.ImagPart := VectorCrossProduct(V1, V2);
- Result.RealPart := Sqrt((VectorAffineDotProduct(V1, V2) + 1)/2);}
-
- PUSH EAX
- CALL VectorCrossProduct // determine axis to rotate about
- POP EAX
- FLD1 // prepare next calculation
- Call VectorAffineDotProduct // calculate cos(angle between V1 and V2)
- FADD ST, ST(1) // transform angle to angle/2 by: cos(a/2)=sqrt((1 + cos(a))/2)
- FXCH ST(1)
- FADD ST, ST
- FDIVP ST(1), ST
- FSQRT
- FSTP DWORD PTR [ECX + 12] // Result.RealPart := ST(0)
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function QuaternionMultiply(qL, qR: TQuaternion): TQuaternion;
-
-// Returns quaternion product qL * qR. Note: order is important!
-// To combine rotations, use the product QuaternionMuliply(qSecond, qFirst),
-// which gives the effect of rotating by qFirst then qSecond.
-
-var Temp : TQuaternion;
-
-begin
- Temp.RealPart := qL.RealPart * qR.RealPart - qL.ImagPart[X] * qR.ImagPart[X] -
- qL.ImagPart[Y] * qR.ImagPart[Y] - qL.ImagPart[Z] * qR.ImagPart[Z];
- Temp.ImagPart[X] := qL.RealPart * qR.ImagPart[X] + qL.ImagPart[X] * qR.RealPart +
- qL.ImagPart[Y] * qR.ImagPart[Z] - qL.ImagPart[Z] * qR.ImagPart[Y];
- Temp.ImagPart[Y] := qL.RealPart * qR.ImagPart[Y] + qL.ImagPart[Y] * qR.RealPart +
- qL.ImagPart[Z] * qR.ImagPart[X] - qL.ImagPart[X] * qR.ImagPart[Z];
- Temp.ImagPart[Z] := qL.RealPart * qR.ImagPart[Z] + qL.ImagPart[Z] * qR.RealPart +
- qL.ImagPart[X] * qR.ImagPart[Y] - qL.ImagPart[Y] * qR.ImagPart[X];
- Result := Temp;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function QuaternionToMatrix(Q: TQuaternion): TMatrix;
-
-// Constructs rotation matrix from (possibly non-unit) quaternion.
-// Assumes matrix is used to multiply column vector on the left:
-// vnew = mat vold. Works correctly for right-handed coordinate system
-// and right-handed rotations.
-
-// Essentially, this function is the same as CreateRotationMatrix and you can consider it as
-// being for reference here.
-
-{var Norm, S,
- XS, YS, ZS,
- WX, WY, WZ,
- XX, XY, XZ,
- YY, YZ, ZZ : Single;
-
-begin
- Norm := Q.Vector[X] * Q.Vector[X] + Q.Vector[Y] * Q.Vector[Y] + Q.Vector[Z] * Q.Vector[Z] + Q.RealPart * Q.RealPart;
- if Norm > 0 then S := 2 / Norm
- else S := 0;
-
- XS := Q.Vector[X] * S; YS := Q.Vector[Y] * S; ZS := Q.Vector[Z] * S;
- WX := Q.RealPart * XS; WY := Q.RealPart * YS; WZ := Q.RealPart * ZS;
- XX := Q.Vector[X] * XS; XY := Q.Vector[X] * YS; XZ := Q.Vector[X] * ZS;
- YY := Q.Vector[Y] * YS; YZ := Q.Vector[Y] * ZS; ZZ := Q.Vector[Z] * ZS;
-
- Result[X, X] := 1 - (YY + ZZ); Result[Y, X] := XY + WZ; Result[Z, X] := XZ - WY; Result[W, X] := 0;
- Result[X, Y] := XY - WZ; Result[Y, Y] := 1 - (XX + ZZ); Result[Z, Y] := YZ + WX; Result[W, Y] := 0;
- Result[X, Z] := XZ + WY; Result[Y, Z] := YZ - WX; Result[Z, Z] := 1 - (XX + YY); Result[W, Z] := 0;
- Result[X, W] := 0; Result[Y, W] := 0; Result[Z, W] := 0; Result[W, W] := 1;}
-
-var
- V: TAffineVector;
- SinA, CosA,
- A, B, C: Extended;
-
-begin
- V := Q.ImagPart;
- VectorNormalize(V);
- SinCos(Q.RealPart / 2, SinA, CosA);
- A := V[X] * SinA;
- B := V[Y] * SinA;
- C := V[Z] * SinA;
-
- Result := IdentityMatrix;
- Result[X, X] := 1 - 2 * B * B - 2 * C * C;
- Result[X, Y] := 2 * A * B - 2 * CosA * C;
- Result[X, Z] := 2 * A * C + 2 * CosA * B;
-
- Result[Y, X] := 2 * A * B + 2 * CosA * C;
- Result[Y, Y] := 1 - 2 * A * A - 2 * C * C;
- Result[Y, Z] := 2 * B * C - 2 * CosA * A;
-
- Result[Z, X] := 2 * A * C - 2 * CosA * B;
- Result[Z, Y] := 2 * B * C + 2 * CosA * A;
- Result[Z, Z] := 1 - 2 * A * A - 2 * B * B;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure QuaternionToPoints(Q: TQuaternion; var ArcFrom, ArcTo: TAffineVector); register;
-
-// converts a unit quaternion into two points on a unit sphere
-
-var S: Single;
-
-begin
- S := Sqrt(Q.ImagPart[X] * Q.ImagPart[X] + Q.ImagPart[Y] * Q.ImagPart[Y]);
- if S = 0 then ArcFrom := MakeAffineVector([0, 1, 0])
- else ArcFrom := MakeAffineVector([-Q.ImagPart[Y] / S, Q.ImagPart[X] / S, 0]);
- ArcTo[X] := Q.RealPart * ArcFrom[X] - Q.ImagPart[Z] * ArcFrom[Y];
- ArcTo[Y] := Q.RealPart * ArcFrom[Y] + Q.ImagPart[Z] * ArcFrom[X];
- ArcTo[Z] := Q.ImagPart[X] * ArcFrom[Y] - Q.ImagPart[Y] * ArcFrom[X];
- if Q.RealPart < 0 then ArcFrom := MakeAffineVector([-ArcFrom[X], -ArcFrom[Y], 0]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MatrixAffineDeterminant(M: TAffineMatrix): Single; register;
-
-// determinant of a 3x3 matrix
-
-begin
- Result := M[X, X] * (M[Y, Y] * M[Z, Z] - M[Z, Y] * M[Y, Z]) -
- M[X, Y] * (M[Y, X] * M[Z, Z] - M[Z, X] * M[Y, Z]) +
- M[X, Z] * (M[Y, X] * M[Z, Y] - M[Z, X] * M[Y, Y]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3: Single): Single;
-
-// internal version for the determinant of a 3x3 matrix
-
-begin
- Result := a1 * (b2 * c3 - b3 * c2) -
- b1 * (a2 * c3 - a3 * c2) +
- c1 * (a2 * b3 - a3 * b2);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure MatrixAdjoint(var M: TMatrix); register;
-
-// Adjoint of a 4x4 matrix - used in the computation of the inverse
-// of a 4x4 matrix
-
-var a1, a2, a3, a4,
- b1, b2, b3, b4,
- c1, c2, c3, c4,
- d1, d2, d3, d4: Single;
-
-
-begin
- a1 := M[X, X]; b1 := M[X, Y];
- c1 := M[X, Z]; d1 := M[X, W];
- a2 := M[Y, X]; b2 := M[Y, Y];
- c2 := M[Y, Z]; d2 := M[Y, W];
- a3 := M[Z, X]; b3 := M[Z, Y];
- c3 := M[Z, Z]; d3 := M[Z, W];
- a4 := M[W, X]; b4 := M[W, Y];
- c4 := M[W, Z]; d4 := M[W, W];
-
- // row column labeling reversed since we transpose rows & columns
- M[X, X] := MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4);
- M[Y, X] := -MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4);
- M[Z, X] := MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4);
- M[W, X] := -MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
-
- M[X, Y] := -MatrixDetInternal(b1, b3, b4, c1, c3, c4, d1, d3, d4);
- M[Y, Y] := MatrixDetInternal(a1, a3, a4, c1, c3, c4, d1, d3, d4);
- M[Z, Y] := -MatrixDetInternal(a1, a3, a4, b1, b3, b4, d1, d3, d4);
- M[W, Y] := MatrixDetInternal(a1, a3, a4, b1, b3, b4, c1, c3, c4);
-
- M[X, Z] := MatrixDetInternal(b1, b2, b4, c1, c2, c4, d1, d2, d4);
- M[Y, Z] := -MatrixDetInternal(a1, a2, a4, c1, c2, c4, d1, d2, d4);
- M[Z, Z] := MatrixDetInternal(a1, a2, a4, b1, b2, b4, d1, d2, d4);
- M[W, Z] := -MatrixDetInternal(a1, a2, a4, b1, b2, b4, c1, c2, c4);
-
- M[X, W] := -MatrixDetInternal(b1, b2, b3, c1, c2, c3, d1, d2, d3);
- M[Y, W] := MatrixDetInternal(a1, a2, a3, c1, c2, c3, d1, d2, d3);
- M[Z, W] := -MatrixDetInternal(a1, a2, a3, b1, b2, b3, d1, d2, d3);
- M[W, W] := MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MatrixDeterminant(M: TMatrix): Single; register;
-
-// Determinant of a 4x4 matrix
-
-var a1, a2, a3, a4,
- b1, b2, b3, b4,
- c1, c2, c3, c4,
- d1, d2, d3, d4 : Single;
-
-begin
- a1 := M[X, X]; b1 := M[X, Y]; c1 := M[X, Z]; d1 := M[X, W];
- a2 := M[Y, X]; b2 := M[Y, Y]; c2 := M[Y, Z]; d2 := M[Y, W];
- a3 := M[Z, X]; b3 := M[Z, Y]; c3 := M[Z, Z]; d3 := M[Z, W];
- a4 := M[W, X]; b4 := M[W, Y]; c4 := M[W, Z]; d4 := M[W, W];
-
- Result := a1 * MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
- b1 * MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
- c1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
- d1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure MatrixScale(var M: TMatrix; Factor: Single); register;
-
-// multiplies all elements of a 4x4 matrix with a factor
-
-var I, J: Integer;
-
-begin
- for I := 0 to 3 do
- for J := 0 to 3 do M[I, J] := M[I, J] * Factor;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure MatrixInvert(var M: TMatrix); register;
-
-// finds the inverse of a 4x4 matrix
-
-var Det: Single;
-
-begin
- Det := MatrixDeterminant(M);
- if Abs(Det) < EPSILON then M := IdentityMatrix
- else
- begin
- MatrixAdjoint(M);
- MatrixScale(M, 1 / Det);
- end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure MatrixTranspose(var M: TMatrix); register;
-
-// computes transpose of 4x4 matrix
-
-var I, J: Integer;
- TM: TMatrix;
-
-begin
- for I := 0 to 3 do
- for J := 0 to 3 do TM[J, I] := M[I, J];
- M := TM;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure MatrixAffineTranspose(var M: TAffineMatrix); register;
-
-// computes transpose of 3x3 matrix
-
-var I, J: Integer;
- TM: TAffineMatrix;
-
-begin
- for I := 0 to 2 do
- for J := 0 to 2 do TM[J, I] := M[I, J];
- M := TM;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MatrixMultiply(M1, M2: TMatrix): TMatrix; register;
-
-// multiplies two 4x4 matrices
-
-var I, J: Integer;
- TM: TMatrix;
-
-begin
- for I := 0 to 3 do
- for J := 0 to 3 do
- TM[I, J] := M1[I, X] * M2[X, J] +
- M1[I, Y] * M2[Y, J] +
- M1[I, Z] * M2[Z, J] +
- M1[I, W] * M2[W, J];
- Result := TM;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateRotationMatrix(Axis: TVector3f; Angle: Single): TMatrix; register;
-
-// Creates a rotation matrix along the given Axis by the given Angle in radians.
-
-var cosine,
- sine,
- Len,
- one_minus_cosine: Extended;
-
-begin
- SinCos(Angle, Sine, Cosine);
- one_minus_cosine := 1 - cosine;
- Len := VectorNormalize(Axis);
-
- if Len = 0 then Result := IdentityMatrix
- else
- begin
- Result[X, X] := (one_minus_cosine * Sqr(Axis[0])) + Cosine;
- Result[X, Y] := (one_minus_cosine * Axis[0] * Axis[1]) - (Axis[2] * Sine);
- Result[X, Z] := (one_minus_cosine * Axis[2] * Axis[0]) + (Axis[1] * Sine);
- Result[X, W] := 0;
-
- Result[Y, X] := (one_minus_cosine * Axis[0] * Axis[1]) + (Axis[2] * Sine);
- Result[Y, Y] := (one_minus_cosine * Sqr(Axis[1])) + Cosine;
- Result[Y, Z] := (one_minus_cosine * Axis[1] * Axis[2]) - (Axis[0] * Sine);
- Result[Y, W] := 0;
-
- Result[Z, X] := (one_minus_cosine * Axis[2] * Axis[0]) - (Axis[1] * Sine);
- Result[Z, Y] := (one_minus_cosine * Axis[1] * Axis[2]) + (Axis[0] * Sine);
- Result[Z, Z] := (one_minus_cosine * Sqr(Axis[2])) + Cosine;
- Result[Z, W] := 0;
-
- Result[W, X] := 0;
- Result[W, Y] := 0;
- Result[W, Z] := 0;
- Result[W, W] := 1;
- end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function ConvertRotation(Angles: TAffineVector): TVector; register;
-
-{ Turn a triplet of rotations about x, y, and z (in that order) into an
- equivalent rotation around a single axis (all in radians).
-
- Rotation of the Angle t about the axis (X, Y, Z) is given by:
-
- | X^2 + (1-X^2) Cos(t), XY(1-Cos(t)) + Z Sin(t), XZ(1-Cos(t))-Y Sin(t) |
- M = | XY(1-Cos(t))-Z Sin(t), Y^2 + (1-Y^2) Cos(t), YZ(1-Cos(t)) + X Sin(t) |
- | XZ(1-Cos(t)) + Y Sin(t), YZ(1-Cos(t))-X Sin(t), Z^2 + (1-Z^2) Cos(t) |
-
- Rotation about the three axes (Angles a1, a2, a3) can be represented as
- the product of the individual rotation matrices:
-
- | 1 0 0 | | Cos(a2) 0 -Sin(a2) | | Cos(a3) Sin(a3) 0 |
- | 0 Cos(a1) Sin(a1) | * | 0 1 0 | * | -Sin(a3) Cos(a3) 0 |
- | 0 -Sin(a1) Cos(a1) | | Sin(a2) 0 Cos(a2) | | 0 0 1 |
- Mx My Mz
-
- We now want to solve for X, Y, Z, and t given 9 equations in 4 unknowns.
- Using the diagonal elements of the two matrices, we get:
-
- X^2 + (1-X^2) Cos(t) = M[0][0]
- Y^2 + (1-Y^2) Cos(t) = M[1][1]
- Z^2 + (1-Z^2) Cos(t) = M[2][2]
-
- Adding the three equations, we get:
-
- X^2 + Y^2 + Z^2 - (M[0][0] + M[1][1] + M[2][2]) =
- - (3 - X^2 - Y^2 - Z^2) Cos(t)
-
- Since (X^2 + Y^2 + Z^2) = 1, we can rewrite as:
-
- Cos(t) = (1 - (M[0][0] + M[1][1] + M[2][2])) / 2
-
- Solving for t, we get:
-
- t = Acos(((M[0][0] + M[1][1] + M[2][2]) - 1) / 2)
-
- We can substitute t into the equations for X^2, Y^2, and Z^2 above
- to get the values for X, Y, and Z. To find the proper signs we note
- that:
-
- 2 X Sin(t) = M[1][2] - M[2][1]
- 2 Y Sin(t) = M[2][0] - M[0][2]
- 2 Z Sin(t) = M[0][1] - M[1][0]
-}
-
-var Axis1, Axis2: TVector3f;
- M, M1, M2: TMatrix;
- cost, cost1,
- sint,
- s1, s2, s3: Single;
- I: Integer;
-
-
-begin
- // see if we are only rotating about a single Axis
- if Abs(Angles[X]) < EPSILON then
- begin
- if Abs(Angles[Y]) < EPSILON then
- begin
- Result := MakeVector([0, 0, 1, Angles[Z]]);
- Exit;
- end
- else
- if Abs(Angles[Z]) < EPSILON then
- begin
- Result := MakeVector([0, 1, 0, Angles[Y]]);
- Exit;
- end
- end
- else
- if (Abs(Angles[Y]) < EPSILON) and
- (Abs(Angles[Z]) < EPSILON) then
- begin
- Result := MakeVector([1, 0, 0, Angles[X]]);
- Exit;
- end;
-
- // make the rotation matrix
- Axis1 := MakeAffineVector([1, 0, 0]);
- M := CreateRotationMatrix(Axis1, Angles[X]);
-
- Axis2 := MakeAffineVector([0, 1, 0]);
- M2 := CreateRotationMatrix(Axis2, Angles[Y]);
- M1 := MatrixMultiply(M, M2);
-
- Axis2 := MakeAffineVector([0, 0, 1]);
- M2 := CreateRotationMatrix(Axis2, Angles[Z]);
- M := MatrixMultiply(M1, M2);
-
- cost := ((M[X, X] + M[Y, Y] + M[Z, Z])-1) / 2;
- if cost < -1 then cost := -1
- else
- if cost > 1 - EPSILON then
- begin
- // Bad Angle - this would cause a crash
- Result := MakeVector([1, 0, 0, 0]);
- Exit;
- end;
-
- cost1 := 1 - cost;
- Result := Makevector([Sqrt((M[X, X]-cost) / cost1),
- Sqrt((M[Y, Y]-cost) / cost1),
- sqrt((M[Z, Z]-cost) / cost1),
- arccos(cost)]);
-
- sint := 2 * Sqrt(1 - cost * cost); // This is actually 2 Sin(t)
-
- // Determine the proper signs
- for I := 0 to 7 do
- begin
- if (I and 1) > 1 then s1 := -1 else s1 := 1;
- if (I and 2) > 1 then s2 := -1 else s2 := 1;
- if (I and 4) > 1 then s3 := -1 else s3 := 1;
- if (Abs(s1 * Result[X] * sint-M[Y, Z] + M[Z, Y]) < EPSILON2) and
- (Abs(s2 * Result[Y] * sint-M[Z, X] + M[X, Z]) < EPSILON2) and
- (Abs(s3 * Result[Z] * sint-M[X, Y] + M[Y, X]) < EPSILON2) then
- begin
- // We found the right combination of signs
- Result[X] := Result[X] * s1;
- Result[Y] := Result[Y] * s2;
- Result[Z] := Result[Z] * s3;
- Exit;
- end;
- end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateRotationMatrixX(Sine, Cosine: Single): TMatrix; register;
-
-// creates matrix for rotation about x-axis
-
-begin
- Result := EmptyMatrix;
- Result[X, X] := 1;
- Result[Y, Y] := Cosine;
- Result[Y, Z] := Sine;
- Result[Z, Y] := -Sine;
- Result[Z, Z] := Cosine;
- Result[W, W] := 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateRotationMatrixY(Sine, Cosine: Single): TMatrix; register;
-
-// creates matrix for rotation about y-axis
-
-begin
- Result := EmptyMatrix;
- Result[X, X] := Cosine;
- Result[X, Z] := -Sine;
- Result[Y, Y] := 1;
- Result[Z, X] := Sine;
- Result[Z, Z] := Cosine;
- Result[W, W] := 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateRotationMatrixZ(Sine, Cosine: Single): TMatrix; register;
-
-// creates matrix for rotation about z-axis
-
-begin
- Result := EmptyMatrix;
- Result[X, X] := Cosine;
- Result[X, Y] := Sine;
- Result[Y, X] := -Sine;
- Result[Y, Y] := Cosine;
- Result[Z, Z] := 1;
- Result[W, W] := 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateScaleMatrix(V: TAffineVector): TMatrix; register;
-
-// creates scaling matrix
-
-begin
- Result := IdentityMatrix;
- Result[X, X] := V[X];
- Result[Y, Y] := V[Y];
- Result[Z, Z] := V[Z];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function CreateTranslationMatrix(V: TVector): TMatrix; register;
-
-// creates translation matrix
-
-begin
- Result := IdentityMatrix;
- Result[W, X] := V[X];
- Result[W, Y] := V[Y];
- Result[W, Z] := V[Z];
- Result[W, W] := V[W];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Lerp(Start, Stop, t: Single): Single;
-
-// calculates linear interpolation between start and stop at point t
-
-begin
- Result := Start + (Stop - Start) * t;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineLerp(V1, V2: TAffineVector; t: Single): TAffineVector;
-
-// calculates linear interpolation between vector1 and vector2 at point t
-
-begin
- Result[X] := Lerp(V1[X], V2[X], t);
- Result[Y] := Lerp(V1[Y], V2[Y], t);
- Result[Z] := Lerp(V1[Z], V2[Z], t);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorLerp(V1, V2: TVector; t: Single): TVector;
-
-// calculates linear interpolation between vector1 and vector2 at point t
-
-begin
- Result[X] := Lerp(V1[X], V2[X], t);
- Result[Y] := Lerp(V1[Y], V2[Y], t);
- Result[Z] := Lerp(V1[Z], V2[Z], t);
- Result[W] := Lerp(V1[W], V2[W], t);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function QuaternionSlerp(QStart, QEnd: TQuaternion; Spin: Integer; t: Single): TQuaternion;
-
-// spherical linear interpolation of unit quaternions with spins
-// QStart, QEnd - start and end unit quaternions
-// t - interpolation parameter (0 to 1)
-// Spin - number of extra spin rotations to involve
-
-var beta, // complementary interp parameter
- theta, // Angle between A and B
- sint, cost, // sine, cosine of theta
- phi: Single; // theta plus spins
- bflip: Boolean; // use negativ t?
-
-
-begin
- // cosine theta
- cost := VectorAngle(QStart.ImagPart, QEnd.ImagPart);
-
- // if QEnd is on opposite hemisphere from QStart, use -QEnd instead
- if cost < 0 then
- begin
- cost := -cost;
- bflip := True;
- end
- else bflip := False;
-
- // if QEnd is (within precision limits) the same as QStart,
- // just linear interpolate between QStart and QEnd.
- // Can't do spins, since we don't know what direction to spin.
-
- if (1 - cost) < EPSILON then beta := 1 - t
- else
- begin
- // normal case
- theta := arccos(cost);
- phi := theta + Spin * Pi;
- sint := sin(theta);
- beta := sin(theta - t * phi) / sint;
- t := sin(t * phi) / sint;
- end;
-
- if bflip then t := -t;
-
- // interpolate
- Result.ImagPart[X] := beta * QStart.ImagPart[X] + t * QEnd.ImagPart[X];
- Result.ImagPart[Y] := beta * QStart.ImagPart[Y] + t * QEnd.ImagPart[Y];
- Result.ImagPart[Z] := beta * QStart.ImagPart[Z] + t * QEnd.ImagPart[Z];
- Result.RealPart := beta * QStart.RealPart + t * QEnd.RealPart;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineCombine(V1, V2: TAffineVector; F1, F2: Single): TAffineVector;
-
-// makes a linear combination of two vectors and return the result
-
-begin
- Result[X] := (F1 * V1[X]) + (F2 * V2[X]);
- Result[Y] := (F1 * V1[Y]) + (F2 * V2[Y]);
- Result[Z] := (F1 * V1[Z]) + (F2 * V2[Z]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorCombine(V1, V2: TVector; F1, F2: Single): TVector;
-
-// makes a linear combination of two vectors and return the result
-
-begin
- Result[X] := (F1 * V1[X]) + (F2 * V2[X]);
- Result[Y] := (F1 * V1[Y]) + (F2 * V2[Y]);
- Result[Z] := (F1 * V1[Z]) + (F2 * V2[Z]);
- Result[W] := (F1 * V1[W]) + (F2 * V2[W]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function MatrixDecompose(M: TMatrix; var Tran: TTransformations): Boolean; register;
-
-// Author: Spencer W. Thomas, University of Michigan
-//
-// MatrixDecompose - Decompose a non-degenerated 4x4 transformation matrix into
-// the sequence of transformations that produced it.
-//
-// The coefficient of each transformation is returned in the corresponding
-// element of the vector Tran.
-//
-// Returns true upon success, false if the matrix is singular.
-
-var I, J: Integer;
- LocMat,
- pmat,
- invpmat,
- tinvpmat: TMatrix;
- prhs,
- psol: TVector;
- Row: array[0..2] of TAffineVector;
-
-begin
- Result := False;
- locmat := M;
- // normalize the matrix
- if locmat[W, W] = 0 then Exit;
- for I := 0 to 3 do
- for J := 0 to 3 do
- locmat[I, J] := locmat[I, J] / locmat[W, W];
-
- // pmat is used to solve for perspective, but it also provides
- // an easy way to test for singularity of the upper 3x3 component.
-
- pmat := locmat;
- for I := 0 to 2 do pmat[I, W] := 0;
- pmat[W, W] := 1;
-
- if MatrixDeterminant(pmat) = 0 then Exit;
-
- // First, isolate perspective. This is the messiest.
- if (locmat[X, W] <> 0) or
- (locmat[Y, W] <> 0) or
- (locmat[Z, W] <> 0) then
- begin
- // prhs is the right hand side of the equation.
- prhs[X] := locmat[X, W];
- prhs[Y] := locmat[Y, W];
- prhs[Z] := locmat[Z, W];
- prhs[W] := locmat[W, W];
-
- // Solve the equation by inverting pmat and multiplying
- // prhs by the inverse. (This is the easiest way, not
- // necessarily the best.)
-
- invpmat := pmat;
- MatrixInvert(invpmat);
- MatrixTranspose(invpmat);
- psol := VectorTransform(prhs, tinvpmat);
-
- // stuff the answer away
- Tran[ttPerspectiveX] := psol[X];
- Tran[ttPerspectiveY] := psol[Y];
- Tran[ttPerspectiveZ] := psol[Z];
- Tran[ttPerspectiveW] := psol[W];
-
- // clear the perspective partition
- locmat[X, W] := 0;
- locmat[Y, W] := 0;
- locmat[Z, W] := 0;
- locmat[W, W] := 1;
- end
- else
- begin
- // no perspective
- Tran[ttPerspectiveX] := 0;
- Tran[ttPerspectiveY] := 0;
- Tran[ttPerspectiveZ] := 0;
- Tran[ttPerspectiveW] := 0;
- end;
-
- // next take care of translation (easy)
- for I := 0 to 2 do
- begin
- Tran[TTransType(Ord(ttTranslateX) + I)] := locmat[W, I];
- locmat[W, I] := 0;
- end;
-
- // now get scale and shear
- for I := 0 to 2 do
- begin
- row[I, X] := locmat[I, X];
- row[I, Y] := locmat[I, Y];
- row[I, Z] := locmat[I, Z];
- end;
-
- // compute X scale factor and normalize first row
- Tran[ttScaleX] := Sqr(VectorNormalize(row[0])); // ml: calculation optimized
-
- // compute XY shear factor and make 2nd row orthogonal to 1st
- Tran[ttShearXY] := VectorAffineDotProduct(row[0], row[1]);
- row[1] := VectorAffineCombine(row[1], row[0], 1, -Tran[ttShearXY]);
-
- // now, compute Y scale and normalize 2nd row
- Tran[ttScaleY] := Sqr(VectorNormalize(row[1])); // ml: calculation optimized
- Tran[ttShearXY] := Tran[ttShearXY]/Tran[ttScaleY];
-
- // compute XZ and YZ shears, orthogonalize 3rd row
- Tran[ttShearXZ] := VectorAffineDotProduct(row[0], row[2]);
- row[2] := VectorAffineCombine(row[2], row[0], 1, -Tran[ttShearXZ]);
- Tran[ttShearYZ] := VectorAffineDotProduct(row[1], row[2]);
- row[2] := VectorAffineCombine(row[2], row[1], 1, -Tran[ttShearYZ]);
-
- // next, get Z scale and normalize 3rd row
- Tran[ttScaleZ] := Sqr(VectorNormalize(row[1])); // (ML) calc. optimized
- Tran[ttShearXZ] := Tran[ttShearXZ] / tran[ttScaleZ];
- Tran[ttShearYZ] := Tran[ttShearYZ] / Tran[ttScaleZ];
-
- // At this point, the matrix (in rows[]) is orthonormal.
- // Check for a coordinate system flip. If the determinant
- // is -1, then negate the matrix and the scaling factors.
- if VectorAffineDotProduct(row[0], VectorCrossProduct(row[1], row[2])) < 0 then
- for I := 0 to 2 do
- begin
- Tran[TTransType(Ord(ttScaleX) + I)] := -Tran[TTransType(Ord(ttScaleX) + I)];
- row[I, X] := -row[I, X];
- row[I, Y] := -row[I, Y];
- row[I, Z] := -row[I, Z];
- end;
-
- // now, get the rotations out, as described in the gem
- Tran[ttRotateY] := arcsin(-row[0, Z]);
- if cos(Tran[ttRotateY]) <> 0 then
- begin
- Tran[ttRotateX] := arctan2(row[1, Z], row[2, Z]);
- Tran[ttRotateZ] := arctan2(row[0, Y], row[0, X]);
- end
- else
- begin
- tran[ttRotateX] := arctan2(row[1, X], row[1, Y]);
- tran[ttRotateZ] := 0;
- end;
- // All done!
- Result := True;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorDblToFlt(V: THomogeneousDblVector): THomogeneousVector; assembler;
-
-// converts a vector containing double sized values into a vector with single sized values
-
-asm
- FLD QWORD PTR [EAX]
- FSTP DWORD PTR [EDX]
- FLD QWORD PTR [EAX + 8]
- FSTP DWORD PTR [EDX + 4]
- FLD QWORD PTR [EAX + 16]
- FSTP DWORD PTR [EDX + 8]
- FLD QWORD PTR [EAX + 24]
- FSTP DWORD PTR [EDX + 12]
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineDblToFlt(V: TAffineDblVector): TAffineVector; assembler;
-
-// converts a vector containing double sized values into a vector with single sized values
-
-asm
- FLD QWORD PTR [EAX]
- FSTP DWORD PTR [EDX]
- FLD QWORD PTR [EAX + 8]
- FSTP DWORD PTR [EDX + 4]
- FLD QWORD PTR [EAX + 16]
- FSTP DWORD PTR [EDX + 8]
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorAffineFltToDbl(V: TAffineVector): TAffineDblVector; assembler;
-
-// converts a vector containing single sized values into a vector with double sized values
-
-asm
- FLD DWORD PTR [EAX]
- FSTP QWORD PTR [EDX]
- FLD DWORD PTR [EAX + 8]
- FSTP QWORD PTR [EDX + 4]
- FLD DWORD PTR [EAX + 16]
- FSTP QWORD PTR [EDX + 8]
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function VectorFltToDbl(V: TVector): THomogeneousDblVector; assembler;
-
-// converts a vector containing single sized values into a vector with double sized values
-
-asm
- FLD DWORD PTR [EAX]
- FSTP QWORD PTR [EDX]
- FLD DWORD PTR [EAX + 8]
- FSTP QWORD PTR [EDX + 4]
- FLD DWORD PTR [EAX + 16]
- FSTP QWORD PTR [EDX + 8]
- FLD DWORD PTR [EAX + 24]
- FSTP QWORD PTR [EDX + 12]
-end;
-
-//----------------- coordinate system manipulation functions -----------------------------------------------------------
-
-function Turn(Matrix: TMatrix; Angle: Single): TMatrix;
-
-// rotates the given coordinate system (represented by the matrix) around its Y-axis
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[1]), Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Turn(Matrix: TMatrix; MasterUp: TAffineVector; Angle: Single): TMatrix;
-
-// rotates the given coordinate system (represented by the matrix) around MasterUp
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterUp, Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Pitch(Matrix: TMatrix; Angle: Single): TMatrix;
-
-// rotates the given coordinate system (represented by the matrix) around its X-axis
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[0]), Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Pitch(Matrix: TMatrix; MasterRight: TAffineVector; Angle: Single): TMatrix; overload;
-
-// rotates the given coordinate system (represented by the matrix) around MasterRight
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterRight, Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Roll(Matrix: TMatrix; Angle: Single): TMatrix;
-
-// rotates the given coordinate system (represented by the matrix) around its Z-axis
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[2]), Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function Roll(Matrix: TMatrix; MasterDirection: TAffineVector; Angle: Single): TMatrix; overload;
-
-// rotates the given coordinate system (represented by the matrix) around MasterDirection
-
-begin
- Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterDirection, Angle));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-end.
-
-
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/gl.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/gl.pas
deleted file mode 100644
index 2dc99df5..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/gl.pas
+++ /dev/null
@@ -1,2301 +0,0 @@
-unit gl;
-{
- $Id: gl.pas,v 1.5 2007/05/20 20:28:31 savage Exp $
-
- Adaption of the delphi3d.net OpenGL units to FreePascal
- Sebastian Guenther (sg@freepascal.org) in 2002
- These units are free to use
-}
-
-(*++ BUILD Version: 0004 // Increment this if a change has global effects
-
-Copyright (c) 1985-96, Microsoft Corporation
-
-Module Name:
-
- gl.h
-
-Abstract:
-
- Procedure declarations, constant definitions and macros for the OpenGL
- component.
-
---*)
-
-(*
-** Copyright 1996 Silicon Graphics, Inc.
-** All Rights Reserved.
-**
-** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
-** the contents of this file may not be disclosed to third parties, copied or
-** duplicated in any form, in whole or in part, without the prior written
-** permission of Silicon Graphics, Inc.
-**
-** RESTRICTED RIGHTS LEGEND:
-** Use, duplication or disclosure by the Government is subject to restrictions
-** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
-** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
-** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
-** rights reserved under the Copyright Laws of the United States.
-*)
-
-{******************************************************************************}
-{ }
-{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
-{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
-{ }
-{ Modified for Delphi/Kylix and FreePascal }
-{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
-{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
-{ }
-{******************************************************************************}
-
-{
- $Log: gl.pas,v $
- Revision 1.5 2007/05/20 20:28:31 savage
- Initial Changes to Handle 64 Bits
-
- Revision 1.4 2006/11/20 21:20:59 savage
- Updated to work in MacOS X
-
- Revision 1.3 2005/05/22 18:52:09 savage
- Changes as suggested by Michalis Kamburelis. Thanks again.
-
- Revision 1.2 2004/08/14 22:54:30 savage
- Updated so that Library name defines are correctly defined for MacOS X.
-
- Revision 1.1 2004/03/30 21:53:54 savage
- Moved to it's own folder.
-
- Revision 1.4 2004/02/20 17:09:55 savage
- Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
-
- Revision 1.3 2004/02/14 00:23:39 savage
- As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
-
- Revision 1.2 2004/02/14 00:09:18 savage
- Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
- Revision 1.6 2003/06/02 12:32:12 savage
- Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-uses
-{$IFDEF __GPC__}
- system,
- gpc,
-{$ENDIF}
-
-{$IFDEF WINDOWS}
- Windows,
-{$ENDIF}
- moduleloader;
-
-
-var
- LibGL: TModuleHandle;
-
-type
- GLenum = Cardinal; PGLenum = ^GLenum;
- GLboolean = Byte; PGLboolean = ^GLboolean;
- GLbitfield = Cardinal; PGLbitfield = ^GLbitfield;
- GLbyte = ShortInt; PGLbyte = ^GLbyte;
- GLshort = SmallInt; PGLshort = ^GLshort;
- GLint = Integer; PGLint = ^GLint;
- GLsizei = Integer; PGLsizei = ^GLsizei;
- GLubyte = Byte; PGLubyte = ^GLubyte;
- GLushort = Word; PGLushort = ^GLushort;
- GLuint = Cardinal; PGLuint = ^GLuint;
- GLfloat = Single; PGLfloat = ^GLfloat;
- GLclampf = Single; PGLclampf = ^GLclampf;
- GLdouble = Double; PGLdouble = ^GLdouble;
- GLclampd = Double; PGLclampd = ^GLclampd;
-{ GLvoid = void; } PGLvoid = Pointer;
-
-{******************************************************************************}
-
-const
-{$IFDEF WINDOWS}
- GLLibName = 'OpenGL32.dll';
-{$ENDIF}
-
-{$IFDEF UNIX}
-{$IFDEF DARWIN}
- GLLibName = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib';
-{$ELSE}
- GLLibName = 'libGL.so';
-{$ENDIF}
-{$ENDIF}
-
- // Version
- GL_VERSION_1_1 = 1;
-
- // AccumOp
- GL_ACCUM = $0100;
- GL_LOAD = $0101;
- GL_RETURN = $0102;
- GL_MULT = $0103;
- GL_ADD = $0104;
-
- // AlphaFunction
- GL_NEVER = $0200;
- GL_LESS = $0201;
- GL_EQUAL = $0202;
- GL_LEQUAL = $0203;
- GL_GREATER = $0204;
- GL_NOTEQUAL = $0205;
- GL_GEQUAL = $0206;
- GL_ALWAYS = $0207;
-
- // AttribMask
- GL_CURRENT_BIT = $00000001;
- GL_POINT_BIT = $00000002;
- GL_LINE_BIT = $00000004;
- GL_POLYGON_BIT = $00000008;
- GL_POLYGON_STIPPLE_BIT = $00000010;
- GL_PIXEL_MODE_BIT = $00000020;
- GL_LIGHTING_BIT = $00000040;
- GL_FOG_BIT = $00000080;
- GL_DEPTH_BUFFER_BIT = $00000100;
- GL_ACCUM_BUFFER_BIT = $00000200;
- GL_STENCIL_BUFFER_BIT = $00000400;
- GL_VIEWPORT_BIT = $00000800;
- GL_TRANSFORM_BIT = $00001000;
- GL_ENABLE_BIT = $00002000;
- GL_COLOR_BUFFER_BIT = $00004000;
- GL_HINT_BIT = $00008000;
- GL_EVAL_BIT = $00010000;
- GL_LIST_BIT = $00020000;
- GL_TEXTURE_BIT = $00040000;
- GL_SCISSOR_BIT = $00080000;
- GL_ALL_ATTRIB_BITS = $000FFFFF;
-
- // BeginMode
- GL_POINTS = $0000;
- GL_LINES = $0001;
- GL_LINE_LOOP = $0002;
- GL_LINE_STRIP = $0003;
- GL_TRIANGLES = $0004;
- GL_TRIANGLE_STRIP = $0005;
- GL_TRIANGLE_FAN = $0006;
- GL_QUADS = $0007;
- GL_QUAD_STRIP = $0008;
- GL_POLYGON = $0009;
-
- // BlendingFactorDest
- GL_ZERO = 0;
- GL_ONE = 1;
- GL_SRC_COLOR = $0300;
- GL_ONE_MINUS_SRC_COLOR = $0301;
- GL_SRC_ALPHA = $0302;
- GL_ONE_MINUS_SRC_ALPHA = $0303;
- GL_DST_ALPHA = $0304;
- GL_ONE_MINUS_DST_ALPHA = $0305;
-
- // BlendingFactorSrc
- // GL_ZERO
- // GL_ONE
- GL_DST_COLOR = $0306;
- GL_ONE_MINUS_DST_COLOR = $0307;
- GL_SRC_ALPHA_SATURATE = $0308;
- // GL_SRC_ALPHA
- // GL_ONE_MINUS_SRC_ALPHA
- // GL_DST_ALPHA
- // GL_ONE_MINUS_DST_ALPHA
-
- // Boolean
- GL_TRUE = 1;
- GL_FALSE = 0;
-
- // ClearBufferMask
- // GL_COLOR_BUFFER_BIT
- // GL_ACCUM_BUFFER_BIT
- // GL_STENCIL_BUFFER_BIT
- // GL_DEPTH_BUFFER_BIT
-
- // ClientArrayType
- // GL_VERTEX_ARRAY
- // GL_NORMAL_ARRAY
- // GL_COLOR_ARRAY
- // GL_INDEX_ARRAY
- // GL_TEXTURE_COORD_ARRAY
- // GL_EDGE_FLAG_ARRAY
-
- // ClipPlaneName
- GL_CLIP_PLANE0 = $3000;
- GL_CLIP_PLANE1 = $3001;
- GL_CLIP_PLANE2 = $3002;
- GL_CLIP_PLANE3 = $3003;
- GL_CLIP_PLANE4 = $3004;
- GL_CLIP_PLANE5 = $3005;
-
- // ColorMaterialFace
- // GL_FRONT
- // GL_BACK
- // GL_FRONT_AND_BACK
-
- // ColorMaterialParameter
- // GL_AMBIENT
- // GL_DIFFUSE
- // GL_SPECULAR
- // GL_EMISSION
- // GL_AMBIENT_AND_DIFFUSE
-
- // ColorPointerType
- // GL_BYTE
- // GL_UNSIGNED_BYTE
- // GL_SHORT
- // GL_UNSIGNED_SHORT
- // GL_INT
- // GL_UNSIGNED_INT
- // GL_FLOAT
- // GL_DOUBLE
-
- // CullFaceMode
- // GL_FRONT
- // GL_BACK
- // GL_FRONT_AND_BACK
-
- // DataType
- GL_BYTE = $1400;
- GL_UNSIGNED_BYTE = $1401;
- GL_SHORT = $1402;
- GL_UNSIGNED_SHORT = $1403;
- GL_INT = $1404;
- GL_UNSIGNED_INT = $1405;
- GL_FLOAT = $1406;
- GL_2_BYTES = $1407;
- GL_3_BYTES = $1408;
- GL_4_BYTES = $1409;
- GL_DOUBLE = $140A;
-
- // DepthFunction
- // GL_NEVER
- // GL_LESS
- // GL_EQUAL
- // GL_LEQUAL
- // GL_GREATER
- // GL_NOTEQUAL
- // GL_GEQUAL
- // GL_ALWAYS
-
- // DrawBufferMode
- GL_NONE = 0;
- GL_FRONT_LEFT = $0400;
- GL_FRONT_RIGHT = $0401;
- GL_BACK_LEFT = $0402;
- GL_BACK_RIGHT = $0403;
- GL_FRONT = $0404;
- GL_BACK = $0405;
- GL_LEFT = $0406;
- GL_RIGHT = $0407;
- GL_FRONT_AND_BACK = $0408;
- GL_AUX0 = $0409;
- GL_AUX1 = $040A;
- GL_AUX2 = $040B;
- GL_AUX3 = $040C;
-
- // Enable
- // GL_FOG
- // GL_LIGHTING
- // GL_TEXTURE_1D
- // GL_TEXTURE_2D
- // GL_LINE_STIPPLE
- // GL_POLYGON_STIPPLE
- // GL_CULL_FACE
- // GL_ALPHA_TEST
- // GL_BLEND
- // GL_INDEX_LOGIC_OP
- // GL_COLOR_LOGIC_OP
- // GL_DITHER
- // GL_STENCIL_TEST
- // GL_DEPTH_TEST
- // GL_CLIP_PLANE0
- // GL_CLIP_PLANE1
- // GL_CLIP_PLANE2
- // GL_CLIP_PLANE3
- // GL_CLIP_PLANE4
- // GL_CLIP_PLANE5
- // GL_LIGHT0
- // GL_LIGHT1
- // GL_LIGHT2
- // GL_LIGHT3
- // GL_LIGHT4
- // GL_LIGHT5
- // GL_LIGHT6
- // GL_LIGHT7
- // GL_TEXTURE_GEN_S
- // GL_TEXTURE_GEN_T
- // GL_TEXTURE_GEN_R
- // GL_TEXTURE_GEN_Q
- // GL_MAP1_VERTEX_3
- // GL_MAP1_VERTEX_4
- // GL_MAP1_COLOR_4
- // GL_MAP1_INDEX
- // GL_MAP1_NORMAL
- // GL_MAP1_TEXTURE_COORD_1
- // GL_MAP1_TEXTURE_COORD_2
- // GL_MAP1_TEXTURE_COORD_3
- // GL_MAP1_TEXTURE_COORD_4
- // GL_MAP2_VERTEX_3
- // GL_MAP2_VERTEX_4
- // GL_MAP2_COLOR_4
- // GL_MAP2_INDEX
- // GL_MAP2_NORMAL
- // GL_MAP2_TEXTURE_COORD_1
- // GL_MAP2_TEXTURE_COORD_2
- // GL_MAP2_TEXTURE_COORD_3
- // GL_MAP2_TEXTURE_COORD_4
- // GL_POINT_SMOOTH
- // GL_LINE_SMOOTH
- // GL_POLYGON_SMOOTH
- // GL_SCISSOR_TEST
- // GL_COLOR_MATERIAL
- // GL_NORMALIZE
- // GL_AUTO_NORMAL
- // GL_VERTEX_ARRAY
- // GL_NORMAL_ARRAY
- // GL_COLOR_ARRAY
- // GL_INDEX_ARRAY
- // GL_TEXTURE_COORD_ARRAY
- // GL_EDGE_FLAG_ARRAY
- // GL_POLYGON_OFFSET_POINT
- // GL_POLYGON_OFFSET_LINE
- // GL_POLYGON_OFFSET_FILL
-
- // ErrorCode
- GL_NO_ERROR = 0;
- GL_INVALID_ENUM = $0500;
- GL_INVALID_VALUE = $0501;
- GL_INVALID_OPERATION = $0502;
- GL_STACK_OVERFLOW = $0503;
- GL_STACK_UNDERFLOW = $0504;
- GL_OUT_OF_MEMORY = $0505;
-
- // FeedBackMode
- GL_2D = $0600;
- GL_3D = $0601;
- GL_3D_COLOR = $0602;
- GL_3D_COLOR_TEXTURE = $0603;
- GL_4D_COLOR_TEXTURE = $0604;
-
- // FeedBackToken
- GL_PASS_THROUGH_TOKEN = $0700;
- GL_POINT_TOKEN = $0701;
- GL_LINE_TOKEN = $0702;
- GL_POLYGON_TOKEN = $0703;
- GL_BITMAP_TOKEN = $0704;
- GL_DRAW_PIXEL_TOKEN = $0705;
- GL_COPY_PIXEL_TOKEN = $0706;
- GL_LINE_RESET_TOKEN = $0707;
-
- // FogMode
- // GL_LINEAR
- GL_EXP = $0800;
- GL_EXP2 = $0801;
-
- // FogParameter
- // GL_FOG_COLOR
- // GL_FOG_DENSITY
- // GL_FOG_END
- // GL_FOG_INDEX
- // GL_FOG_MODE
- // GL_FOG_START
-
- // FrontFaceDirection
- GL_CW = $0900;
- GL_CCW = $0901;
-
- // GetMapTarget
- GL_COEFF = $0A00;
- GL_ORDER = $0A01;
- GL_DOMAIN = $0A02;
-
- // GetPixelMap
- // GL_PIXEL_MAP_I_TO_I
- // GL_PIXEL_MAP_S_TO_S
- // GL_PIXEL_MAP_I_TO_R
- // GL_PIXEL_MAP_I_TO_G
- // GL_PIXEL_MAP_I_TO_B
- // GL_PIXEL_MAP_I_TO_A
- // GL_PIXEL_MAP_R_TO_R
- // GL_PIXEL_MAP_G_TO_G
- // GL_PIXEL_MAP_B_TO_B
- // GL_PIXEL_MAP_A_TO_A
-
- // GetPointerTarget
- // GL_VERTEX_ARRAY_POINTER
- // GL_NORMAL_ARRAY_POINTER
- // GL_COLOR_ARRAY_POINTER
- // GL_INDEX_ARRAY_POINTER
- // GL_TEXTURE_COORD_ARRAY_POINTER
- // GL_EDGE_FLAG_ARRAY_POINTER
-
- // GetTarget
- GL_CURRENT_COLOR = $0B00;
- GL_CURRENT_INDEX = $0B01;
- GL_CURRENT_NORMAL = $0B02;
- GL_CURRENT_TEXTURE_COORDS = $0B03;
- GL_CURRENT_RASTER_COLOR = $0B04;
- GL_CURRENT_RASTER_INDEX = $0B05;
- GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06;
- GL_CURRENT_RASTER_POSITION = $0B07;
- GL_CURRENT_RASTER_POSITION_VALID = $0B08;
- GL_CURRENT_RASTER_DISTANCE = $0B09;
- GL_POINT_SMOOTH = $0B10;
- GL_POINT_SIZE = $0B11;
- GL_POINT_SIZE_RANGE = $0B12;
- GL_POINT_SIZE_GRANULARITY = $0B13;
- GL_LINE_SMOOTH = $0B20;
- GL_LINE_WIDTH = $0B21;
- GL_LINE_WIDTH_RANGE = $0B22;
- GL_LINE_WIDTH_GRANULARITY = $0B23;
- GL_LINE_STIPPLE = $0B24;
- GL_LINE_STIPPLE_PATTERN = $0B25;
- GL_LINE_STIPPLE_REPEAT = $0B26;
- GL_LIST_MODE = $0B30;
- GL_MAX_LIST_NESTING = $0B31;
- GL_LIST_BASE = $0B32;
- GL_LIST_INDEX = $0B33;
- GL_POLYGON_MODE = $0B40;
- GL_POLYGON_SMOOTH = $0B41;
- GL_POLYGON_STIPPLE = $0B42;
- GL_EDGE_FLAG = $0B43;
- GL_CULL_FACE = $0B44;
- GL_CULL_FACE_MODE = $0B45;
- GL_FRONT_FACE = $0B46;
- GL_LIGHTING = $0B50;
- GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51;
- GL_LIGHT_MODEL_TWO_SIDE = $0B52;
- GL_LIGHT_MODEL_AMBIENT = $0B53;
- GL_SHADE_MODEL = $0B54;
- GL_COLOR_MATERIAL_FACE = $0B55;
- GL_COLOR_MATERIAL_PARAMETER = $0B56;
- GL_COLOR_MATERIAL = $0B57;
- GL_FOG = $0B60;
- GL_FOG_INDEX = $0B61;
- GL_FOG_DENSITY = $0B62;
- GL_FOG_START = $0B63;
- GL_FOG_END = $0B64;
- GL_FOG_MODE = $0B65;
- GL_FOG_COLOR = $0B66;
- GL_DEPTH_RANGE = $0B70;
- GL_DEPTH_TEST = $0B71;
- GL_DEPTH_WRITEMASK = $0B72;
- GL_DEPTH_CLEAR_VALUE = $0B73;
- GL_DEPTH_FUNC = $0B74;
- GL_ACCUM_CLEAR_VALUE = $0B80;
- GL_STENCIL_TEST = $0B90;
- GL_STENCIL_CLEAR_VALUE = $0B91;
- GL_STENCIL_FUNC = $0B92;
- GL_STENCIL_VALUE_MASK = $0B93;
- GL_STENCIL_FAIL = $0B94;
- GL_STENCIL_PASS_DEPTH_FAIL = $0B95;
- GL_STENCIL_PASS_DEPTH_PASS = $0B96;
- GL_STENCIL_REF = $0B97;
- GL_STENCIL_WRITEMASK = $0B98;
- GL_MATRIX_MODE = $0BA0;
- GL_NORMALIZE = $0BA1;
- GL_VIEWPORT = $0BA2;
- GL_MODELVIEW_STACK_DEPTH = $0BA3;
- GL_PROJECTION_STACK_DEPTH = $0BA4;
- GL_TEXTURE_STACK_DEPTH = $0BA5;
- GL_MODELVIEW_MATRIX = $0BA6;
- GL_PROJECTION_MATRIX = $0BA7;
- GL_TEXTURE_MATRIX = $0BA8;
- GL_ATTRIB_STACK_DEPTH = $0BB0;
- GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1;
- GL_ALPHA_TEST = $0BC0;
- GL_ALPHA_TEST_FUNC = $0BC1;
- GL_ALPHA_TEST_REF = $0BC2;
- GL_DITHER = $0BD0;
- GL_BLEND_DST = $0BE0;
- GL_BLEND_SRC = $0BE1;
- GL_BLEND = $0BE2;
- GL_LOGIC_OP_MODE = $0BF0;
- GL_INDEX_LOGIC_OP = $0BF1;
- GL_COLOR_LOGIC_OP = $0BF2;
- GL_AUX_BUFFERS = $0C00;
- GL_DRAW_BUFFER = $0C01;
- GL_READ_BUFFER = $0C02;
- GL_SCISSOR_BOX = $0C10;
- GL_SCISSOR_TEST = $0C11;
- GL_INDEX_CLEAR_VALUE = $0C20;
- GL_INDEX_WRITEMASK = $0C21;
- GL_COLOR_CLEAR_VALUE = $0C22;
- GL_COLOR_WRITEMASK = $0C23;
- GL_INDEX_MODE = $0C30;
- GL_RGBA_MODE = $0C31;
- GL_DOUBLEBUFFER = $0C32;
- GL_STEREO = $0C33;
- GL_RENDER_MODE = $0C40;
- GL_PERSPECTIVE_CORRECTION_HINT = $0C50;
- GL_POINT_SMOOTH_HINT = $0C51;
- GL_LINE_SMOOTH_HINT = $0C52;
- GL_POLYGON_SMOOTH_HINT = $0C53;
- GL_FOG_HINT = $0C54;
- GL_TEXTURE_GEN_S = $0C60;
- GL_TEXTURE_GEN_T = $0C61;
- GL_TEXTURE_GEN_R = $0C62;
- GL_TEXTURE_GEN_Q = $0C63;
- GL_PIXEL_MAP_I_TO_I = $0C70;
- GL_PIXEL_MAP_S_TO_S = $0C71;
- GL_PIXEL_MAP_I_TO_R = $0C72;
- GL_PIXEL_MAP_I_TO_G = $0C73;
- GL_PIXEL_MAP_I_TO_B = $0C74;
- GL_PIXEL_MAP_I_TO_A = $0C75;
- GL_PIXEL_MAP_R_TO_R = $0C76;
- GL_PIXEL_MAP_G_TO_G = $0C77;
- GL_PIXEL_MAP_B_TO_B = $0C78;
- GL_PIXEL_MAP_A_TO_A = $0C79;
- GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0;
- GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1;
- GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2;
- GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3;
- GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4;
- GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5;
- GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6;
- GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7;
- GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8;
- GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9;
- GL_UNPACK_SWAP_BYTES = $0CF0;
- GL_UNPACK_LSB_FIRST = $0CF1;
- GL_UNPACK_ROW_LENGTH = $0CF2;
- GL_UNPACK_SKIP_ROWS = $0CF3;
- GL_UNPACK_SKIP_PIXELS = $0CF4;
- GL_UNPACK_ALIGNMENT = $0CF5;
- GL_PACK_SWAP_BYTES = $0D00;
- GL_PACK_LSB_FIRST = $0D01;
- GL_PACK_ROW_LENGTH = $0D02;
- GL_PACK_SKIP_ROWS = $0D03;
- GL_PACK_SKIP_PIXELS = $0D04;
- GL_PACK_ALIGNMENT = $0D05;
- GL_MAP_COLOR = $0D10;
- GL_MAP_STENCIL = $0D11;
- GL_INDEX_SHIFT = $0D12;
- GL_INDEX_OFFSET = $0D13;
- GL_RED_SCALE = $0D14;
- GL_RED_BIAS = $0D15;
- GL_ZOOM_X = $0D16;
- GL_ZOOM_Y = $0D17;
- GL_GREEN_SCALE = $0D18;
- GL_GREEN_BIAS = $0D19;
- GL_BLUE_SCALE = $0D1A;
- GL_BLUE_BIAS = $0D1B;
- GL_ALPHA_SCALE = $0D1C;
- GL_ALPHA_BIAS = $0D1D;
- GL_DEPTH_SCALE = $0D1E;
- GL_DEPTH_BIAS = $0D1F;
- GL_MAX_EVAL_ORDER = $0D30;
- GL_MAX_LIGHTS = $0D31;
- GL_MAX_CLIP_PLANES = $0D32;
- GL_MAX_TEXTURE_SIZE = $0D33;
- GL_MAX_PIXEL_MAP_TABLE = $0D34;
- GL_MAX_ATTRIB_STACK_DEPTH = $0D35;
- GL_MAX_MODELVIEW_STACK_DEPTH = $0D36;
- GL_MAX_NAME_STACK_DEPTH = $0D37;
- GL_MAX_PROJECTION_STACK_DEPTH = $0D38;
- GL_MAX_TEXTURE_STACK_DEPTH = $0D39;
- GL_MAX_VIEWPORT_DIMS = $0D3A;
- GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B;
- GL_SUBPIXEL_BITS = $0D50;
- GL_INDEX_BITS = $0D51;
- GL_RED_BITS = $0D52;
- GL_GREEN_BITS = $0D53;
- GL_BLUE_BITS = $0D54;
- GL_ALPHA_BITS = $0D55;
- GL_DEPTH_BITS = $0D56;
- GL_STENCIL_BITS = $0D57;
- GL_ACCUM_RED_BITS = $0D58;
- GL_ACCUM_GREEN_BITS = $0D59;
- GL_ACCUM_BLUE_BITS = $0D5A;
- GL_ACCUM_ALPHA_BITS = $0D5B;
- GL_NAME_STACK_DEPTH = $0D70;
- GL_AUTO_NORMAL = $0D80;
- GL_MAP1_COLOR_4 = $0D90;
- GL_MAP1_INDEX = $0D91;
- GL_MAP1_NORMAL = $0D92;
- GL_MAP1_TEXTURE_COORD_1 = $0D93;
- GL_MAP1_TEXTURE_COORD_2 = $0D94;
- GL_MAP1_TEXTURE_COORD_3 = $0D95;
- GL_MAP1_TEXTURE_COORD_4 = $0D96;
- GL_MAP1_VERTEX_3 = $0D97;
- GL_MAP1_VERTEX_4 = $0D98;
- GL_MAP2_COLOR_4 = $0DB0;
- GL_MAP2_INDEX = $0DB1;
- GL_MAP2_NORMAL = $0DB2;
- GL_MAP2_TEXTURE_COORD_1 = $0DB3;
- GL_MAP2_TEXTURE_COORD_2 = $0DB4;
- GL_MAP2_TEXTURE_COORD_3 = $0DB5;
- GL_MAP2_TEXTURE_COORD_4 = $0DB6;
- GL_MAP2_VERTEX_3 = $0DB7;
- GL_MAP2_VERTEX_4 = $0DB8;
- GL_MAP1_GRID_DOMAIN = $0DD0;
- GL_MAP1_GRID_SEGMENTS = $0DD1;
- GL_MAP2_GRID_DOMAIN = $0DD2;
- GL_MAP2_GRID_SEGMENTS = $0DD3;
- GL_TEXTURE_1D = $0DE0;
- GL_TEXTURE_2D = $0DE1;
- GL_FEEDBACK_BUFFER_POINTER = $0DF0;
- GL_FEEDBACK_BUFFER_SIZE = $0DF1;
- GL_FEEDBACK_BUFFER_TYPE = $0DF2;
- GL_SELECTION_BUFFER_POINTER = $0DF3;
- GL_SELECTION_BUFFER_SIZE = $0DF4;
- // GL_TEXTURE_BINDING_1D
- // GL_TEXTURE_BINDING_2D
- // GL_VERTEX_ARRAY
- // GL_NORMAL_ARRAY
- // GL_COLOR_ARRAY
- // GL_INDEX_ARRAY
- // GL_TEXTURE_COORD_ARRAY
- // GL_EDGE_FLAG_ARRAY
- // GL_VERTEX_ARRAY_SIZE
- // GL_VERTEX_ARRAY_TYPE
- // GL_VERTEX_ARRAY_STRIDE
- // GL_NORMAL_ARRAY_TYPE
- // GL_NORMAL_ARRAY_STRIDE
- // GL_COLOR_ARRAY_SIZE
- // GL_COLOR_ARRAY_TYPE
- // GL_COLOR_ARRAY_STRIDE
- // GL_INDEX_ARRAY_TYPE
- // GL_INDEX_ARRAY_STRIDE
- // GL_TEXTURE_COORD_ARRAY_SIZE
- // GL_TEXTURE_COORD_ARRAY_TYPE
- // GL_TEXTURE_COORD_ARRAY_STRIDE
- // GL_EDGE_FLAG_ARRAY_STRIDE
- // GL_POLYGON_OFFSET_FACTOR
- // GL_POLYGON_OFFSET_UNITS
-
- // GetTextureParameter
- // GL_TEXTURE_MAG_FILTER
- // GL_TEXTURE_MIN_FILTER
- // GL_TEXTURE_WRAP_S
- // GL_TEXTURE_WRAP_T
- GL_TEXTURE_WIDTH = $1000;
- GL_TEXTURE_HEIGHT = $1001;
- GL_TEXTURE_INTERNAL_FORMAT = $1003;
- GL_TEXTURE_BORDER_COLOR = $1004;
- GL_TEXTURE_BORDER = $1005;
- // GL_TEXTURE_RED_SIZE
- // GL_TEXTURE_GREEN_SIZE
- // GL_TEXTURE_BLUE_SIZE
- // GL_TEXTURE_ALPHA_SIZE
- // GL_TEXTURE_LUMINANCE_SIZE
- // GL_TEXTURE_INTENSITY_SIZE
- // GL_TEXTURE_PRIORITY
- // GL_TEXTURE_RESIDENT
-
- // HintMode
- GL_DONT_CARE = $1100;
- GL_FASTEST = $1101;
- GL_NICEST = $1102;
-
- // HintTarget
- // GL_PERSPECTIVE_CORRECTION_HINT
- // GL_POINT_SMOOTH_HINT
- // GL_LINE_SMOOTH_HINT
- // GL_POLYGON_SMOOTH_HINT
- // GL_FOG_HINT
-
- // IndexPointerType
- // GL_SHORT
- // GL_INT
- // GL_FLOAT
- // GL_DOUBLE
-
- // LightModelParameter
- // GL_LIGHT_MODEL_AMBIENT
- // GL_LIGHT_MODEL_LOCAL_VIEWER
- // GL_LIGHT_MODEL_TWO_SIDE
-
- // LightName
- GL_LIGHT0 = $4000;
- GL_LIGHT1 = $4001;
- GL_LIGHT2 = $4002;
- GL_LIGHT3 = $4003;
- GL_LIGHT4 = $4004;
- GL_LIGHT5 = $4005;
- GL_LIGHT6 = $4006;
- GL_LIGHT7 = $4007;
-
- // LightParameter
- GL_AMBIENT = $1200;
- GL_DIFFUSE = $1201;
- GL_SPECULAR = $1202;
- GL_POSITION = $1203;
- GL_SPOT_DIRECTION = $1204;
- GL_SPOT_EXPONENT = $1205;
- GL_SPOT_CUTOFF = $1206;
- GL_CONSTANT_ATTENUATION = $1207;
- GL_LINEAR_ATTENUATION = $1208;
- GL_QUADRATIC_ATTENUATION = $1209;
-
- // InterleavedArrays
- // GL_V2F
- // GL_V3F
- // GL_C4UB_V2F
- // GL_C4UB_V3F
- // GL_C3F_V3F
- // GL_N3F_V3F
- // GL_C4F_N3F_V3F
- // GL_T2F_V3F
- // GL_T4F_V4F
- // GL_T2F_C4UB_V3F
- // GL_T2F_C3F_V3F
- // GL_T2F_N3F_V3F
- // GL_T2F_C4F_N3F_V3F
- // GL_T4F_C4F_N3F_V4F
-
- // ListMode
- GL_COMPILE = $1300;
- GL_COMPILE_AND_EXECUTE = $1301;
-
- // ListNameType
- // GL_BYTE
- // GL_UNSIGNED_BYTE
- // GL_SHORT
- // GL_UNSIGNED_SHORT
- // GL_INT
- // GL_UNSIGNED_INT
- // GL_FLOAT
- // GL_2_BYTES
- // GL_3_BYTES
- // GL_4_BYTES
-
- // LogicOp
- GL_CLEAR = $1500;
- GL_AND = $1501;
- GL_AND_REVERSE = $1502;
- GL_COPY = $1503;
- GL_AND_INVERTED = $1504;
- GL_NOOP = $1505;
- GL_XOR = $1506;
- GL_OR = $1507;
- GL_NOR = $1508;
- GL_EQUIV = $1509;
- GL_INVERT = $150A;
- GL_OR_REVERSE = $150B;
- GL_COPY_INVERTED = $150C;
- GL_OR_INVERTED = $150D;
- GL_NAND = $150E;
- GL_SET = $150F;
-
- // MapTarget
- // GL_MAP1_COLOR_4
- // GL_MAP1_INDEX
- // GL_MAP1_NORMAL
- // GL_MAP1_TEXTURE_COORD_1
- // GL_MAP1_TEXTURE_COORD_2
- // GL_MAP1_TEXTURE_COORD_3
- // GL_MAP1_TEXTURE_COORD_4
- // GL_MAP1_VERTEX_3
- // GL_MAP1_VERTEX_4
- // GL_MAP2_COLOR_4
- // GL_MAP2_INDEX
- // GL_MAP2_NORMAL
- // GL_MAP2_TEXTURE_COORD_1
- // GL_MAP2_TEXTURE_COORD_2
- // GL_MAP2_TEXTURE_COORD_3
- // GL_MAP2_TEXTURE_COORD_4
- // GL_MAP2_VERTEX_3
- // GL_MAP2_VERTEX_4
-
- // MaterialFace
- // GL_FRONT
- // GL_BACK
- // GL_FRONT_AND_BACK
-
- // MaterialParameter
- GL_EMISSION = $1600;
- GL_SHININESS = $1601;
- GL_AMBIENT_AND_DIFFUSE = $1602;
- GL_COLOR_INDEXES = $1603;
- // GL_AMBIENT
- // GL_DIFFUSE
- // GL_SPECULAR
-
- // MatrixMode
- GL_MODELVIEW = $1700;
- GL_PROJECTION = $1701;
- GL_TEXTURE = $1702;
-
- // MeshMode1
- // GL_POINT
- // GL_LINE
-
- // MeshMode2
- // GL_POINT
- // GL_LINE
- // GL_FILL
-
- // NormalPointerType
- // GL_BYTE
- // GL_SHORT
- // GL_INT
- // GL_FLOAT
- // GL_DOUBLE
-
- // PixelCopyType
- GL_COLOR = $1800;
- GL_DEPTH = $1801;
- GL_STENCIL = $1802;
-
- // PixelFormat
- GL_COLOR_INDEX = $1900;
- GL_STENCIL_INDEX = $1901;
- GL_DEPTH_COMPONENT = $1902;
- GL_RED = $1903;
- GL_GREEN = $1904;
- GL_BLUE = $1905;
- GL_ALPHA = $1906;
- GL_RGB = $1907;
- GL_RGBA = $1908;
- GL_LUMINANCE = $1909;
- GL_LUMINANCE_ALPHA = $190A;
-
- // PixelMap
- // GL_PIXEL_MAP_I_TO_I
- // GL_PIXEL_MAP_S_TO_S
- // GL_PIXEL_MAP_I_TO_R
- // GL_PIXEL_MAP_I_TO_G
- // GL_PIXEL_MAP_I_TO_B
- // GL_PIXEL_MAP_I_TO_A
- // GL_PIXEL_MAP_R_TO_R
- // GL_PIXEL_MAP_G_TO_G
- // GL_PIXEL_MAP_B_TO_B
- // GL_PIXEL_MAP_A_TO_A
-
- // PixelStore
- // GL_UNPACK_SWAP_BYTES
- // GL_UNPACK_LSB_FIRST
- // GL_UNPACK_ROW_LENGTH
- // GL_UNPACK_SKIP_ROWS
- // GL_UNPACK_SKIP_PIXELS
- // GL_UNPACK_ALIGNMENT
- // GL_PACK_SWAP_BYTES
- // GL_PACK_LSB_FIRST
- // GL_PACK_ROW_LENGTH
- // GL_PACK_SKIP_ROWS
- // GL_PACK_SKIP_PIXELS
- // GL_PACK_ALIGNMENT
-
- // PixelTransfer
- // GL_MAP_COLOR
- // GL_MAP_STENCIL
- // GL_INDEX_SHIFT
- // GL_INDEX_OFFSET
- // GL_RED_SCALE
- // GL_RED_BIAS
- // GL_GREEN_SCALE
- // GL_GREEN_BIAS
- // GL_BLUE_SCALE
- // GL_BLUE_BIAS
- // GL_ALPHA_SCALE
- // GL_ALPHA_BIAS
- // GL_DEPTH_SCALE
- // GL_DEPTH_BIAS
-
- // PixelType
- GL_BITMAP = $1A00;
- // GL_BYTE
- // GL_UNSIGNED_BYTE
- // GL_SHORT
- // GL_UNSIGNED_SHORT
- // GL_INT
- // GL_UNSIGNED_INT
- // GL_FLOAT
-
- // PolygonMode
- GL_POINT = $1B00;
- GL_LINE = $1B01;
- GL_FILL = $1B02;
-
- // ReadBufferMode
- // GL_FRONT_LEFT
- // GL_FRONT_RIGHT
- // GL_BACK_LEFT
- // GL_BACK_RIGHT
- // GL_FRONT
- // GL_BACK
- // GL_LEFT
- // GL_RIGHT
- // GL_AUX0
- // GL_AUX1
- // GL_AUX2
- // GL_AUX3
-
- // RenderingMode
- GL_RENDER = $1C00;
- GL_FEEDBACK = $1C01;
- GL_SELECT = $1C02;
-
- // ShadingModel
- GL_FLAT = $1D00;
- GL_SMOOTH = $1D01;
-
- // StencilFunction
- // GL_NEVER
- // GL_LESS
- // GL_EQUAL
- // GL_LEQUAL
- // GL_GREATER
- // GL_NOTEQUAL
- // GL_GEQUAL
- // GL_ALWAYS
-
- // StencilOp
- // GL_ZERO
- GL_KEEP = $1E00;
- GL_REPLACE = $1E01;
- GL_INCR = $1E02;
- GL_DECR = $1E03;
- // GL_INVERT
-
- // StringName
- GL_VENDOR = $1F00;
- GL_RENDERER = $1F01;
- GL_VERSION = $1F02;
- GL_EXTENSIONS = $1F03;
-
- // TextureCoordName
- GL_S = $2000;
- GL_T = $2001;
- GL_R = $2002;
- GL_Q = $2003;
-
- // TexCoordPointerType
- // GL_SHORT
- // GL_INT
- // GL_FLOAT
- // GL_DOUBLE
-
- // TextureEnvMode
- GL_MODULATE = $2100;
- GL_DECAL = $2101;
- // GL_BLEND
- // GL_REPLACE
-
- // TextureEnvParameter
- GL_TEXTURE_ENV_MODE = $2200;
- GL_TEXTURE_ENV_COLOR = $2201;
-
- // TextureEnvTarget
- GL_TEXTURE_ENV = $2300;
-
- // TextureGenMode
- GL_EYE_LINEAR = $2400;
- GL_OBJECT_LINEAR = $2401;
- GL_SPHERE_MAP = $2402;
-
- // TextureGenParameter
- GL_TEXTURE_GEN_MODE = $2500;
- GL_OBJECT_PLANE = $2501;
- GL_EYE_PLANE = $2502;
-
- // TextureMagFilter
- GL_NEAREST = $2600;
- GL_LINEAR = $2601;
-
- // TextureMinFilter
- // GL_NEAREST
- // GL_LINEAR
- GL_NEAREST_MIPMAP_NEAREST = $2700;
- GL_LINEAR_MIPMAP_NEAREST = $2701;
- GL_NEAREST_MIPMAP_LINEAR = $2702;
- GL_LINEAR_MIPMAP_LINEAR = $2703;
-
- // TextureParameterName
- GL_TEXTURE_MAG_FILTER = $2800;
- GL_TEXTURE_MIN_FILTER = $2801;
- GL_TEXTURE_WRAP_S = $2802;
- GL_TEXTURE_WRAP_T = $2803;
- // GL_TEXTURE_BORDER_COLOR
- // GL_TEXTURE_PRIORITY
-
- // TextureTarget
- // GL_TEXTURE_1D
- // GL_TEXTURE_2D
- // GL_PROXY_TEXTURE_1D
- // GL_PROXY_TEXTURE_2D
-
- // TextureWrapMode
- GL_CLAMP = $2900;
- GL_REPEAT = $2901;
-
- // VertexPointerType
- // GL_SHORT
- // GL_INT
- // GL_FLOAT
- // GL_DOUBLE
-
- // ClientAttribMask
- GL_CLIENT_PIXEL_STORE_BIT = $00000001;
- GL_CLIENT_VERTEX_ARRAY_BIT = $00000002;
- GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF;
-
- // polygon_offset
- GL_POLYGON_OFFSET_FACTOR = $8038;
- GL_POLYGON_OFFSET_UNITS = $2A00;
- GL_POLYGON_OFFSET_POINT = $2A01;
- GL_POLYGON_OFFSET_LINE = $2A02;
- GL_POLYGON_OFFSET_FILL = $8037;
-
- // texture
- GL_ALPHA4 = $803B;
- GL_ALPHA8 = $803C;
- GL_ALPHA12 = $803D;
- GL_ALPHA16 = $803E;
- GL_LUMINANCE4 = $803F;
- GL_LUMINANCE8 = $8040;
- GL_LUMINANCE12 = $8041;
- GL_LUMINANCE16 = $8042;
- GL_LUMINANCE4_ALPHA4 = $8043;
- GL_LUMINANCE6_ALPHA2 = $8044;
- GL_LUMINANCE8_ALPHA8 = $8045;
- GL_LUMINANCE12_ALPHA4 = $8046;
- GL_LUMINANCE12_ALPHA12 = $8047;
- GL_LUMINANCE16_ALPHA16 = $8048;
- GL_INTENSITY = $8049;
- GL_INTENSITY4 = $804A;
- GL_INTENSITY8 = $804B;
- GL_INTENSITY12 = $804C;
- GL_INTENSITY16 = $804D;
- GL_R3_G3_B2 = $2A10;
- GL_RGB4 = $804F;
- GL_RGB5 = $8050;
- GL_RGB8 = $8051;
- GL_RGB10 = $8052;
- GL_RGB12 = $8053;
- GL_RGB16 = $8054;
- GL_RGBA2 = $8055;
- GL_RGBA4 = $8056;
- GL_RGB5_A1 = $8057;
- GL_RGBA8 = $8058;
- GL_RGB10_A2 = $8059;
- GL_RGBA12 = $805A;
- GL_RGBA16 = $805B;
- GL_TEXTURE_RED_SIZE = $805C;
- GL_TEXTURE_GREEN_SIZE = $805D;
- GL_TEXTURE_BLUE_SIZE = $805E;
- GL_TEXTURE_ALPHA_SIZE = $805F;
- GL_TEXTURE_LUMINANCE_SIZE = $8060;
- GL_TEXTURE_INTENSITY_SIZE = $8061;
- GL_PROXY_TEXTURE_1D = $8063;
- GL_PROXY_TEXTURE_2D = $8064;
-
- // texture_object
- GL_TEXTURE_PRIORITY = $8066;
- GL_TEXTURE_RESIDENT = $8067;
- GL_TEXTURE_BINDING_1D = $8068;
- GL_TEXTURE_BINDING_2D = $8069;
-
- // vertex_array
- GL_VERTEX_ARRAY = $8074;
- GL_NORMAL_ARRAY = $8075;
- GL_COLOR_ARRAY = $8076;
- GL_INDEX_ARRAY = $8077;
- GL_TEXTURE_COORD_ARRAY = $8078;
- GL_EDGE_FLAG_ARRAY = $8079;
- GL_VERTEX_ARRAY_SIZE = $807A;
- GL_VERTEX_ARRAY_TYPE = $807B;
- GL_VERTEX_ARRAY_STRIDE = $807C;
- GL_NORMAL_ARRAY_TYPE = $807E;
- GL_NORMAL_ARRAY_STRIDE = $807F;
- GL_COLOR_ARRAY_SIZE = $8081;
- GL_COLOR_ARRAY_TYPE = $8082;
- GL_COLOR_ARRAY_STRIDE = $8083;
- GL_INDEX_ARRAY_TYPE = $8085;
- GL_INDEX_ARRAY_STRIDE = $8086;
- GL_TEXTURE_COORD_ARRAY_SIZE = $8088;
- GL_TEXTURE_COORD_ARRAY_TYPE = $8089;
- GL_TEXTURE_COORD_ARRAY_STRIDE = $808A;
- GL_EDGE_FLAG_ARRAY_STRIDE = $808C;
- GL_VERTEX_ARRAY_POINTER = $808E;
- GL_NORMAL_ARRAY_POINTER = $808F;
- GL_COLOR_ARRAY_POINTER = $8090;
- GL_INDEX_ARRAY_POINTER = $8091;
- GL_TEXTURE_COORD_ARRAY_POINTER = $8092;
- GL_EDGE_FLAG_ARRAY_POINTER = $8093;
- GL_V2F = $2A20;
- GL_V3F = $2A21;
- GL_C4UB_V2F = $2A22;
- GL_C4UB_V3F = $2A23;
- GL_C3F_V3F = $2A24;
- GL_N3F_V3F = $2A25;
- GL_C4F_N3F_V3F = $2A26;
- GL_T2F_V3F = $2A27;
- GL_T4F_V4F = $2A28;
- GL_T2F_C4UB_V3F = $2A29;
- GL_T2F_C3F_V3F = $2A2A;
- GL_T2F_N3F_V3F = $2A2B;
- GL_T2F_C4F_N3F_V3F = $2A2C;
- GL_T4F_C4F_N3F_V4F = $2A2D;
-
- // Extensions
- GL_EXT_vertex_array = 1;
- GL_WIN_swap_hint = 1;
- GL_EXT_bgra = 1;
- GL_EXT_paletted_texture = 1;
-
- // EXT_vertex_array
- GL_VERTEX_ARRAY_EXT = $8074;
- GL_NORMAL_ARRAY_EXT = $8075;
- GL_COLOR_ARRAY_EXT = $8076;
- GL_INDEX_ARRAY_EXT = $8077;
- GL_TEXTURE_COORD_ARRAY_EXT = $8078;
- GL_EDGE_FLAG_ARRAY_EXT = $8079;
- GL_VERTEX_ARRAY_SIZE_EXT = $807A;
- GL_VERTEX_ARRAY_TYPE_EXT = $807B;
- GL_VERTEX_ARRAY_STRIDE_EXT = $807C;
- GL_VERTEX_ARRAY_COUNT_EXT = $807D;
- GL_NORMAL_ARRAY_TYPE_EXT = $807E;
- GL_NORMAL_ARRAY_STRIDE_EXT = $807F;
- GL_NORMAL_ARRAY_COUNT_EXT = $8080;
- GL_COLOR_ARRAY_SIZE_EXT = $8081;
- GL_COLOR_ARRAY_TYPE_EXT = $8082;
- GL_COLOR_ARRAY_STRIDE_EXT = $8083;
- GL_COLOR_ARRAY_COUNT_EXT = $8084;
- GL_INDEX_ARRAY_TYPE_EXT = $8085;
- GL_INDEX_ARRAY_STRIDE_EXT = $8086;
- GL_INDEX_ARRAY_COUNT_EXT = $8087;
- GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088;
- GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089;
- GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A;
- GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B;
- GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C;
- GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D;
- GL_VERTEX_ARRAY_POINTER_EXT = $808E;
- GL_NORMAL_ARRAY_POINTER_EXT = $808F;
- GL_COLOR_ARRAY_POINTER_EXT = $8090;
- GL_INDEX_ARRAY_POINTER_EXT = $8091;
- GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092;
- GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093;
- GL_DOUBLE_EXT = GL_DOUBLE;
-
- // EXT_bgra
- GL_BGR_EXT = $80E0;
- GL_BGRA_EXT = $80E1;
-
- // EXT_paletted_texture
-
- // These must match the GL_COLOR_TABLE_*_SGI enumerants
- GL_COLOR_TABLE_FORMAT_EXT = $80D8;
- GL_COLOR_TABLE_WIDTH_EXT = $80D9;
- GL_COLOR_TABLE_RED_SIZE_EXT = $80DA;
- GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB;
- GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC;
- GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD;
- GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE;
- GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF;
-
- GL_COLOR_INDEX1_EXT = $80E2;
- GL_COLOR_INDEX2_EXT = $80E3;
- GL_COLOR_INDEX4_EXT = $80E4;
- GL_COLOR_INDEX8_EXT = $80E5;
- GL_COLOR_INDEX12_EXT = $80E6;
- GL_COLOR_INDEX16_EXT = $80E7;
-
- // For compatibility with OpenGL v1.0
- GL_LOGIC_OP = GL_INDEX_LOGIC_OP;
- GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT;
-
-{******************************************************************************}
-
-var
- glAccum: procedure(op: GLenum; value: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAlphaFunc: procedure(func: GLenum; ref: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAreTexturesResident: function (n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glArrayElement: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBegin: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindTexture: procedure(target: GLenum; texture: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBitmap: procedure (width, height: GLsizei; xorig, yorig: GLfloat; xmove, ymove: GLfloat; const bitmap: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBlendFunc: procedure(sfactor, dfactor: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCallList: procedure(list: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCallLists: procedure(n: GLsizei; atype: GLenum; const lists: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClear: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClearAccum: procedure(red, green, blue, alpha: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClearColor: procedure(red, green, blue, alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClearDepth: procedure(depth: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClearIndex: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClearStencil: procedure(s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClipPlane: procedure(plane: GLenum; const equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3b: procedure(red, green, blue: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3d: procedure(red, green, blue: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3f: procedure(red, green, blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3i: procedure(red, green, blue: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3s: procedure(red, green, blue: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3ub: procedure(red, green, blue: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3ui: procedure(red, green, blue: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3us: procedure(red, green, blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4b: procedure(red, green, blue, alpha: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4d: procedure(red, green, blue, alpha: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4f: procedure(red, green, blue, alpha: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4i: procedure(red, green, blue, alpha: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4s: procedure(red, green, blue, alpha: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ub: procedure(red, green, blue, alpha: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ui: procedure(red, green, blue, alpha: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4us: procedure(red, green, blue, alpha: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorMask: procedure(red, green, blue, alpha: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorMaterial: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyPixels: procedure(x, y: GLint; width, height: GLsizei; atype: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyTexImage1D: procedure (target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyTexImage2D: procedure(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyTexSubImage1D: procedure(target: GLenum; level, xoffset, x, y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset, x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCullFace: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteLists: procedure(list: GLuint; range: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDepthFunc: procedure(func: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDepthMask: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDepthRange: procedure(zNear, zFar: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDisable: procedure(cap: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDisableClientState: procedure(aarray: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawArrays: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawBuffer: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawElements: procedure(mode: GLenum; count: GLsizei; atype: GLenum; const indices: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawPixels: procedure(width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEdgeFlag: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEdgeFlagPointer: procedure(stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEdgeFlagv: procedure(const flag: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnable: procedure(cap: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnableClientState: procedure(aarray: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnd: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndList: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord1d: procedure(u: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord1dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord1f: procedure(u: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord1fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord2d: procedure(u, v: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord2dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord2f: procedure(u, v: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalCoord2fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalMesh1: procedure(mode: GLenum; i1, i2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalMesh2: procedure(mode: GLenum; i1, i2, j1, j2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalPoint1: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalPoint2: procedure(i, j: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFeedbackBuffer: procedure(size: GLsizei; atype: GLenum; buffer: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFinish: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFlush: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogiv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFrontFace: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFrustum: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenLists: function(range: GLsizei): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenTextures: procedure(n: GLsizei; textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBooleanv: procedure(pname: GLenum; params: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetClipPlane: procedure(plane: GLenum; equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetDoublev: procedure(pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetError: function: GLenum; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetFloatv: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetIntegerv: procedure(pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetLightfv: procedure(light, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetLightiv: procedure(light, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapdv: procedure(target, query: GLenum; v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapfv: procedure(target, query: GLenum; v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapiv: procedure(target, query: GLenum; v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMaterialfv: procedure(face, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMaterialiv: procedure(face, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPixelMapfv: procedure(map: GLenum; values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPixelMapuiv: procedure(map: GLenum; values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPixelMapusv: procedure(map: GLenum; values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPointerv: procedure(pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPolygonStipple: procedure(mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetString: function(name: GLenum): PChar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexEnvfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexEnviv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexGendv: procedure(coord, pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexGenfv: procedure(coord, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexGeniv: procedure(coord, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexImage: procedure(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexLevelParameterfv: procedure(target: GLenum; level: GLint; pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexLevelParameteriv: procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexParameterfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexParameteriv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glHint: procedure(target, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexd: procedure(c: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexdv: procedure(const c: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexf: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexfv: procedure(const c: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexi: procedure(c: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexiv: procedure(const c: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexs: procedure(c: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexsv: procedure(const c: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexub: procedure(c: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexubv: procedure(const c: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glInitNames: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glInterleavedArrays: procedure(format: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsEnabled: function(cap: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsList: function(list: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsTexture: function(texture: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightModelf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightModelfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightModeli: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightModeliv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightf: procedure(light, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightfv: procedure(light, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLighti: procedure(light, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLightiv: procedure(light, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLineStipple: procedure(factor: GLint; pattern: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLineWidth: procedure(width: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glListBase: procedure(base: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadIdentity: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLogicOp: procedure(opcode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMap1d: procedure(target: GLenum; u1, u2: GLdouble; stride, order: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMap1f: procedure(target: GLenum; u1, u2: GLfloat; stride, order: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMap2d: procedure(target: GLenum; u1, u2: GLdouble; ustride, uorder: GLint; v1, v2: GLdouble; vstride, vorder: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMap2f: procedure(target: GLenum; u1, u2: GLfloat; ustride, uorder: GLint; v1, v2: GLfloat; vstride, vorder: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapGrid1d: procedure(un: GLint; u1, u2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapGrid1f: procedure(un: GLint; u1, u2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapGrid2d: procedure(un: GLint; u1, u2: GLdouble; vn: GLint; v1, v2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapGrid2f: procedure(un: GLint; u1, u2: GLfloat; vn: GLint; v1, v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMaterialf: procedure(face, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMaterialfv: procedure(face, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMateriali: procedure(face, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMaterialiv: procedure(face, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMatrixMode: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNewList: procedure(list: GLuint; mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3b: procedure(nx, ny, nz: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3d: procedure(nx, ny, nz: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3f: procedure(nx, ny, nz: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3i: procedure(nx, ny, nz: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3s: procedure(nx, ny, nz: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glOrtho: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPassThrough: procedure(token: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelMapfv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelMapuiv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelMapusv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelStoref: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelStorei: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelTransferf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelTransferi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelZoom: procedure(xfactor, yfactor: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointSize: procedure(size: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPolygonMode: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPolygonOffset: procedure(factor, units: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPolygonStipple: procedure(const mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPopAttrib: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPopClientAttrib: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPopMatrix: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPopName: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPrioritizeTextures: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPushAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPushClientAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPushMatrix: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPushName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2d: procedure(x, y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2f: procedure(x, y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2i: procedure(x, y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2s: procedure(x, y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3d: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3f: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3i: procedure(x, y, z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3s: procedure(x, y, z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4d: procedure(x, y, z, w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4f: procedure(x, y, z, w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4i: procedure(x, y, z, w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4s: procedure(x, y, z, w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRasterPos4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReadBuffer: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReadPixels: procedure(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectd: procedure(x1, y1, x2, y2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectdv: procedure(const v1: PGLdouble; const v2: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectf: procedure(x1, y1, x2, y2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectfv: procedure(const v1: PGLfloat; const v2: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRecti: procedure(x1, y1, x2, y2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectiv: procedure(const v1: PGLint; const v2: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRects: procedure(x1, y1, x2, y2: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRectsv: procedure(const v1: PGLshort; const v2: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRenderMode: function(mode: GLint): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRotated: procedure(angle, x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRotatef: procedure(angle, x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glScaled: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glScalef: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glScissor: procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSelectBuffer: procedure(size: GLsizei; buffer: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShadeModel: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilFunc: procedure(func: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilOp: procedure(fail, zfail, zpass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1d: procedure(s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1f: procedure(s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1i: procedure(s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1s: procedure(s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2d: procedure(s, t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2f: procedure(s, t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2i: procedure(s, t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2s: procedure(s, t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3d: procedure(s, t, r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3f: procedure(s, t, r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3i: procedure(s, t, r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3s: procedure(s, t, r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4d: procedure(s, t, r, q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4f: procedure(s, t, r, q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4i: procedure(s, t, r, q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4s: procedure(s, t, r, q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoordPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexEnvf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexEnvfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexEnvi: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexEnviv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGend: procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGendv: procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGenf: procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGenfv: procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGeni: procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexGeniv: procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexImage1D: procedure(target: GLenum; level, internalformat: GLint; width: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexImage2D: procedure(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexParameteri: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexSubImage1D: procedure(target: GLenum; level, xoffset: GLint; width: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTranslated: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTranslatef: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2d: procedure(x, y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2f: procedure(x, y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2i: procedure(x, y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2s: procedure(x, y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3d: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3f: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3i: procedure(x, y, z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3s: procedure(x, y, z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4d: procedure(x, y, z, w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4f: procedure(x, y, z, w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4i: procedure(x, y, z, w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4s: procedure(x, y, z, w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glViewport: procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- {$IFDEF WINDOWS}
- ChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- {$ENDIF}
-
-type
- // EXT_vertex_array
- PFNGLARRAYELEMENTEXTPROC = procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLDRAWARRAYSEXTPROC = procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLVERTEXPOINTEREXTPROC = procedure(size: GLint; atype: GLenum;
- stride, count: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLNORMALPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei;
- const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLCOLORPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; stride, count: GLsizei;
- const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLINDEXPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei;
- const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLTEXCOORDPOINTEREXTPROC = procedure(size: GLint; atype: GLenum;
- stride, count: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLEDGEFLAGPOINTEREXTPROC = procedure(stride, count: GLsizei;
- const pointer: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLGETPOINTERVEXTPROC = procedure(pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLARRAYELEMENTARRAYEXTPROC = procedure(mode: GLenum; count: GLsizei;
- const pi: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
- // WIN_swap_hint
- PFNGLADDSWAPHINTRECTWINPROC = procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
- // EXT_paletted_texture
- PFNGLCOLORTABLEEXTPROC = procedure(target, internalFormat: GLenum; width: GLsizei;
- format, atype: GLenum; const data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLCOLORSUBTABLEEXTPROC = procedure(target: GLenum; start, count: GLsizei;
- format, atype: GLenum; const data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLGETCOLORTABLEEXTPROC = procedure(target, format, atype: GLenum; data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLGETCOLORTABLEPARAMETERIVEXTPROC = procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- PFNGLGETCOLORTABLEPARAMETERFVEXTPROC = procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-procedure LoadOpenGL( const dll: PChar );
-procedure FreeOpenGL;
-
-implementation
-
-procedure FreeOpenGL;
-begin
-
- @glAccum := nil;
- @glAlphaFunc := nil;
- @glAreTexturesResident := nil;
- @glArrayElement := nil;
- @glBegin := nil;
- @glBindTexture := nil;
- @glBitmap := nil;
- @glBlendFunc := nil;
- @glCallList := nil;
- @glCallLists := nil;
- @glClear := nil;
- @glClearAccum := nil;
- @glClearColor := nil;
- @glClearDepth := nil;
- @glClearIndex := nil;
- @glClearStencil := nil;
- @glClipPlane := nil;
- @glColor3b := nil;
- @glColor3bv := nil;
- @glColor3d := nil;
- @glColor3dv := nil;
- @glColor3f := nil;
- @glColor3fv := nil;
- @glColor3i := nil;
- @glColor3iv := nil;
- @glColor3s := nil;
- @glColor3sv := nil;
- @glColor3ub := nil;
- @glColor3ubv := nil;
- @glColor3ui := nil;
- @glColor3uiv := nil;
- @glColor3us := nil;
- @glColor3usv := nil;
- @glColor4b := nil;
- @glColor4bv := nil;
- @glColor4d := nil;
- @glColor4dv := nil;
- @glColor4f := nil;
- @glColor4fv := nil;
- @glColor4i := nil;
- @glColor4iv := nil;
- @glColor4s := nil;
- @glColor4sv := nil;
- @glColor4ub := nil;
- @glColor4ubv := nil;
- @glColor4ui := nil;
- @glColor4uiv := nil;
- @glColor4us := nil;
- @glColor4usv := nil;
- @glColorMask := nil;
- @glColorMaterial := nil;
- @glColorPointer := nil;
- @glCopyPixels := nil;
- @glCopyTexImage1D := nil;
- @glCopyTexImage2D := nil;
- @glCopyTexSubImage1D := nil;
- @glCopyTexSubImage2D := nil;
- @glCullFace := nil;
- @glDeleteLists := nil;
- @glDeleteTextures := nil;
- @glDepthFunc := nil;
- @glDepthMask := nil;
- @glDepthRange := nil;
- @glDisable := nil;
- @glDisableClientState := nil;
- @glDrawArrays := nil;
- @glDrawBuffer := nil;
- @glDrawElements := nil;
- @glDrawPixels := nil;
- @glEdgeFlag := nil;
- @glEdgeFlagPointer := nil;
- @glEdgeFlagv := nil;
- @glEnable := nil;
- @glEnableClientState := nil;
- @glEnd := nil;
- @glEndList := nil;
- @glEvalCoord1d := nil;
- @glEvalCoord1dv := nil;
- @glEvalCoord1f := nil;
- @glEvalCoord1fv := nil;
- @glEvalCoord2d := nil;
- @glEvalCoord2dv := nil;
- @glEvalCoord2f := nil;
- @glEvalCoord2fv := nil;
- @glEvalMesh1 := nil;
- @glEvalMesh2 := nil;
- @glEvalPoint1 := nil;
- @glEvalPoint2 := nil;
- @glFeedbackBuffer := nil;
- @glFinish := nil;
- @glFlush := nil;
- @glFogf := nil;
- @glFogfv := nil;
- @glFogi := nil;
- @glFogiv := nil;
- @glFrontFace := nil;
- @glFrustum := nil;
- @glGenLists := nil;
- @glGenTextures := nil;
- @glGetBooleanv := nil;
- @glGetClipPlane := nil;
- @glGetDoublev := nil;
- @glGetError := nil;
- @glGetFloatv := nil;
- @glGetIntegerv := nil;
- @glGetLightfv := nil;
- @glGetLightiv := nil;
- @glGetMapdv := nil;
- @glGetMapfv := nil;
- @glGetMapiv := nil;
- @glGetMaterialfv := nil;
- @glGetMaterialiv := nil;
- @glGetPixelMapfv := nil;
- @glGetPixelMapuiv := nil;
- @glGetPixelMapusv := nil;
- @glGetPointerv := nil;
- @glGetPolygonStipple := nil;
- @glGetString := nil;
- @glGetTexEnvfv := nil;
- @glGetTexEnviv := nil;
- @glGetTexGendv := nil;
- @glGetTexGenfv := nil;
- @glGetTexGeniv := nil;
- @glGetTexImage := nil;
- @glGetTexLevelParameterfv := nil;
- @glGetTexLevelParameteriv := nil;
- @glGetTexParameterfv := nil;
- @glGetTexParameteriv := nil;
- @glHint := nil;
- @glIndexMask := nil;
- @glIndexPointer := nil;
- @glIndexd := nil;
- @glIndexdv := nil;
- @glIndexf := nil;
- @glIndexfv := nil;
- @glIndexi := nil;
- @glIndexiv := nil;
- @glIndexs := nil;
- @glIndexsv := nil;
- @glIndexub := nil;
- @glIndexubv := nil;
- @glInitNames := nil;
- @glInterleavedArrays := nil;
- @glIsEnabled := nil;
- @glIsList := nil;
- @glIsTexture := nil;
- @glLightModelf := nil;
- @glLightModelfv := nil;
- @glLightModeli := nil;
- @glLightModeliv := nil;
- @glLightf := nil;
- @glLightfv := nil;
- @glLighti := nil;
- @glLightiv := nil;
- @glLineStipple := nil;
- @glLineWidth := nil;
- @glListBase := nil;
- @glLoadIdentity := nil;
- @glLoadMatrixd := nil;
- @glLoadMatrixf := nil;
- @glLoadName := nil;
- @glLogicOp := nil;
- @glMap1d := nil;
- @glMap1f := nil;
- @glMap2d := nil;
- @glMap2f := nil;
- @glMapGrid1d := nil;
- @glMapGrid1f := nil;
- @glMapGrid2d := nil;
- @glMapGrid2f := nil;
- @glMaterialf := nil;
- @glMaterialfv := nil;
- @glMateriali := nil;
- @glMaterialiv := nil;
- @glMatrixMode := nil;
- @glMultMatrixd := nil;
- @glMultMatrixf := nil;
- @glNewList := nil;
- @glNormal3b := nil;
- @glNormal3bv := nil;
- @glNormal3d := nil;
- @glNormal3dv := nil;
- @glNormal3f := nil;
- @glNormal3fv := nil;
- @glNormal3i := nil;
- @glNormal3iv := nil;
- @glNormal3s := nil;
- @glNormal3sv := nil;
- @glNormalPointer := nil;
- @glOrtho := nil;
- @glPassThrough := nil;
- @glPixelMapfv := nil;
- @glPixelMapuiv := nil;
- @glPixelMapusv := nil;
- @glPixelStoref := nil;
- @glPixelStorei := nil;
- @glPixelTransferf := nil;
- @glPixelTransferi := nil;
- @glPixelZoom := nil;
- @glPointSize := nil;
- @glPolygonMode := nil;
- @glPolygonOffset := nil;
- @glPolygonStipple := nil;
- @glPopAttrib := nil;
- @glPopClientAttrib := nil;
- @glPopMatrix := nil;
- @glPopName := nil;
- @glPrioritizeTextures := nil;
- @glPushAttrib := nil;
- @glPushClientAttrib := nil;
- @glPushMatrix := nil;
- @glPushName := nil;
- @glRasterPos2d := nil;
- @glRasterPos2dv := nil;
- @glRasterPos2f := nil;
- @glRasterPos2fv := nil;
- @glRasterPos2i := nil;
- @glRasterPos2iv := nil;
- @glRasterPos2s := nil;
- @glRasterPos2sv := nil;
- @glRasterPos3d := nil;
- @glRasterPos3dv := nil;
- @glRasterPos3f := nil;
- @glRasterPos3fv := nil;
- @glRasterPos3i := nil;
- @glRasterPos3iv := nil;
- @glRasterPos3s := nil;
- @glRasterPos3sv := nil;
- @glRasterPos4d := nil;
- @glRasterPos4dv := nil;
- @glRasterPos4f := nil;
- @glRasterPos4fv := nil;
- @glRasterPos4i := nil;
- @glRasterPos4iv := nil;
- @glRasterPos4s := nil;
- @glRasterPos4sv := nil;
- @glReadBuffer := nil;
- @glReadPixels := nil;
- @glRectd := nil;
- @glRectdv := nil;
- @glRectf := nil;
- @glRectfv := nil;
- @glRecti := nil;
- @glRectiv := nil;
- @glRects := nil;
- @glRectsv := nil;
- @glRenderMode := nil;
- @glRotated := nil;
- @glRotatef := nil;
- @glScaled := nil;
- @glScalef := nil;
- @glScissor := nil;
- @glSelectBuffer := nil;
- @glShadeModel := nil;
- @glStencilFunc := nil;
- @glStencilMask := nil;
- @glStencilOp := nil;
- @glTexCoord1d := nil;
- @glTexCoord1dv := nil;
- @glTexCoord1f := nil;
- @glTexCoord1fv := nil;
- @glTexCoord1i := nil;
- @glTexCoord1iv := nil;
- @glTexCoord1s := nil;
- @glTexCoord1sv := nil;
- @glTexCoord2d := nil;
- @glTexCoord2dv := nil;
- @glTexCoord2f := nil;
- @glTexCoord2fv := nil;
- @glTexCoord2i := nil;
- @glTexCoord2iv := nil;
- @glTexCoord2s := nil;
- @glTexCoord2sv := nil;
- @glTexCoord3d := nil;
- @glTexCoord3dv := nil;
- @glTexCoord3f := nil;
- @glTexCoord3fv := nil;
- @glTexCoord3i := nil;
- @glTexCoord3iv := nil;
- @glTexCoord3s := nil;
- @glTexCoord3sv := nil;
- @glTexCoord4d := nil;
- @glTexCoord4dv := nil;
- @glTexCoord4f := nil;
- @glTexCoord4fv := nil;
- @glTexCoord4i := nil;
- @glTexCoord4iv := nil;
- @glTexCoord4s := nil;
- @glTexCoord4sv := nil;
- @glTexCoordPointer := nil;
- @glTexEnvf := nil;
- @glTexEnvfv := nil;
- @glTexEnvi := nil;
- @glTexEnviv := nil;
- @glTexGend := nil;
- @glTexGendv := nil;
- @glTexGenf := nil;
- @glTexGenfv := nil;
- @glTexGeni := nil;
- @glTexGeniv := nil;
- @glTexImage1D := nil;
- @glTexImage2D := nil;
- @glTexParameterf := nil;
- @glTexParameterfv := nil;
- @glTexParameteri := nil;
- @glTexParameteriv := nil;
- @glTexSubImage1D := nil;
- @glTexSubImage2D := nil;
- @glTranslated := nil;
- @glTranslatef := nil;
- @glVertex2d := nil;
- @glVertex2dv := nil;
- @glVertex2f := nil;
- @glVertex2fv := nil;
- @glVertex2i := nil;
- @glVertex2iv := nil;
- @glVertex2s := nil;
- @glVertex2sv := nil;
- @glVertex3d := nil;
- @glVertex3dv := nil;
- @glVertex3f := nil;
- @glVertex3fv := nil;
- @glVertex3i := nil;
- @glVertex3iv := nil;
- @glVertex3s := nil;
- @glVertex3sv := nil;
- @glVertex4d := nil;
- @glVertex4dv := nil;
- @glVertex4f := nil;
- @glVertex4fv := nil;
- @glVertex4i := nil;
- @glVertex4iv := nil;
- @glVertex4s := nil;
- @glVertex4sv := nil;
- @glVertexPointer := nil;
- @glViewport := nil;
- {$IFDEF WINDOWS}
- @ChoosePixelFormat := nil;
- {$ENDIF}
-
- UnLoadModule(LibGL);
-
-end;
-
-procedure LoadOpenGL(const dll: PChar);
-begin
-
- FreeOpenGL;
-
- if LoadModule( LibGL, dll ) then
- begin
- @glAccum := GetModuleSymbol(LibGL, 'glAccum');
- @glAlphaFunc := GetModuleSymbol(LibGL, 'glAlphaFunc');
- @glAreTexturesResident := GetModuleSymbol(LibGL, 'glAreTexturesResident');
- @glArrayElement := GetModuleSymbol(LibGL, 'glArrayElement');
- @glBegin := GetModuleSymbol(LibGL, 'glBegin');
- @glBindTexture := GetModuleSymbol(LibGL, 'glBindTexture');
- @glBitmap := GetModuleSymbol(LibGL, 'glBitmap');
- @glBlendFunc := GetModuleSymbol(LibGL, 'glBlendFunc');
- @glCallList := GetModuleSymbol(LibGL, 'glCallList');
- @glCallLists := GetModuleSymbol(LibGL, 'glCallLists');
- @glClear := GetModuleSymbol(LibGL, 'glClear');
- @glClearAccum := GetModuleSymbol(LibGL, 'glClearAccum');
- @glClearColor := GetModuleSymbol(LibGL, 'glClearColor');
- @glClearDepth := GetModuleSymbol(LibGL, 'glClearDepth');
- @glClearIndex := GetModuleSymbol(LibGL, 'glClearIndex');
- @glClearStencil := GetModuleSymbol(LibGL, 'glClearStencil');
- @glClipPlane := GetModuleSymbol(LibGL, 'glClipPlane');
- @glColor3b := GetModuleSymbol(LibGL, 'glColor3b');
- @glColor3bv := GetModuleSymbol(LibGL, 'glColor3bv');
- @glColor3d := GetModuleSymbol(LibGL, 'glColor3d');
- @glColor3dv := GetModuleSymbol(LibGL, 'glColor3dv');
- @glColor3f := GetModuleSymbol(LibGL, 'glColor3f');
- @glColor3fv := GetModuleSymbol(LibGL, 'glColor3fv');
- @glColor3i := GetModuleSymbol(LibGL, 'glColor3i');
- @glColor3iv := GetModuleSymbol(LibGL, 'glColor3iv');
- @glColor3s := GetModuleSymbol(LibGL, 'glColor3s');
- @glColor3sv := GetModuleSymbol(LibGL, 'glColor3sv');
- @glColor3ub := GetModuleSymbol(LibGL, 'glColor3ub');
- @glColor3ubv := GetModuleSymbol(LibGL, 'glColor3ubv');
- @glColor3ui := GetModuleSymbol(LibGL, 'glColor3ui');
- @glColor3uiv := GetModuleSymbol(LibGL, 'glColor3uiv');
- @glColor3us := GetModuleSymbol(LibGL, 'glColor3us');
- @glColor3usv := GetModuleSymbol(LibGL, 'glColor3usv');
- @glColor4b := GetModuleSymbol(LibGL, 'glColor4b');
- @glColor4bv := GetModuleSymbol(LibGL, 'glColor4bv');
- @glColor4d := GetModuleSymbol(LibGL, 'glColor4d');
- @glColor4dv := GetModuleSymbol(LibGL, 'glColor4dv');
- @glColor4f := GetModuleSymbol(LibGL, 'glColor4f');
- @glColor4fv := GetModuleSymbol(LibGL, 'glColor4fv');
- @glColor4i := GetModuleSymbol(LibGL, 'glColor4i');
- @glColor4iv := GetModuleSymbol(LibGL, 'glColor4iv');
- @glColor4s := GetModuleSymbol(LibGL, 'glColor4s');
- @glColor4sv := GetModuleSymbol(LibGL, 'glColor4sv');
- @glColor4ub := GetModuleSymbol(LibGL, 'glColor4ub');
- @glColor4ubv := GetModuleSymbol(LibGL, 'glColor4ubv');
- @glColor4ui := GetModuleSymbol(LibGL, 'glColor4ui');
- @glColor4uiv := GetModuleSymbol(LibGL, 'glColor4uiv');
- @glColor4us := GetModuleSymbol(LibGL, 'glColor4us');
- @glColor4usv := GetModuleSymbol(LibGL, 'glColor4usv');
- @glColorMask := GetModuleSymbol(LibGL, 'glColorMask');
- @glColorMaterial := GetModuleSymbol(LibGL, 'glColorMaterial');
- @glColorPointer := GetModuleSymbol(LibGL, 'glColorPointer');
- @glCopyPixels := GetModuleSymbol(LibGL, 'glCopyPixels');
- @glCopyTexImage1D := GetModuleSymbol(LibGL, 'glCopyTexImage1D');
- @glCopyTexImage2D := GetModuleSymbol(LibGL, 'glCopyTexImage2D');
- @glCopyTexSubImage1D := GetModuleSymbol(LibGL, 'glCopyTexSubImage1D');
- @glCopyTexSubImage2D := GetModuleSymbol(LibGL, 'glCopyTexSubImage2D');
- @glCullFace := GetModuleSymbol(LibGL, 'glCullFace');
- @glDeleteLists := GetModuleSymbol(LibGL, 'glDeleteLists');
- @glDeleteTextures := GetModuleSymbol(LibGL, 'glDeleteTextures');
- @glDepthFunc := GetModuleSymbol(LibGL, 'glDepthFunc');
- @glDepthMask := GetModuleSymbol(LibGL, 'glDepthMask');
- @glDepthRange := GetModuleSymbol(LibGL, 'glDepthRange');
- @glDisable := GetModuleSymbol(LibGL, 'glDisable');
- @glDisableClientState := GetModuleSymbol(LibGL, 'glDisableClientState');
- @glDrawArrays := GetModuleSymbol(LibGL, 'glDrawArrays');
- @glDrawBuffer := GetModuleSymbol(LibGL, 'glDrawBuffer');
- @glDrawElements := GetModuleSymbol(LibGL, 'glDrawElements');
- @glDrawPixels := GetModuleSymbol(LibGL, 'glDrawPixels');
- @glEdgeFlag := GetModuleSymbol(LibGL, 'glEdgeFlag');
- @glEdgeFlagPointer := GetModuleSymbol(LibGL, 'glEdgeFlagPointer');
- @glEdgeFlagv := GetModuleSymbol(LibGL, 'glEdgeFlagv');
- @glEnable := GetModuleSymbol(LibGL, 'glEnable');
- @glEnableClientState := GetModuleSymbol(LibGL, 'glEnableClientState');
- @glEnd := GetModuleSymbol(LibGL, 'glEnd');
- @glEndList := GetModuleSymbol(LibGL, 'glEndList');
- @glEvalCoord1d := GetModuleSymbol(LibGL, 'glEvalCoord1d');
- @glEvalCoord1dv := GetModuleSymbol(LibGL, 'glEvalCoord1dv');
- @glEvalCoord1f := GetModuleSymbol(LibGL, 'glEvalCoord1f');
- @glEvalCoord1fv := GetModuleSymbol(LibGL, 'glEvalCoord1fv');
- @glEvalCoord2d := GetModuleSymbol(LibGL, 'glEvalCoord2d');
- @glEvalCoord2dv := GetModuleSymbol(LibGL, 'glEvalCoord2dv');
- @glEvalCoord2f := GetModuleSymbol(LibGL, 'glEvalCoord2f');
- @glEvalCoord2fv := GetModuleSymbol(LibGL, 'glEvalCoord2fv');
- @glEvalMesh1 := GetModuleSymbol(LibGL, 'glEvalMesh1');
- @glEvalMesh2 := GetModuleSymbol(LibGL, 'glEvalMesh2');
- @glEvalPoint1 := GetModuleSymbol(LibGL, 'glEvalPoint1');
- @glEvalPoint2 := GetModuleSymbol(LibGL, 'glEvalPoint2');
- @glFeedbackBuffer := GetModuleSymbol(LibGL, 'glFeedbackBuffer');
- @glFinish := GetModuleSymbol(LibGL, 'glFinish');
- @glFlush := GetModuleSymbol(LibGL, 'glFlush');
- @glFogf := GetModuleSymbol(LibGL, 'glFogf');
- @glFogfv := GetModuleSymbol(LibGL, 'glFogfv');
- @glFogi := GetModuleSymbol(LibGL, 'glFogi');
- @glFogiv := GetModuleSymbol(LibGL, 'glFogiv');
- @glFrontFace := GetModuleSymbol(LibGL, 'glFrontFace');
- @glFrustum := GetModuleSymbol(LibGL, 'glFrustum');
- @glGenLists := GetModuleSymbol(LibGL, 'glGenLists');
- @glGenTextures := GetModuleSymbol(LibGL, 'glGenTextures');
- @glGetBooleanv := GetModuleSymbol(LibGL, 'glGetBooleanv');
- @glGetClipPlane := GetModuleSymbol(LibGL, 'glGetClipPlane');
- @glGetDoublev := GetModuleSymbol(LibGL, 'glGetDoublev');
- @glGetError := GetModuleSymbol(LibGL, 'glGetError');
- @glGetFloatv := GetModuleSymbol(LibGL, 'glGetFloatv');
- @glGetIntegerv := GetModuleSymbol(LibGL, 'glGetIntegerv');
- @glGetLightfv := GetModuleSymbol(LibGL, 'glGetLightfv');
- @glGetLightiv := GetModuleSymbol(LibGL, 'glGetLightiv');
- @glGetMapdv := GetModuleSymbol(LibGL, 'glGetMapdv');
- @glGetMapfv := GetModuleSymbol(LibGL, 'glGetMapfv');
- @glGetMapiv := GetModuleSymbol(LibGL, 'glGetMapiv');
- @glGetMaterialfv := GetModuleSymbol(LibGL, 'glGetMaterialfv');
- @glGetMaterialiv := GetModuleSymbol(LibGL, 'glGetMaterialiv');
- @glGetPixelMapfv := GetModuleSymbol(LibGL, 'glGetPixelMapfv');
- @glGetPixelMapuiv := GetModuleSymbol(LibGL, 'glGetPixelMapuiv');
- @glGetPixelMapusv := GetModuleSymbol(LibGL, 'glGetPixelMapusv');
- @glGetPointerv := GetModuleSymbol(LibGL, 'glGetPointerv');
- @glGetPolygonStipple := GetModuleSymbol(LibGL, 'glGetPolygonStipple');
- @glGetString := GetModuleSymbol(LibGL, 'glGetString');
- @glGetTexEnvfv := GetModuleSymbol(LibGL, 'glGetTexEnvfv');
- @glGetTexEnviv := GetModuleSymbol(LibGL, 'glGetTexEnviv');
- @glGetTexGendv := GetModuleSymbol(LibGL, 'glGetTexGendv');
- @glGetTexGenfv := GetModuleSymbol(LibGL, 'glGetTexGenfv');
- @glGetTexGeniv := GetModuleSymbol(LibGL, 'glGetTexGeniv');
- @glGetTexImage := GetModuleSymbol(LibGL, 'glGetTexImage');
- @glGetTexLevelParameterfv := GetModuleSymbol(LibGL, 'glGetTexLevelParameterfv');
- @glGetTexLevelParameteriv := GetModuleSymbol(LibGL, 'glGetTexLevelParameteriv');
- @glGetTexParameterfv := GetModuleSymbol(LibGL, 'glGetTexParameterfv');
- @glGetTexParameteriv := GetModuleSymbol(LibGL, 'glGetTexParameteriv');
- @glHint := GetModuleSymbol(LibGL, 'glHint');
- @glIndexMask := GetModuleSymbol(LibGL, 'glIndexMask');
- @glIndexPointer := GetModuleSymbol(LibGL, 'glIndexPointer');
- @glIndexd := GetModuleSymbol(LibGL, 'glIndexd');
- @glIndexdv := GetModuleSymbol(LibGL, 'glIndexdv');
- @glIndexf := GetModuleSymbol(LibGL, 'glIndexf');
- @glIndexfv := GetModuleSymbol(LibGL, 'glIndexfv');
- @glIndexi := GetModuleSymbol(LibGL, 'glIndexi');
- @glIndexiv := GetModuleSymbol(LibGL, 'glIndexiv');
- @glIndexs := GetModuleSymbol(LibGL, 'glIndexs');
- @glIndexsv := GetModuleSymbol(LibGL, 'glIndexsv');
- @glIndexub := GetModuleSymbol(LibGL, 'glIndexub');
- @glIndexubv := GetModuleSymbol(LibGL, 'glIndexubv');
- @glInitNames := GetModuleSymbol(LibGL, 'glInitNames');
- @glInterleavedArrays := GetModuleSymbol(LibGL, 'glInterleavedArrays');
- @glIsEnabled := GetModuleSymbol(LibGL, 'glIsEnabled');
- @glIsList := GetModuleSymbol(LibGL, 'glIsList');
- @glIsTexture := GetModuleSymbol(LibGL, 'glIsTexture');
- @glLightModelf := GetModuleSymbol(LibGL, 'glLightModelf');
- @glLightModelfv := GetModuleSymbol(LibGL, 'glLightModelfv');
- @glLightModeli := GetModuleSymbol(LibGL, 'glLightModeli');
- @glLightModeliv := GetModuleSymbol(LibGL, 'glLightModeliv');
- @glLightf := GetModuleSymbol(LibGL, 'glLightf');
- @glLightfv := GetModuleSymbol(LibGL, 'glLightfv');
- @glLighti := GetModuleSymbol(LibGL, 'glLighti');
- @glLightiv := GetModuleSymbol(LibGL, 'glLightiv');
- @glLineStipple := GetModuleSymbol(LibGL, 'glLineStipple');
- @glLineWidth := GetModuleSymbol(LibGL, 'glLineWidth');
- @glListBase := GetModuleSymbol(LibGL, 'glListBase');
- @glLoadIdentity := GetModuleSymbol(LibGL, 'glLoadIdentity');
- @glLoadMatrixd := GetModuleSymbol(LibGL, 'glLoadMatrixd');
- @glLoadMatrixf := GetModuleSymbol(LibGL, 'glLoadMatrixf');
- @glLoadName := GetModuleSymbol(LibGL, 'glLoadName');
- @glLogicOp := GetModuleSymbol(LibGL, 'glLogicOp');
- @glMap1d := GetModuleSymbol(LibGL, 'glMap1d');
- @glMap1f := GetModuleSymbol(LibGL, 'glMap1f');
- @glMap2d := GetModuleSymbol(LibGL, 'glMap2d');
- @glMap2f := GetModuleSymbol(LibGL, 'glMap2f');
- @glMapGrid1d := GetModuleSymbol(LibGL, 'glMapGrid1d');
- @glMapGrid1f := GetModuleSymbol(LibGL, 'glMapGrid1f');
- @glMapGrid2d := GetModuleSymbol(LibGL, 'glMapGrid2d');
- @glMapGrid2f := GetModuleSymbol(LibGL, 'glMapGrid2f');
- @glMaterialf := GetModuleSymbol(LibGL, 'glMaterialf');
- @glMaterialfv := GetModuleSymbol(LibGL, 'glMaterialfv');
- @glMateriali := GetModuleSymbol(LibGL, 'glMateriali');
- @glMaterialiv := GetModuleSymbol(LibGL, 'glMaterialiv');
- @glMatrixMode := GetModuleSymbol(LibGL, 'glMatrixMode');
- @glMultMatrixd := GetModuleSymbol(LibGL, 'glMultMatrixd');
- @glMultMatrixf := GetModuleSymbol(LibGL, 'glMultMatrixf');
- @glNewList := GetModuleSymbol(LibGL, 'glNewList');
- @glNormal3b := GetModuleSymbol(LibGL, 'glNormal3b');
- @glNormal3bv := GetModuleSymbol(LibGL, 'glNormal3bv');
- @glNormal3d := GetModuleSymbol(LibGL, 'glNormal3d');
- @glNormal3dv := GetModuleSymbol(LibGL, 'glNormal3dv');
- @glNormal3f := GetModuleSymbol(LibGL, 'glNormal3f');
- @glNormal3fv := GetModuleSymbol(LibGL, 'glNormal3fv');
- @glNormal3i := GetModuleSymbol(LibGL, 'glNormal3i');
- @glNormal3iv := GetModuleSymbol(LibGL, 'glNormal3iv');
- @glNormal3s := GetModuleSymbol(LibGL, 'glNormal3s');
- @glNormal3sv := GetModuleSymbol(LibGL, 'glNormal3sv');
- @glNormalPointer := GetModuleSymbol(LibGL, 'glNormalPointer');
- @glOrtho := GetModuleSymbol(LibGL, 'glOrtho');
- @glPassThrough := GetModuleSymbol(LibGL, 'glPassThrough');
- @glPixelMapfv := GetModuleSymbol(LibGL, 'glPixelMapfv');
- @glPixelMapuiv := GetModuleSymbol(LibGL, 'glPixelMapuiv');
- @glPixelMapusv := GetModuleSymbol(LibGL, 'glPixelMapusv');
- @glPixelStoref := GetModuleSymbol(LibGL, 'glPixelStoref');
- @glPixelStorei := GetModuleSymbol(LibGL, 'glPixelStorei');
- @glPixelTransferf := GetModuleSymbol(LibGL, 'glPixelTransferf');
- @glPixelTransferi := GetModuleSymbol(LibGL, 'glPixelTransferi');
- @glPixelZoom := GetModuleSymbol(LibGL, 'glPixelZoom');
- @glPointSize := GetModuleSymbol(LibGL, 'glPointSize');
- @glPolygonMode := GetModuleSymbol(LibGL, 'glPolygonMode');
- @glPolygonOffset := GetModuleSymbol(LibGL, 'glPolygonOffset');
- @glPolygonStipple := GetModuleSymbol(LibGL, 'glPolygonStipple');
- @glPopAttrib := GetModuleSymbol(LibGL, 'glPopAttrib');
- @glPopClientAttrib := GetModuleSymbol(LibGL, 'glPopClientAttrib');
- @glPopMatrix := GetModuleSymbol(LibGL, 'glPopMatrix');
- @glPopName := GetModuleSymbol(LibGL, 'glPopName');
- @glPrioritizeTextures := GetModuleSymbol(LibGL, 'glPrioritizeTextures');
- @glPushAttrib := GetModuleSymbol(LibGL, 'glPushAttrib');
- @glPushClientAttrib := GetModuleSymbol(LibGL, 'glPushClientAttrib');
- @glPushMatrix := GetModuleSymbol(LibGL, 'glPushMatrix');
- @glPushName := GetModuleSymbol(LibGL, 'glPushName');
- @glRasterPos2d := GetModuleSymbol(LibGL, 'glRasterPos2d');
- @glRasterPos2dv := GetModuleSymbol(LibGL, 'glRasterPos2dv');
- @glRasterPos2f := GetModuleSymbol(LibGL, 'glRasterPos2f');
- @glRasterPos2fv := GetModuleSymbol(LibGL, 'glRasterPos2fv');
- @glRasterPos2i := GetModuleSymbol(LibGL, 'glRasterPos2i');
- @glRasterPos2iv := GetModuleSymbol(LibGL, 'glRasterPos2iv');
- @glRasterPos2s := GetModuleSymbol(LibGL, 'glRasterPos2s');
- @glRasterPos2sv := GetModuleSymbol(LibGL, 'glRasterPos2sv');
- @glRasterPos3d := GetModuleSymbol(LibGL, 'glRasterPos3d');
- @glRasterPos3dv := GetModuleSymbol(LibGL, 'glRasterPos3dv');
- @glRasterPos3f := GetModuleSymbol(LibGL, 'glRasterPos3f');
- @glRasterPos3fv := GetModuleSymbol(LibGL, 'glRasterPos3fv');
- @glRasterPos3i := GetModuleSymbol(LibGL, 'glRasterPos3i');
- @glRasterPos3iv := GetModuleSymbol(LibGL, 'glRasterPos3iv');
- @glRasterPos3s := GetModuleSymbol(LibGL, 'glRasterPos3s');
- @glRasterPos3sv := GetModuleSymbol(LibGL, 'glRasterPos3sv');
- @glRasterPos4d := GetModuleSymbol(LibGL, 'glRasterPos4d');
- @glRasterPos4dv := GetModuleSymbol(LibGL, 'glRasterPos4dv');
- @glRasterPos4f := GetModuleSymbol(LibGL, 'glRasterPos4f');
- @glRasterPos4fv := GetModuleSymbol(LibGL, 'glRasterPos4fv');
- @glRasterPos4i := GetModuleSymbol(LibGL, 'glRasterPos4i');
- @glRasterPos4iv := GetModuleSymbol(LibGL, 'glRasterPos4iv');
- @glRasterPos4s := GetModuleSymbol(LibGL, 'glRasterPos4s');
- @glRasterPos4sv := GetModuleSymbol(LibGL, 'glRasterPos4sv');
- @glReadBuffer := GetModuleSymbol(LibGL, 'glReadBuffer');
- @glReadPixels := GetModuleSymbol(LibGL, 'glReadPixels');
- @glRectd := GetModuleSymbol(LibGL, 'glRectd');
- @glRectdv := GetModuleSymbol(LibGL, 'glRectdv');
- @glRectf := GetModuleSymbol(LibGL, 'glRectf');
- @glRectfv := GetModuleSymbol(LibGL, 'glRectfv');
- @glRecti := GetModuleSymbol(LibGL, 'glRecti');
- @glRectiv := GetModuleSymbol(LibGL, 'glRectiv');
- @glRects := GetModuleSymbol(LibGL, 'glRects');
- @glRectsv := GetModuleSymbol(LibGL, 'glRectsv');
- @glRenderMode := GetModuleSymbol(LibGL, 'glRenderMode');
- @glRotated := GetModuleSymbol(LibGL, 'glRotated');
- @glRotatef := GetModuleSymbol(LibGL, 'glRotatef');
- @glScaled := GetModuleSymbol(LibGL, 'glScaled');
- @glScalef := GetModuleSymbol(LibGL, 'glScalef');
- @glScissor := GetModuleSymbol(LibGL, 'glScissor');
- @glSelectBuffer := GetModuleSymbol(LibGL, 'glSelectBuffer');
- @glShadeModel := GetModuleSymbol(LibGL, 'glShadeModel');
- @glStencilFunc := GetModuleSymbol(LibGL, 'glStencilFunc');
- @glStencilMask := GetModuleSymbol(LibGL, 'glStencilMask');
- @glStencilOp := GetModuleSymbol(LibGL, 'glStencilOp');
- @glTexCoord1d := GetModuleSymbol(LibGL, 'glTexCoord1d');
- @glTexCoord1dv := GetModuleSymbol(LibGL, 'glTexCoord1dv');
- @glTexCoord1f := GetModuleSymbol(LibGL, 'glTexCoord1f');
- @glTexCoord1fv := GetModuleSymbol(LibGL, 'glTexCoord1fv');
- @glTexCoord1i := GetModuleSymbol(LibGL, 'glTexCoord1i');
- @glTexCoord1iv := GetModuleSymbol(LibGL, 'glTexCoord1iv');
- @glTexCoord1s := GetModuleSymbol(LibGL, 'glTexCoord1s');
- @glTexCoord1sv := GetModuleSymbol(LibGL, 'glTexCoord1sv');
- @glTexCoord2d := GetModuleSymbol(LibGL, 'glTexCoord2d');
- @glTexCoord2dv := GetModuleSymbol(LibGL, 'glTexCoord2dv');
- @glTexCoord2f := GetModuleSymbol(LibGL, 'glTexCoord2f');
- @glTexCoord2fv := GetModuleSymbol(LibGL, 'glTexCoord2fv');
- @glTexCoord2i := GetModuleSymbol(LibGL, 'glTexCoord2i');
- @glTexCoord2iv := GetModuleSymbol(LibGL, 'glTexCoord2iv');
- @glTexCoord2s := GetModuleSymbol(LibGL, 'glTexCoord2s');
- @glTexCoord2sv := GetModuleSymbol(LibGL, 'glTexCoord2sv');
- @glTexCoord3d := GetModuleSymbol(LibGL, 'glTexCoord3d');
- @glTexCoord3dv := GetModuleSymbol(LibGL, 'glTexCoord3dv');
- @glTexCoord3f := GetModuleSymbol(LibGL, 'glTexCoord3f');
- @glTexCoord3fv := GetModuleSymbol(LibGL, 'glTexCoord3fv');
- @glTexCoord3i := GetModuleSymbol(LibGL, 'glTexCoord3i');
- @glTexCoord3iv := GetModuleSymbol(LibGL, 'glTexCoord3iv');
- @glTexCoord3s := GetModuleSymbol(LibGL, 'glTexCoord3s');
- @glTexCoord3sv := GetModuleSymbol(LibGL, 'glTexCoord3sv');
- @glTexCoord4d := GetModuleSymbol(LibGL, 'glTexCoord4d');
- @glTexCoord4dv := GetModuleSymbol(LibGL, 'glTexCoord4dv');
- @glTexCoord4f := GetModuleSymbol(LibGL, 'glTexCoord4f');
- @glTexCoord4fv := GetModuleSymbol(LibGL, 'glTexCoord4fv');
- @glTexCoord4i := GetModuleSymbol(LibGL, 'glTexCoord4i');
- @glTexCoord4iv := GetModuleSymbol(LibGL, 'glTexCoord4iv');
- @glTexCoord4s := GetModuleSymbol(LibGL, 'glTexCoord4s');
- @glTexCoord4sv := GetModuleSymbol(LibGL, 'glTexCoord4sv');
- @glTexCoordPointer := GetModuleSymbol(LibGL, 'glTexCoordPointer');
- @glTexEnvf := GetModuleSymbol(LibGL, 'glTexEnvf');
- @glTexEnvfv := GetModuleSymbol(LibGL, 'glTexEnvfv');
- @glTexEnvi := GetModuleSymbol(LibGL, 'glTexEnvi');
- @glTexEnviv := GetModuleSymbol(LibGL, 'glTexEnviv');
- @glTexGend := GetModuleSymbol(LibGL, 'glTexGend');
- @glTexGendv := GetModuleSymbol(LibGL, 'glTexGendv');
- @glTexGenf := GetModuleSymbol(LibGL, 'glTexGenf');
- @glTexGenfv := GetModuleSymbol(LibGL, 'glTexGenfv');
- @glTexGeni := GetModuleSymbol(LibGL, 'glTexGeni');
- @glTexGeniv := GetModuleSymbol(LibGL, 'glTexGeniv');
- @glTexImage1D := GetModuleSymbol(LibGL, 'glTexImage1D');
- @glTexImage2D := GetModuleSymbol(LibGL, 'glTexImage2D');
- @glTexParameterf := GetModuleSymbol(LibGL, 'glTexParameterf');
- @glTexParameterfv := GetModuleSymbol(LibGL, 'glTexParameterfv');
- @glTexParameteri := GetModuleSymbol(LibGL, 'glTexParameteri');
- @glTexParameteriv := GetModuleSymbol(LibGL, 'glTexParameteriv');
- @glTexSubImage1D := GetModuleSymbol(LibGL, 'glTexSubImage1D');
- @glTexSubImage2D := GetModuleSymbol(LibGL, 'glTexSubImage2D');
- @glTranslated := GetModuleSymbol(LibGL, 'glTranslated');
- @glTranslatef := GetModuleSymbol(LibGL, 'glTranslatef');
- @glVertex2d := GetModuleSymbol(LibGL, 'glVertex2d');
- @glVertex2dv := GetModuleSymbol(LibGL, 'glVertex2dv');
- @glVertex2f := GetModuleSymbol(LibGL, 'glVertex2f');
- @glVertex2fv := GetModuleSymbol(LibGL, 'glVertex2fv');
- @glVertex2i := GetModuleSymbol(LibGL, 'glVertex2i');
- @glVertex2iv := GetModuleSymbol(LibGL, 'glVertex2iv');
- @glVertex2s := GetModuleSymbol(LibGL, 'glVertex2s');
- @glVertex2sv := GetModuleSymbol(LibGL, 'glVertex2sv');
- @glVertex3d := GetModuleSymbol(LibGL, 'glVertex3d');
- @glVertex3dv := GetModuleSymbol(LibGL, 'glVertex3dv');
- @glVertex3f := GetModuleSymbol(LibGL, 'glVertex3f');
- @glVertex3fv := GetModuleSymbol(LibGL, 'glVertex3fv');
- @glVertex3i := GetModuleSymbol(LibGL, 'glVertex3i');
- @glVertex3iv := GetModuleSymbol(LibGL, 'glVertex3iv');
- @glVertex3s := GetModuleSymbol(LibGL, 'glVertex3s');
- @glVertex3sv := GetModuleSymbol(LibGL, 'glVertex3sv');
- @glVertex4d := GetModuleSymbol(LibGL, 'glVertex4d');
- @glVertex4dv := GetModuleSymbol(LibGL, 'glVertex4dv');
- @glVertex4f := GetModuleSymbol(LibGL, 'glVertex4f');
- @glVertex4fv := GetModuleSymbol(LibGL, 'glVertex4fv');
- @glVertex4i := GetModuleSymbol(LibGL, 'glVertex4i');
- @glVertex4iv := GetModuleSymbol(LibGL, 'glVertex4iv');
- @glVertex4s := GetModuleSymbol(LibGL, 'glVertex4s');
- @glVertex4sv := GetModuleSymbol(LibGL, 'glVertex4sv');
- @glVertexPointer := GetModuleSymbol(LibGL, 'glVertexPointer');
- @glViewport := GetModuleSymbol(LibGL, 'glViewport');
-
- {$IFDEF WINDOWS}
- @ChoosePixelFormat := GetModuleSymbol(LibGL, 'ChoosePixelFormat');
- if not Assigned(ChoosePixelFormat) then
- {$IFNDEF FPC}@{$ENDIF}ChoosePixelFormat := @Windows.ChoosePixelFormat;
- {$ENDIF}
- end;
-end;
-
-initialization
- {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
- Set8087CW($133F);
- {$IFEND}
-
- LoadOpenGL( GLLibName );
-
-finalization
-
- FreeOpenGL;
-
-end.
-
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glext.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glext.pas
deleted file mode 100644
index 1fc70f8a..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glext.pas
+++ /dev/null
@@ -1,9578 +0,0 @@
-unit glext;
-{
- $Id: glext.pas,v 1.6 2007/05/20 20:28:31 savage Exp $
-
-}
-(**************************************************
- * OpenGL extension loading library *
- * Generated by MetaGLext, written by Tom Nuydens *
- * (tom@delphi3d.net -- http://www.delphi3d.net *
- **************************************************)
-
-{
- $Log: glext.pas,v $
- Revision 1.6 2007/05/20 20:28:31 savage
- Initial Changes to Handle 64 Bits
-
- Revision 1.5 2006/01/11 22:39:02 drellis
- Updated to Support Up to OpenGL 2.0
-
- Revision 1.4 2005/01/05 00:28:40 savage
- Forgot to wrap a couple of Load_WGL function calls with an IFDEF WIN32. Fixed so now compiles under Linux as well.
-
- Revision 1.3 2004/08/24 19:33:06 savage
- Removed declarations of SDL_GL_GetProcAddress as the correct ones are in sdl.pas.
-
- Revision 1.2 2004/08/09 00:38:01 savage
- Updated to Tom's latest version. May contains bugs, but I hope not.
-
- Revision 1.1 2004/03/30 21:53:54 savage
- Moved to it's own folder.
-
- Revision 1.6 2004/03/28 00:28:43 savage
- Fixed some glSecondaryColor definitions...
-
- Revision 1.5 2004/02/20 17:18:16 savage
- Forgot to prefix function pointer with @ for FPC and other Pascal compilers.
-
- Revision 1.4 2004/02/20 17:09:55 savage
- Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
-
- Revision 1.3 2004/02/14 22:36:29 savage
- Fixed inconsistencies of using LoadLibrary and LoadModule.
- Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
-
- Revision 1.2 2004/02/14 00:09:19 savage
- Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
- Revision 1.7 2003/06/02 12:32:13 savage
- Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-uses
- SysUtils,
-{$IFDEF __GPC__}
- gpc,
-{$ENDIF}
-
-{$IFDEF WINDOWS}
- Windows,
-{$ENDIF}
- moduleloader,
- gl;
-
-// Test if the given extension name is present in the given extension string.
-function glext_ExtensionSupported(const extension: PChar; const searchIn: PChar): Boolean;
-
-// Load a Specific Extension
-function glext_LoadExtension(ext: String): Boolean;
-// Some types that were introduced by extensions:
-type
- GLintptrARB = Integer;
- PGLintptrARB = ^GLintptrARB;
-
- GLsizeiptrARB = Integer;
- PGLsizeiptrARB = ^GLsizeiptrARB;
-
- GLcharARB = Char;
- PGLcharARB = ^GLcharARB;
-
- GLhandleARB = Cardinal;
- PGLhandleARB = ^GLhandleARB;
-
- GLintptr = Integer;
- PGLintptr = ^GLintptr;
-
- GLsizeiptr = Integer;
- PGLsizeiptr = ^GLsizeiptr;
-
- GLchar = Char;
- PGLchar = ^GLchar;
-
-//***** GL_version_1_2 *****//
-const
- GL_UNSIGNED_BYTE_3_3_2 = $8032;
- GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
- GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
- GL_UNSIGNED_INT_8_8_8_8 = $8035;
- GL_UNSIGNED_INT_10_10_10_2 = $8036;
- GL_RESCALE_NORMAL = $803A;
- GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
- GL_UNSIGNED_SHORT_5_6_5 = $8363;
- GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
- GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
- GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
- GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
- GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
- GL_BGR = $80E0;
- GL_BGRA = $80E1;
- GL_MAX_ELEMENTS_VERTICES = $80E8;
- GL_MAX_ELEMENTS_INDICES = $80E9;
- GL_CLAMP_TO_EDGE = $812F;
- GL_TEXTURE_MIN_LOD = $813A;
- GL_TEXTURE_MAX_LOD = $813B;
- GL_TEXTURE_BASE_LEVEL = $813C;
- GL_TEXTURE_MAX_LEVEL = $813D;
- GL_LIGHT_MODEL_COLOR_CONTROL = $81F8;
- GL_SINGLE_COLOR = $81F9;
- GL_SEPARATE_SPECULAR_COLOR = $81FA;
- GL_SMOOTH_POINT_SIZE_RANGE = $0B12;
- GL_SMOOTH_POINT_SIZE_GRANULARITY = $0B13;
- GL_SMOOTH_LINE_WIDTH_RANGE = $0B22;
- GL_SMOOTH_LINE_WIDTH_GRANULARITY = $0B23;
- GL_ALIASED_POINT_SIZE_RANGE = $846D;
- GL_ALIASED_LINE_WIDTH_RANGE = $846E;
- GL_PACK_SKIP_IMAGES = $806B;
- GL_PACK_IMAGE_HEIGHT = $806C;
- GL_UNPACK_SKIP_IMAGES = $806D;
- GL_UNPACK_IMAGE_HEIGHT = $806E;
- GL_TEXTURE_3D = $806F;
- GL_PROXY_TEXTURE_3D = $8070;
- GL_TEXTURE_DEPTH = $8071;
- GL_TEXTURE_WRAP_R = $8072;
- GL_MAX_3D_TEXTURE_SIZE = $8073;
-var
- glDrawRangeElements: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_version_1_2: Boolean;
-
-//***** GL_ARB_imaging *****//
-const
- GL_CONSTANT_COLOR = $8001;
- GL_ONE_MINUS_CONSTANT_COLOR = $8002;
- GL_CONSTANT_ALPHA = $8003;
- GL_ONE_MINUS_CONSTANT_ALPHA = $8004;
- GL_BLEND_COLOR = $8005;
- GL_FUNC_ADD = $8006;
- GL_MIN = $8007;
- GL_MAX = $8008;
- GL_BLEND_EQUATION = $8009;
- GL_FUNC_SUBTRACT = $800A;
- GL_FUNC_REVERSE_SUBTRACT = $800B;
- GL_CONVOLUTION_1D = $8010;
- GL_CONVOLUTION_2D = $8011;
- GL_SEPARABLE_2D = $8012;
- GL_CONVOLUTION_BORDER_MODE = $8013;
- GL_CONVOLUTION_FILTER_SCALE = $8014;
- GL_CONVOLUTION_FILTER_BIAS = $8015;
- GL_REDUCE = $8016;
- GL_CONVOLUTION_FORMAT = $8017;
- GL_CONVOLUTION_WIDTH = $8018;
- GL_CONVOLUTION_HEIGHT = $8019;
- GL_MAX_CONVOLUTION_WIDTH = $801A;
- GL_MAX_CONVOLUTION_HEIGHT = $801B;
- GL_POST_CONVOLUTION_RED_SCALE = $801C;
- GL_POST_CONVOLUTION_GREEN_SCALE = $801D;
- GL_POST_CONVOLUTION_BLUE_SCALE = $801E;
- GL_POST_CONVOLUTION_ALPHA_SCALE = $801F;
- GL_POST_CONVOLUTION_RED_BIAS = $8020;
- GL_POST_CONVOLUTION_GREEN_BIAS = $8021;
- GL_POST_CONVOLUTION_BLUE_BIAS = $8022;
- GL_POST_CONVOLUTION_ALPHA_BIAS = $8023;
- GL_HISTOGRAM = $8024;
- GL_PROXY_HISTOGRAM = $8025;
- GL_HISTOGRAM_WIDTH = $8026;
- GL_HISTOGRAM_FORMAT = $8027;
- GL_HISTOGRAM_RED_SIZE = $8028;
- GL_HISTOGRAM_GREEN_SIZE = $8029;
- GL_HISTOGRAM_BLUE_SIZE = $802A;
- GL_HISTOGRAM_ALPHA_SIZE = $802B;
- GL_HISTOGRAM_LUMINANCE_SIZE = $802C;
- GL_HISTOGRAM_SINK = $802D;
- GL_MINMAX = $802E;
- GL_MINMAX_FORMAT = $802F;
- GL_MINMAX_SINK = $8030;
- GL_TABLE_TOO_LARGE = $8031;
- GL_COLOR_MATRIX = $80B1;
- GL_COLOR_MATRIX_STACK_DEPTH = $80B2;
- GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3;
- GL_POST_COLOR_MATRIX_RED_SCALE = $80B4;
- GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5;
- GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6;
- GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7;
- GL_POST_COLOR_MATRIX_RED_BIAS = $80B8;
- GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9;
- GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA;
- GL_POST_COLOR_MATIX_ALPHA_BIAS = $80BB;
- GL_COLOR_TABLE = $80D0;
- GL_POST_CONVOLUTION_COLOR_TABLE = $80D1;
- GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2;
- GL_PROXY_COLOR_TABLE = $80D3;
- GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4;
- GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5;
- GL_COLOR_TABLE_SCALE = $80D6;
- GL_COLOR_TABLE_BIAS = $80D7;
- GL_COLOR_TABLE_FORMAT = $80D8;
- GL_COLOR_TABLE_WIDTH = $80D9;
- GL_COLOR_TABLE_RED_SIZE = $80DA;
- GL_COLOR_TABLE_GREEN_SIZE = $80DB;
- GL_COLOR_TABLE_BLUE_SIZE = $80DC;
- GL_COLOR_TABLE_ALPHA_SIZE = $80DD;
- GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE;
- GL_COLOR_TABLE_INTENSITY_SIZE = $80DF;
- GL_IGNORE_BORDER = $8150;
- GL_CONSTANT_BORDER = $8151;
- GL_WRAP_BORDER = $8152;
- GL_REPLICATE_BORDER = $8153;
- GL_CONVOLUTION_BORDER_COLOR = $8154;
-var
- glColorTable: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorTableParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorTableParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyColorTable: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTable: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorSubTable: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyColorSubTable: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameterf: procedure(target: GLenum; pname: GLenum; params: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameteri: procedure(target: GLenum; pname: GLenum; params: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetSeparableFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSeparableFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogram: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogramParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogramParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmax: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmaxParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmaxParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glHistogram: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMinmax: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glResetHistogram: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glResetMinmax: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBlendEquation: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBlendColor: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_imaging: Boolean;
-
-//***** GL_version_1_3 *****//
-const
- GL_TEXTURE0 = $84C0;
- GL_TEXTURE1 = $84C1;
- GL_TEXTURE2 = $84C2;
- GL_TEXTURE3 = $84C3;
- GL_TEXTURE4 = $84C4;
- GL_TEXTURE5 = $84C5;
- GL_TEXTURE6 = $84C6;
- GL_TEXTURE7 = $84C7;
- GL_TEXTURE8 = $84C8;
- GL_TEXTURE9 = $84C9;
- GL_TEXTURE10 = $84CA;
- GL_TEXTURE11 = $84CB;
- GL_TEXTURE12 = $84CC;
- GL_TEXTURE13 = $84CD;
- GL_TEXTURE14 = $84CE;
- GL_TEXTURE15 = $84CF;
- GL_TEXTURE16 = $84D0;
- GL_TEXTURE17 = $84D1;
- GL_TEXTURE18 = $84D2;
- GL_TEXTURE19 = $84D3;
- GL_TEXTURE20 = $84D4;
- GL_TEXTURE21 = $84D5;
- GL_TEXTURE22 = $84D6;
- GL_TEXTURE23 = $84D7;
- GL_TEXTURE24 = $84D8;
- GL_TEXTURE25 = $84D9;
- GL_TEXTURE26 = $84DA;
- GL_TEXTURE27 = $84DB;
- GL_TEXTURE28 = $84DC;
- GL_TEXTURE29 = $84DD;
- GL_TEXTURE30 = $84DE;
- GL_TEXTURE31 = $84DF;
- GL_ACTIVE_TEXTURE = $84E0;
- GL_CLIENT_ACTIVE_TEXTURE = $84E1;
- GL_MAX_TEXTURE_UNITS = $84E2;
- GL_TRANSPOSE_MODELVIEW_MATRIX = $84E3;
- GL_TRANSPOSE_PROJECTION_MATRIX = $84E4;
- GL_TRANSPOSE_TEXTURE_MATRIX = $84E5;
- GL_TRANSPOSE_COLOR_MATRIX = $84E6;
- GL_MULTISAMPLE = $809D;
- GL_SAMPLE_ALPHA_TO_COVERAGE = $809E;
- GL_SAMPLE_ALPHA_TO_ONE = $809F;
- GL_SAMPLE_COVERAGE = $80A0;
- GL_SAMPLE_BUFFERS = $80A8;
- GL_SAMPLES = $80A9;
- GL_SAMPLE_COVERAGE_VALUE = $80AA;
- GL_SAMPLE_COVERAGE_INVERT = $80AB;
- GL_MULTISAMPLE_BIT = $20000000;
- GL_NORMAL_MAP = $8511;
- GL_REFLECTION_MAP = $8512;
- GL_TEXTURE_CUBE_MAP = $8513;
- GL_TEXTURE_BINDING_CUBE_MAP = $8514;
- GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
- GL_PROXY_TEXTURE_CUBE_MAP = $851B;
- GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
- GL_COMPRESSED_ALPHA = $84E9;
- GL_COMPRESSED_LUMINANCE = $84EA;
- GL_COMPRESSED_LUMINANCE_ALPHA = $84EB;
- GL_COMPRESSED_INTENSITY = $84EC;
- GL_COMPRESSED_RGB = $84ED;
- GL_COMPRESSED_RGBA = $84EE;
- GL_TEXTURE_COMPRESSION_HINT = $84EF;
- GL_TEXTURE_COMPRESSED_IMAGE_SIZE = $86A0;
- GL_TEXTURE_COMPRESSED = $86A1;
- GL_NUM_COMPRESSED_TEXTURE_FORMATS = $86A2;
- GL_COMPRESSED_TEXTURE_FORMATS = $86A3;
- GL_CLAMP_TO_BORDER = $812D;
- GL_CLAMP_TO_BORDER_SGIS = $812D;
- GL_COMBINE = $8570;
- GL_COMBINE_RGB = $8571;
- GL_COMBINE_ALPHA = $8572;
- GL_SOURCE0_RGB = $8580;
- GL_SOURCE1_RGB = $8581;
- GL_SOURCE2_RGB = $8582;
- GL_SOURCE0_ALPHA = $8588;
- GL_SOURCE1_ALPHA = $8589;
- GL_SOURCE2_ALPHA = $858A;
- GL_OPERAND0_RGB = $8590;
- GL_OPERAND1_RGB = $8591;
- GL_OPERAND2_RGB = $8592;
- GL_OPERAND0_ALPHA = $8598;
- GL_OPERAND1_ALPHA = $8599;
- GL_OPERAND2_ALPHA = $859A;
- GL_RGB_SCALE = $8573;
- GL_ADD_SIGNED = $8574;
- GL_INTERPOLATE = $8575;
- GL_SUBTRACT = $84E7;
- GL_CONSTANT = $8576;
- GL_PRIMARY_COLOR = $8577;
- GL_PREVIOUS = $8578;
- GL_DOT3_RGB = $86AE;
- GL_DOT3_RGBA = $86AF;
-var
- glActiveTexture: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClientActiveTexture: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1d: procedure(target: GLenum; s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1f: procedure(target: GLenum; s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1i: procedure(target: GLenum; s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1s: procedure(target: GLenum; s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2d: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2f: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2i: procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2s: procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadTransposeMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadTransposeMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultTransposeMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultTransposeMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSampleCoverage: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexImage1D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage2D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage1D: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCompressedTexImage: procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_version_1_3: Boolean;
-
-//***** GL_ARB_multitexture *****//
-const
- GL_TEXTURE0_ARB = $84C0;
- GL_TEXTURE1_ARB = $84C1;
- GL_TEXTURE2_ARB = $84C2;
- GL_TEXTURE3_ARB = $84C3;
- GL_TEXTURE4_ARB = $84C4;
- GL_TEXTURE5_ARB = $84C5;
- GL_TEXTURE6_ARB = $84C6;
- GL_TEXTURE7_ARB = $84C7;
- GL_TEXTURE8_ARB = $84C8;
- GL_TEXTURE9_ARB = $84C9;
- GL_TEXTURE10_ARB = $84CA;
- GL_TEXTURE11_ARB = $84CB;
- GL_TEXTURE12_ARB = $84CC;
- GL_TEXTURE13_ARB = $84CD;
- GL_TEXTURE14_ARB = $84CE;
- GL_TEXTURE15_ARB = $84CF;
- GL_TEXTURE16_ARB = $84D0;
- GL_TEXTURE17_ARB = $84D1;
- GL_TEXTURE18_ARB = $84D2;
- GL_TEXTURE19_ARB = $84D3;
- GL_TEXTURE20_ARB = $84D4;
- GL_TEXTURE21_ARB = $84D5;
- GL_TEXTURE22_ARB = $84D6;
- GL_TEXTURE23_ARB = $84D7;
- GL_TEXTURE24_ARB = $84D8;
- GL_TEXTURE25_ARB = $84D9;
- GL_TEXTURE26_ARB = $84DA;
- GL_TEXTURE27_ARB = $84DB;
- GL_TEXTURE28_ARB = $84DC;
- GL_TEXTURE29_ARB = $84DD;
- GL_TEXTURE30_ARB = $84DE;
- GL_TEXTURE31_ARB = $84DF;
- GL_ACTIVE_TEXTURE_ARB = $84E0;
- GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1;
- GL_MAX_TEXTURE_UNITS_ARB = $84E2;
-var
- glActiveTextureARB: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClientActiveTextureARB: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1dARB: procedure(target: GLenum; s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1fARB: procedure(target: GLenum; s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1iARB: procedure(target: GLenum; s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1sARB: procedure(target: GLenum; s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2iARB: procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2sARB: procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_multitexture: Boolean;
-
-//***** GL_ARB_transpose_matrix *****//
-const
- GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3;
- GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4;
- GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5;
- GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6;
-var
- glLoadTransposeMatrixfARB: procedure(m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadTransposeMatrixdARB: procedure(m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultTransposeMatrixfARB: procedure(m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultTransposeMatrixdARB: procedure(m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_transpose_matrix: Boolean;
-
-//***** GL_ARB_multisample *****//
-const
- WGL_SAMPLE_BUFFERS_ARB = $2041;
- WGL_SAMPLES_ARB = $2042;
- GL_MULTISAMPLE_ARB = $809D;
- GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E;
- GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F;
- GL_SAMPLE_COVERAGE_ARB = $80A0;
- GL_MULTISAMPLE_BIT_ARB = $20000000;
- GL_SAMPLE_BUFFERS_ARB = $80A8;
- GL_SAMPLES_ARB = $80A9;
- GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA;
- GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB;
-var
- glSampleCoverageARB: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_multisample: Boolean;
-
-//***** GL_ARB_texture_env_add *****//
-
-function Load_GL_ARB_texture_env_add: Boolean;
-
-{$IFDEF WINDOWS}
-//***** WGL_ARB_extensions_string *****//
-var
- wglGetExtensionsStringARB: function(hdc: HDC): Pchar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_extensions_string: Boolean;
-
-//***** WGL_ARB_buffer_region *****//
-const
- WGL_FRONT_COLOR_BUFFER_BIT_ARB = $0001;
- WGL_BACK_COLOR_BUFFER_BIT_ARB = $0002;
- WGL_DEPTH_BUFFER_BIT_ARB = $0004;
- WGL_STENCIL_BUFFER_BIT_ARB = $0008;
-var
- wglCreateBufferRegionARB: function(hDC: HDC; iLayerPlane: GLint; uType: GLuint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDeleteBufferRegionARB: procedure(hRegion: THandle); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglSaveBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglRestoreBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint; xSrc: GLint; ySrc: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_buffer_region: Boolean;
-{$ENDIF}
-
-//***** GL_ARB_texture_cube_map *****//
-const
- GL_NORMAL_MAP_ARB = $8511;
- GL_REFLECTION_MAP_ARB = $8512;
- GL_TEXTURE_CUBE_MAP_ARB = $8513;
- GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514;
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516;
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518;
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519;
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A;
- GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B;
- GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C;
-
-function Load_GL_ARB_texture_cube_map: Boolean;
-
-//***** GL_ARB_depth_texture *****//
-const
- GL_DEPTH_COMPONENT16_ARB = $81A5;
- GL_DEPTH_COMPONENT24_ARB = $81A6;
- GL_DEPTH_COMPONENT32_ARB = $81A7;
- GL_TEXTURE_DEPTH_SIZE_ARB = $884A;
- GL_DEPTH_TEXTURE_MODE_ARB = $884B;
-
-function Load_GL_ARB_depth_texture: Boolean;
-
-//***** GL_ARB_point_parameters *****//
-const
- GL_POINT_SIZE_MIN_ARB = $8126;
- GL_POINT_SIZE_MAX_ARB = $8127;
- GL_POINT_FADE_THRESHOLD_SIZE_ARB = $8128;
- GL_POINT_DISTANCE_ATTENUATION_ARB = $8129;
-var
- glPointParameterfARB: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameterfvARB: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_point_parameters: Boolean;
-
-//***** GL_ARB_shadow *****//
-const
- GL_TEXTURE_COMPARE_MODE_ARB = $884C;
- GL_TEXTURE_COMPARE_FUNC_ARB = $884D;
- GL_COMPARE_R_TO_TEXTURE_ARB = $884E;
-
-function Load_GL_ARB_shadow: Boolean;
-
-//***** GL_ARB_shadow_ambient *****//
-const
- GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = $80BF;
-
-function Load_GL_ARB_shadow_ambient: Boolean;
-
-//***** GL_ARB_texture_border_clamp *****//
-const
- GL_CLAMP_TO_BORDER_ARB = $812D;
-
-function Load_GL_ARB_texture_border_clamp: Boolean;
-
-//***** GL_ARB_texture_compression *****//
-const
- GL_COMPRESSED_ALPHA_ARB = $84E9;
- GL_COMPRESSED_LUMINANCE_ARB = $84EA;
- GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB;
- GL_COMPRESSED_INTENSITY_ARB = $84EC;
- GL_COMPRESSED_RGB_ARB = $84ED;
- GL_COMPRESSED_RGBA_ARB = $84EE;
- GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF;
- GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0;
- GL_TEXTURE_COMPRESSED_ARB = $86A1;
- GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2;
- GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3;
-var
- glCompressedTexImage3DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexImage2DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexImage1DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage3DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage2DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompressedTexSubImage1DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCompressedTexImageARB: procedure(target: GLenum; lod: GLint; img: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_texture_compression: Boolean;
-
-//***** GL_ARB_texture_env_combine *****//
-const
- GL_COMBINE_ARB = $8570;
- GL_COMBINE_RGB_ARB = $8571;
- GL_COMBINE_ALPHA_ARB = $8572;
- GL_SOURCE0_RGB_ARB = $8580;
- GL_SOURCE1_RGB_ARB = $8581;
- GL_SOURCE2_RGB_ARB = $8582;
- GL_SOURCE0_ALPHA_ARB = $8588;
- GL_SOURCE1_ALPHA_ARB = $8589;
- GL_SOURCE2_ALPHA_ARB = $858A;
- GL_OPERAND0_RGB_ARB = $8590;
- GL_OPERAND1_RGB_ARB = $8591;
- GL_OPERAND2_RGB_ARB = $8592;
- GL_OPERAND0_ALPHA_ARB = $8598;
- GL_OPERAND1_ALPHA_ARB = $8599;
- GL_OPERAND2_ALPHA_ARB = $859A;
- GL_RGB_SCALE_ARB = $8573;
- GL_ADD_SIGNED_ARB = $8574;
- GL_INTERPOLATE_ARB = $8575;
- GL_SUBTRACT_ARB = $84E7;
- GL_CONSTANT_ARB = $8576;
- GL_PRIMARY_COLOR_ARB = $8577;
- GL_PREVIOUS_ARB = $8578;
-
-function Load_GL_ARB_texture_env_combine: Boolean;
-
-//***** GL_ARB_texture_env_crossbar *****//
-
-function Load_GL_ARB_texture_env_crossbar: Boolean;
-
-//***** GL_ARB_texture_env_dot3 *****//
-const
- GL_DOT3_RGB_ARB = $86AE;
- GL_DOT3_RGBA_ARB = $86AF;
-
-function Load_GL_ARB_texture_env_dot3: Boolean;
-
-//***** GL_ARB_texture_mirrored_repeat *****//
-const
- GL_MIRRORED_REPEAT_ARB = $8370;
-
-function Load_GL_ARB_texture_mirrored_repeat: Boolean;
-
-//***** GL_ARB_vertex_blend *****//
-const
- GL_MAX_VERTEX_UNITS_ARB = $86A4;
- GL_ACTIVE_VERTEX_UNITS_ARB = $86A5;
- GL_WEIGHT_SUM_UNITY_ARB = $86A6;
- GL_VERTEX_BLEND_ARB = $86A7;
- GL_MODELVIEW0_ARB = $1700;
- GL_MODELVIEW1_ARB = $850A;
- GL_MODELVIEW2_ARB = $8722;
- GL_MODELVIEW3_ARB = $8723;
- GL_MODELVIEW4_ARB = $8724;
- GL_MODELVIEW5_ARB = $8725;
- GL_MODELVIEW6_ARB = $8726;
- GL_MODELVIEW7_ARB = $8727;
- GL_MODELVIEW8_ARB = $8728;
- GL_MODELVIEW9_ARB = $8729;
- GL_MODELVIEW10_ARB = $872A;
- GL_MODELVIEW11_ARB = $872B;
- GL_MODELVIEW12_ARB = $872C;
- GL_MODELVIEW13_ARB = $872D;
- GL_MODELVIEW14_ARB = $872E;
- GL_MODELVIEW15_ARB = $872F;
- GL_MODELVIEW16_ARB = $8730;
- GL_MODELVIEW17_ARB = $8731;
- GL_MODELVIEW18_ARB = $8732;
- GL_MODELVIEW19_ARB = $8733;
- GL_MODELVIEW20_ARB = $8734;
- GL_MODELVIEW21_ARB = $8735;
- GL_MODELVIEW22_ARB = $8736;
- GL_MODELVIEW23_ARB = $8737;
- GL_MODELVIEW24_ARB = $8738;
- GL_MODELVIEW25_ARB = $8739;
- GL_MODELVIEW26_ARB = $873A;
- GL_MODELVIEW27_ARB = $873B;
- GL_MODELVIEW28_ARB = $873C;
- GL_MODELVIEW29_ARB = $873D;
- GL_MODELVIEW30_ARB = $873E;
- GL_MODELVIEW31_ARB = $873F;
- GL_CURRENT_WEIGHT_ARB = $86A8;
- GL_WEIGHT_ARRAY_TYPE_ARB = $86A9;
- GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA;
- GL_WEIGHT_ARRAY_SIZE_ARB = $86AB;
- GL_WEIGHT_ARRAY_POINTER_ARB = $86AC;
- GL_WEIGHT_ARRAY_ARB = $86AD;
-var
- glWeightbvARB: procedure(size: GLint; weights: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightsvARB: procedure(size: GLint; weights: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightivARB: procedure(size: GLint; weights: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightfvARB: procedure(size: GLint; weights: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightdvARB: procedure(size: GLint; weights: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightvARB: procedure(size: GLint; weights: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightubvARB: procedure(size: GLint; weights: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightusvARB: procedure(size: GLint; weights: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightuivARB: procedure(size: GLint; weights: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWeightPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexBlendARB: procedure(count: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_vertex_blend: Boolean;
-
-//***** GL_ARB_vertex_program *****//
-const
- GL_VERTEX_PROGRAM_ARB = $8620;
- GL_VERTEX_PROGRAM_POINT_SIZE_ARB = $8642;
- GL_VERTEX_PROGRAM_TWO_SIDE_ARB = $8643;
- GL_COLOR_SUM_ARB = $8458;
- GL_PROGRAM_FORMAT_ASCII_ARB = $8875;
- GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = $8622;
- GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = $8623;
- GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = $8624;
- GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = $8625;
- GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = $886A;
- GL_CURRENT_VERTEX_ATTRIB_ARB = $8626;
- GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = $8645;
- GL_PROGRAM_LENGTH_ARB = $8627;
- GL_PROGRAM_FORMAT_ARB = $8876;
- GL_PROGRAM_BINDING_ARB = $8677;
- GL_PROGRAM_INSTRUCTIONS_ARB = $88A0;
- GL_MAX_PROGRAM_INSTRUCTIONS_ARB = $88A1;
- GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A2;
- GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A3;
- GL_PROGRAM_TEMPORARIES_ARB = $88A4;
- GL_MAX_PROGRAM_TEMPORARIES_ARB = $88A5;
- GL_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A6;
- GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A7;
- GL_PROGRAM_PARAMETERS_ARB = $88A8;
- GL_MAX_PROGRAM_PARAMETERS_ARB = $88A9;
- GL_PROGRAM_NATIVE_PARAMETERS_ARB = $88AA;
- GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = $88AB;
- GL_PROGRAM_ATTRIBS_ARB = $88AC;
- GL_MAX_PROGRAM_ATTRIBS_ARB = $88AD;
- GL_PROGRAM_NATIVE_ATTRIBS_ARB = $88AE;
- GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = $88AF;
- GL_PROGRAM_ADDRESS_REGISTERS_ARB = $88B0;
- GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = $88B1;
- GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B2;
- GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B3;
- GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = $88B4;
- GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = $88B5;
- GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = $88B6;
- GL_PROGRAM_STRING_ARB = $8628;
- GL_PROGRAM_ERROR_POSITION_ARB = $864B;
- GL_CURRENT_MATRIX_ARB = $8641;
- GL_TRANSPOSE_CURRENT_MATRIX_ARB = $88B7;
- GL_CURRENT_MATRIX_STACK_DEPTH_ARB = $8640;
- GL_MAX_VERTEX_ATTRIBS_ARB = $8869;
- GL_MAX_PROGRAM_MATRICES_ARB = $862F;
- GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = $862E;
- GL_PROGRAM_ERROR_STRING_ARB = $8874;
- GL_MATRIX0_ARB = $88C0;
- GL_MATRIX1_ARB = $88C1;
- GL_MATRIX2_ARB = $88C2;
- GL_MATRIX3_ARB = $88C3;
- GL_MATRIX4_ARB = $88C4;
- GL_MATRIX5_ARB = $88C5;
- GL_MATRIX6_ARB = $88C6;
- GL_MATRIX7_ARB = $88C7;
- GL_MATRIX8_ARB = $88C8;
- GL_MATRIX9_ARB = $88C9;
- GL_MATRIX10_ARB = $88CA;
- GL_MATRIX11_ARB = $88CB;
- GL_MATRIX12_ARB = $88CC;
- GL_MATRIX13_ARB = $88CD;
- GL_MATRIX14_ARB = $88CE;
- GL_MATRIX15_ARB = $88CF;
- GL_MATRIX16_ARB = $88D0;
- GL_MATRIX17_ARB = $88D1;
- GL_MATRIX18_ARB = $88D2;
- GL_MATRIX19_ARB = $88D3;
- GL_MATRIX20_ARB = $88D4;
- GL_MATRIX21_ARB = $88D5;
- GL_MATRIX22_ARB = $88D6;
- GL_MATRIX23_ARB = $88D7;
- GL_MATRIX24_ARB = $88D8;
- GL_MATRIX25_ARB = $88D9;
- GL_MATRIX26_ARB = $88DA;
- GL_MATRIX27_ARB = $88DB;
- GL_MATRIX28_ARB = $88DC;
- GL_MATRIX29_ARB = $88DD;
- GL_MATRIX30_ARB = $88DE;
- GL_MATRIX31_ARB = $88DF;
-var
- glVertexAttrib1sARB: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1fARB: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1dARB: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2sARB: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NubARB: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4bvARB: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4ivARB: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4ubvARB: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4usvARB: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4uivARB: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NbvARB: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NsvARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NivARB: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NubvARB: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NusvARB: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4NuivARB: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribPointerARB: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnableVertexAttribArrayARB: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDisableVertexAttribArrayARB: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramStringARB: procedure(target: GLenum; format: GLenum; len: GLsizei; const _string: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindProgramARB: procedure(target: GLenum; _program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteProgramsARB: procedure(n: GLsizei; const programs: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenProgramsARB: procedure(n: GLsizei; programs: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramEnvParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramEnvParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramEnvParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramEnvParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramLocalParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramLocalParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramLocalParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramLocalParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramEnvParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramEnvParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramLocalParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramLocalParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramStringARB: procedure(target: GLenum; pname: GLenum; _string: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribdvARB: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribfvARB: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribivARB: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribPointervARB: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsProgramARB: function(_program: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_vertex_program: Boolean;
-
-//***** GL_ARB_window_pos *****//
-var
- glWindowPos2dARB: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2fARB: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2iARB: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2sARB: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2dvARB: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2fvARB: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2ivARB: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2svARB: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3dARB: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3fARB: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3iARB: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3sARB: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3dvARB: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3fvARB: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3ivARB: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3svARB: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_window_pos: Boolean;
-
-//***** GL_EXT_422_pixels *****//
-const
- GL_422_EXT = $80CC;
- GL_422_REV_EXT = $80CD;
- GL_422_AVERAGE_EXT = $80CE;
- GL_422_REV_AVERAGE_EXT = $80CF;
-
-function Load_GL_EXT_422_pixels: Boolean;
-
-//***** GL_EXT_abgr *****//
-const
- GL_ABGR_EXT = $8000;
-
-function Load_GL_EXT_abgr: Boolean;
-
-//***** GL_EXT_bgra *****//
-const
- GL_BGR_EXT = $80E0;
- GL_BGRA_EXT = $80E1;
-
-function Load_GL_EXT_bgra: Boolean;
-
-//***** GL_EXT_blend_color *****//
-const
- GL_CONSTANT_COLOR_EXT = $8001;
- GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002;
- GL_CONSTANT_ALPHA_EXT = $8003;
- GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004;
- GL_BLEND_COLOR_EXT = $8005;
-var
- glBlendColorEXT: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_blend_color: Boolean;
-
-//***** GL_EXT_blend_func_separate *****//
-const
- GL_BLEND_DST_RGB_EXT = $80C8;
- GL_BLEND_SRC_RGB_EXT = $80C9;
- GL_BLEND_DST_ALPHA_EXT = $80CA;
- GL_BLEND_SRC_ALPHA_EXT = $80CB;
-var
- glBlendFuncSeparateEXT: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_blend_func_separate: Boolean;
-
-//***** GL_EXT_blend_logic_op *****//
-
-function Load_GL_EXT_blend_logic_op: Boolean;
-
-//***** GL_EXT_blend_minmax *****//
-const
- GL_FUNC_ADD_EXT = $8006;
- GL_MIN_EXT = $8007;
- GL_MAX_EXT = $8008;
- GL_BLEND_EQUATION_EXT = $8009;
-var
- glBlendEquationEXT: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_blend_minmax: Boolean;
-
-//***** GL_EXT_blend_subtract *****//
-const
- GL_FUNC_SUBTRACT_EXT = $800A;
- GL_FUNC_REVERSE_SUBTRACT_EXT = $800B;
-
-function Load_GL_EXT_blend_subtract: Boolean;
-
-//***** GL_EXT_clip_volume_hint *****//
-const
- GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0;
-
-function Load_GL_EXT_clip_volume_hint: Boolean;
-
-//***** GL_EXT_color_subtable *****//
-var
- glColorSubTableEXT: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyColorSubTableEXT: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_color_subtable: Boolean;
-
-//***** GL_EXT_compiled_vertex_array *****//
-const
- GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8;
- GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9;
-var
- glLockArraysEXT: procedure(first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUnlockArraysEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_compiled_vertex_array: Boolean;
-
-//***** GL_EXT_convolution *****//
-const
- GL_CONVOLUTION_1D_EXT = $8010;
- GL_CONVOLUTION_2D_EXT = $8011;
- GL_SEPARABLE_2D_EXT = $8012;
- GL_CONVOLUTION_BORDER_MODE_EXT = $8013;
- GL_CONVOLUTION_FILTER_SCALE_EXT = $8014;
- GL_CONVOLUTION_FILTER_BIAS_EXT = $8015;
- GL_REDUCE_EXT = $8016;
- GL_CONVOLUTION_FORMAT_EXT = $8017;
- GL_CONVOLUTION_WIDTH_EXT = $8018;
- GL_CONVOLUTION_HEIGHT_EXT = $8019;
- GL_MAX_CONVOLUTION_WIDTH_EXT = $801A;
- GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B;
- GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C;
- GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D;
- GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E;
- GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F;
- GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020;
- GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021;
- GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022;
- GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023;
-var
- glConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSeparableFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetSeparableFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameteriEXT: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameterfEXT: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_convolution: Boolean;
-
-//***** GL_EXT_histogram *****//
-const
- GL_HISTOGRAM_EXT = $8024;
- GL_PROXY_HISTOGRAM_EXT = $8025;
- GL_HISTOGRAM_WIDTH_EXT = $8026;
- GL_HISTOGRAM_FORMAT_EXT = $8027;
- GL_HISTOGRAM_RED_SIZE_EXT = $8028;
- GL_HISTOGRAM_GREEN_SIZE_EXT = $8029;
- GL_HISTOGRAM_BLUE_SIZE_EXT = $802A;
- GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B;
- GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C;
- GL_HISTOGRAM_SINK_EXT = $802D;
- GL_MINMAX_EXT = $802E;
- GL_MINMAX_FORMAT_EXT = $802F;
- GL_MINMAX_SINK_EXT = $8030;
-var
- glHistogramEXT: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glResetHistogramEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogramEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogramParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHistogramParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMinmaxEXT: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glResetMinmaxEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmaxEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmaxParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMinmaxParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_histogram: Boolean;
-
-//***** GL_EXT_multi_draw_arrays *****//
-var
- glMultiDrawArraysEXT: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawElementsEXT: procedure(mode: GLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_multi_draw_arrays: Boolean;
-
-//***** GL_EXT_packed_pixels *****//
-const
- GL_UNSIGNED_BYTE_3_3_2_EXT = $8032;
- GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033;
- GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034;
- GL_UNSIGNED_INT_8_8_8_8_EXT = $8035;
- GL_UNSIGNED_INT_10_10_10_2_EXT = $8036;
-
-function Load_GL_EXT_packed_pixels: Boolean;
-
-//***** GL_EXT_paletted_texture *****//
-const
- GL_COLOR_INDEX1_EXT = $80E2;
- GL_COLOR_INDEX2_EXT = $80E3;
- GL_COLOR_INDEX4_EXT = $80E4;
- GL_COLOR_INDEX8_EXT = $80E5;
- GL_COLOR_INDEX12_EXT = $80E6;
- GL_COLOR_INDEX16_EXT = $80E7;
- GL_COLOR_TABLE_FORMAT_EXT = $80D8;
- GL_COLOR_TABLE_WIDTH_EXT = $80D9;
- GL_COLOR_TABLE_RED_SIZE_EXT = $80DA;
- GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB;
- GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC;
- GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD;
- GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE;
- GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF;
- GL_TEXTURE_INDEX_SIZE_EXT = $80ED;
- GL_TEXTURE_1D = $0DE0;
- GL_TEXTURE_2D = $0DE1;
- GL_TEXTURE_3D_EXT = $806F;
- // GL_TEXTURE_CUBE_MAP_ARB { already defined }
- GL_PROXY_TEXTURE_1D = $8063;
- GL_PROXY_TEXTURE_2D = $8064;
- GL_PROXY_TEXTURE_3D_EXT = $8070;
- // GL_PROXY_TEXTURE_CUBE_MAP_ARB { already defined }
- // GL_TEXTURE_1D { already defined }
- // GL_TEXTURE_2D { already defined }
- // GL_TEXTURE_3D_EXT { already defined }
- // GL_TEXTURE_CUBE_MAP_ARB { already defined }
-var
- glColorTableEXT: procedure(target: GLenum; internalFormat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- // glColorSubTableEXT { already defined }
- glGetColorTableEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_paletted_texture: Boolean;
-
-//***** GL_EXT_point_parameters *****//
-const
- GL_POINT_SIZE_MIN_EXT = $8126;
- GL_POINT_SIZE_MAX_EXT = $8127;
- GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128;
- GL_DISTANCE_ATTENUATION_EXT = $8129;
-var
- glPointParameterfEXT: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameterfvEXT: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_point_parameters: Boolean;
-
-//***** GL_EXT_polygon_offset *****//
-const
- GL_POLYGON_OFFSET_EXT = $8037;
- GL_POLYGON_OFFSET_FACTOR_EXT = $8038;
- GL_POLYGON_OFFSET_BIAS_EXT = $8039;
-var
- glPolygonOffsetEXT: procedure(factor: GLfloat; bias: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_polygon_offset: Boolean;
-
-//***** GL_EXT_separate_specular_color *****//
-const
- GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8;
- GL_SINGLE_COLOR_EXT = $81F9;
- GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA;
-
-function Load_GL_EXT_separate_specular_color: Boolean;
-
-//***** GL_EXT_shadow_funcs *****//
-
-function Load_GL_EXT_shadow_funcs: Boolean;
-
-//***** GL_EXT_shared_texture_palette *****//
-const
- GL_SHARED_TEXTURE_PALETTE_EXT = $81FB;
-
-function Load_GL_EXT_shared_texture_palette: Boolean;
-
-//***** GL_EXT_stencil_two_side *****//
-const
- GL_STENCIL_TEST_TWO_SIDE_EXT = $8910;
- GL_ACTIVE_STENCIL_FACE_EXT = $8911;
-var
- glActiveStencilFaceEXT: procedure(face: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_stencil_two_side: Boolean;
-
-//***** GL_EXT_stencil_wrap *****//
-const
- GL_INCR_WRAP_EXT = $8507;
- GL_DECR_WRAP_EXT = $8508;
-
-function Load_GL_EXT_stencil_wrap: Boolean;
-
-//***** GL_EXT_subtexture *****//
-var
- glTexSubImage1DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexSubImage2DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexSubImage3DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_subtexture: Boolean;
-
-//***** GL_EXT_texture3D *****//
-const
- GL_PACK_SKIP_IMAGES_EXT = $806B;
- GL_PACK_IMAGE_HEIGHT_EXT = $806C;
- GL_UNPACK_SKIP_IMAGES_EXT = $806D;
- GL_UNPACK_IMAGE_HEIGHT_EXT = $806E;
- // GL_TEXTURE_3D_EXT { already defined }
- // GL_PROXY_TEXTURE_3D_EXT { already defined }
- GL_TEXTURE_DEPTH_EXT = $8071;
- GL_TEXTURE_WRAP_R_EXT = $8072;
- GL_MAX_3D_TEXTURE_SIZE_EXT = $8073;
-var
- glTexImage3DEXT: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_texture3D: Boolean;
-
-//***** GL_EXT_texture_compression_s3tc *****//
-const
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
-
-function Load_GL_EXT_texture_compression_s3tc: Boolean;
-
-//***** GL_EXT_texture_env_add *****//
-
-function Load_GL_EXT_texture_env_add: Boolean;
-
-//***** GL_EXT_texture_env_combine *****//
-const
- GL_COMBINE_EXT = $8570;
- GL_COMBINE_RGB_EXT = $8571;
- GL_COMBINE_ALPHA_EXT = $8572;
- GL_SOURCE0_RGB_EXT = $8580;
- GL_SOURCE1_RGB_EXT = $8581;
- GL_SOURCE2_RGB_EXT = $8582;
- GL_SOURCE0_ALPHA_EXT = $8588;
- GL_SOURCE1_ALPHA_EXT = $8589;
- GL_SOURCE2_ALPHA_EXT = $858A;
- GL_OPERAND0_RGB_EXT = $8590;
- GL_OPERAND1_RGB_EXT = $8591;
- GL_OPERAND2_RGB_EXT = $8592;
- GL_OPERAND0_ALPHA_EXT = $8598;
- GL_OPERAND1_ALPHA_EXT = $8599;
- GL_OPERAND2_ALPHA_EXT = $859A;
- GL_RGB_SCALE_EXT = $8573;
- GL_ADD_SIGNED_EXT = $8574;
- GL_INTERPOLATE_EXT = $8575;
- GL_CONSTANT_EXT = $8576;
- GL_PRIMARY_COLOR_EXT = $8577;
- GL_PREVIOUS_EXT = $8578;
-
-function Load_GL_EXT_texture_env_combine: Boolean;
-
-//***** GL_EXT_texture_env_dot3 *****//
-const
- GL_DOT3_RGB_EXT = $8740;
- GL_DOT3_RGBA_EXT = $8741;
-
-function Load_GL_EXT_texture_env_dot3: Boolean;
-
-//***** GL_EXT_texture_filter_anisotropic *****//
-const
- GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
- GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
-
-function Load_GL_EXT_texture_filter_anisotropic: Boolean;
-
-//***** GL_EXT_texture_lod_bias *****//
-const
- GL_TEXTURE_FILTER_CONTROL_EXT = $8500;
- GL_TEXTURE_LOD_BIAS_EXT = $8501;
- GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD;
-
-function Load_GL_EXT_texture_lod_bias: Boolean;
-
-//***** GL_EXT_texture_object *****//
-const
- GL_TEXTURE_PRIORITY_EXT = $8066;
- GL_TEXTURE_RESIDENT_EXT = $8067;
- GL_TEXTURE_1D_BINDING_EXT = $8068;
- GL_TEXTURE_2D_BINDING_EXT = $8069;
- GL_TEXTURE_3D_BINDING_EXT = $806A;
-var
- glGenTexturesEXT: procedure(n: GLsizei; textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteTexturesEXT: procedure(n: GLsizei; const textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindTextureEXT: procedure(target: GLenum; texture: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPrioritizeTexturesEXT: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAreTexturesResidentEXT: function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsTextureEXT: function(texture: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_texture_object: Boolean;
-
-//***** GL_EXT_vertex_array *****//
-const
- GL_VERTEX_ARRAY_EXT = $8074;
- GL_NORMAL_ARRAY_EXT = $8075;
- GL_COLOR_ARRAY_EXT = $8076;
- GL_INDEX_ARRAY_EXT = $8077;
- GL_TEXTURE_COORD_ARRAY_EXT = $8078;
- GL_EDGE_FLAG_ARRAY_EXT = $8079;
- GL_DOUBLE_EXT = $140A;
- GL_VERTEX_ARRAY_SIZE_EXT = $807A;
- GL_VERTEX_ARRAY_TYPE_EXT = $807B;
- GL_VERTEX_ARRAY_STRIDE_EXT = $807C;
- GL_VERTEX_ARRAY_COUNT_EXT = $807D;
- GL_NORMAL_ARRAY_TYPE_EXT = $807E;
- GL_NORMAL_ARRAY_STRIDE_EXT = $807F;
- GL_NORMAL_ARRAY_COUNT_EXT = $8080;
- GL_COLOR_ARRAY_SIZE_EXT = $8081;
- GL_COLOR_ARRAY_TYPE_EXT = $8082;
- GL_COLOR_ARRAY_STRIDE_EXT = $8083;
- GL_COLOR_ARRAY_COUNT_EXT = $8084;
- GL_INDEX_ARRAY_TYPE_EXT = $8085;
- GL_INDEX_ARRAY_STRIDE_EXT = $8086;
- GL_INDEX_ARRAY_COUNT_EXT = $8087;
- GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088;
- GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089;
- GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A;
- GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B;
- GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C;
- GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D;
- GL_VERTEX_ARRAY_POINTER_EXT = $808E;
- GL_NORMAL_ARRAY_POINTER_EXT = $808F;
- GL_COLOR_ARRAY_POINTER_EXT = $8090;
- GL_INDEX_ARRAY_POINTER_EXT = $8091;
- GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092;
- GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093;
-var
- glArrayElementEXT: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawArraysEXT: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIndexPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoordPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEdgeFlagPointerEXT: procedure(stride: GLsizei; count: GLsizei; const pointer: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPointervEXT: procedure(pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_vertex_array: Boolean;
-
-//***** GL_EXT_vertex_shader *****//
-const
- GL_VERTEX_SHADER_EXT = $8780;
- GL_VARIANT_VALUE_EXT = $87E4;
- GL_VARIANT_DATATYPE_EXT = $87E5;
- GL_VARIANT_ARRAY_STRIDE_EXT = $87E6;
- GL_VARIANT_ARRAY_TYPE_EXT = $87E7;
- GL_VARIANT_ARRAY_EXT = $87E8;
- GL_VARIANT_ARRAY_POINTER_EXT = $87E9;
- GL_INVARIANT_VALUE_EXT = $87EA;
- GL_INVARIANT_DATATYPE_EXT = $87EB;
- GL_LOCAL_CONSTANT_VALUE_EXT = $87EC;
- GL_LOCAL_CONSTANT_DATATYPE_EXT = $87ED;
- GL_OP_INDEX_EXT = $8782;
- GL_OP_NEGATE_EXT = $8783;
- GL_OP_DOT3_EXT = $8784;
- GL_OP_DOT4_EXT = $8785;
- GL_OP_MUL_EXT = $8786;
- GL_OP_ADD_EXT = $8787;
- GL_OP_MADD_EXT = $8788;
- GL_OP_FRAC_EXT = $8789;
- GL_OP_MAX_EXT = $878A;
- GL_OP_MIN_EXT = $878B;
- GL_OP_SET_GE_EXT = $878C;
- GL_OP_SET_LT_EXT = $878D;
- GL_OP_CLAMP_EXT = $878E;
- GL_OP_FLOOR_EXT = $878F;
- GL_OP_ROUND_EXT = $8790;
- GL_OP_EXP_BASE_2_EXT = $8791;
- GL_OP_LOG_BASE_2_EXT = $8792;
- GL_OP_POWER_EXT = $8793;
- GL_OP_RECIP_EXT = $8794;
- GL_OP_RECIP_SQRT_EXT = $8795;
- GL_OP_SUB_EXT = $8796;
- GL_OP_CROSS_PRODUCT_EXT = $8797;
- GL_OP_MULTIPLY_MATRIX_EXT = $8798;
- GL_OP_MOV_EXT = $8799;
- GL_OUTPUT_VERTEX_EXT = $879A;
- GL_OUTPUT_COLOR0_EXT = $879B;
- GL_OUTPUT_COLOR1_EXT = $879C;
- GL_OUTPUT_TEXTURE_COORD0_EXT = $879D;
- GL_OUTPUT_TEXTURE_COORD1_EXT = $879E;
- GL_OUTPUT_TEXTURE_COORD2_EXT = $879F;
- GL_OUTPUT_TEXTURE_COORD3_EXT = $87A0;
- GL_OUTPUT_TEXTURE_COORD4_EXT = $87A1;
- GL_OUTPUT_TEXTURE_COORD5_EXT = $87A2;
- GL_OUTPUT_TEXTURE_COORD6_EXT = $87A3;
- GL_OUTPUT_TEXTURE_COORD7_EXT = $87A4;
- GL_OUTPUT_TEXTURE_COORD8_EXT = $87A5;
- GL_OUTPUT_TEXTURE_COORD9_EXT = $87A6;
- GL_OUTPUT_TEXTURE_COORD10_EXT = $87A7;
- GL_OUTPUT_TEXTURE_COORD11_EXT = $87A8;
- GL_OUTPUT_TEXTURE_COORD12_EXT = $87A9;
- GL_OUTPUT_TEXTURE_COORD13_EXT = $87AA;
- GL_OUTPUT_TEXTURE_COORD14_EXT = $87AB;
- GL_OUTPUT_TEXTURE_COORD15_EXT = $87AC;
- GL_OUTPUT_TEXTURE_COORD16_EXT = $87AD;
- GL_OUTPUT_TEXTURE_COORD17_EXT = $87AE;
- GL_OUTPUT_TEXTURE_COORD18_EXT = $87AF;
- GL_OUTPUT_TEXTURE_COORD19_EXT = $87B0;
- GL_OUTPUT_TEXTURE_COORD20_EXT = $87B1;
- GL_OUTPUT_TEXTURE_COORD21_EXT = $87B2;
- GL_OUTPUT_TEXTURE_COORD22_EXT = $87B3;
- GL_OUTPUT_TEXTURE_COORD23_EXT = $87B4;
- GL_OUTPUT_TEXTURE_COORD24_EXT = $87B5;
- GL_OUTPUT_TEXTURE_COORD25_EXT = $87B6;
- GL_OUTPUT_TEXTURE_COORD26_EXT = $87B7;
- GL_OUTPUT_TEXTURE_COORD27_EXT = $87B8;
- GL_OUTPUT_TEXTURE_COORD28_EXT = $87B9;
- GL_OUTPUT_TEXTURE_COORD29_EXT = $87BA;
- GL_OUTPUT_TEXTURE_COORD30_EXT = $87BB;
- GL_OUTPUT_TEXTURE_COORD31_EXT = $87BC;
- GL_OUTPUT_FOG_EXT = $87BD;
- GL_SCALAR_EXT = $87BE;
- GL_VECTOR_EXT = $87BF;
- GL_MATRIX_EXT = $87C0;
- GL_VARIANT_EXT = $87C1;
- GL_INVARIANT_EXT = $87C2;
- GL_LOCAL_CONSTANT_EXT = $87C3;
- GL_LOCAL_EXT = $87C4;
- GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = $87C5;
- GL_MAX_VERTEX_SHADER_VARIANTS_EXT = $87C6;
- GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = $87C7;
- GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87C8;
- GL_MAX_VERTEX_SHADER_LOCALS_EXT = $87C9;
- GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CA;
- GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = $87CB;
- GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87CC;
- GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = $87CD;
- GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = $87CE;
- GL_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CF;
- GL_VERTEX_SHADER_VARIANTS_EXT = $87D0;
- GL_VERTEX_SHADER_INVARIANTS_EXT = $87D1;
- GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87D2;
- GL_VERTEX_SHADER_LOCALS_EXT = $87D3;
- GL_VERTEX_SHADER_BINDING_EXT = $8781;
- GL_VERTEX_SHADER_OPTIMIZED_EXT = $87D4;
- GL_X_EXT = $87D5;
- GL_Y_EXT = $87D6;
- GL_Z_EXT = $87D7;
- GL_W_EXT = $87D8;
- GL_NEGATIVE_X_EXT = $87D9;
- GL_NEGATIVE_Y_EXT = $87DA;
- GL_NEGATIVE_Z_EXT = $87DB;
- GL_NEGATIVE_W_EXT = $87DC;
- GL_ZERO_EXT = $87DD;
- GL_ONE_EXT = $87DE;
- GL_NEGATIVE_ONE_EXT = $87DF;
- GL_NORMALIZED_RANGE_EXT = $87E0;
- GL_FULL_RANGE_EXT = $87E1;
- GL_CURRENT_VERTEX_EXT = $87E2;
- GL_MVP_MATRIX_EXT = $87E3;
-var
- glBeginVertexShaderEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndVertexShaderEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindVertexShaderEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenVertexShadersEXT: function(range: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteVertexShaderEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShaderOp1EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShaderOp2EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShaderOp3EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint; arg3: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSwizzleEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWriteMaskEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glInsertComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glExtractComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenSymbolsEXT: function(datatype: GLenum; storagetype: GLenum; range: GLenum; components: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSetInvariantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSetLocalConstantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantbvEXT: procedure(id: GLuint; addr: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantsvEXT: procedure(id: GLuint; addr: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantivEXT: procedure(id: GLuint; addr: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantfvEXT: procedure(id: GLuint; addr: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantdvEXT: procedure(id: GLuint; addr: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantubvEXT: procedure(id: GLuint; addr: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantusvEXT: procedure(id: GLuint; addr: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantuivEXT: procedure(id: GLuint; addr: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantPointerEXT: procedure(id: GLuint; _type: GLenum; stride: GLuint; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnableVariantClientStateEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDisableVariantClientStateEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindLightParameterEXT: function(light: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindMaterialParameterEXT: function(face: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindTexGenParameterEXT: function(_unit: GLenum; coord: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindTextureUnitParameterEXT: function(_unit: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindParameterEXT: function(value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsVariantEnabledEXT: function(id: GLuint; cap: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantPointervEXT: procedure(id: GLuint; value: GLenum; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetInvariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetInvariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetInvariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetLocalConstantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetLocalConstantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetLocalConstantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_vertex_shader: Boolean;
-
-//***** GL_EXT_vertex_weighting *****//
-const
- GL_VERTEX_WEIGHTING_EXT = $8509;
- GL_MODELVIEW0_EXT = $1700;
- GL_MODELVIEW1_EXT = $850A;
- GL_MODELVIEW0_MATRIX_EXT = $0BA6;
- GL_MODELVIEW1_MATRIX_EXT = $8506;
- GL_CURRENT_VERTEX_WEIGHT_EXT = $850B;
- GL_VERTEX_WEIGHT_ARRAY_EXT = $850C;
- GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D;
- GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E;
- GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F;
- GL_MODELVIEW0_STACK_DEPTH_EXT = $0BA3;
- GL_MODELVIEW1_STACK_DEPTH_EXT = $8502;
- GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510;
-var
- glVertexWeightfEXT: procedure(weight: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexWeightfvEXT: procedure(weight: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexWeightPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_vertex_weighting: Boolean;
-
-//***** GL_HP_occlusion_test *****//
-const
- GL_OCCLUSION_TEST_HP = $8165;
- GL_OCCLUSION_TEST_RESULT_HP = $8166;
-
-function Load_GL_HP_occlusion_test: Boolean;
-
-//***** GL_NV_blend_square *****//
-
-function Load_GL_NV_blend_square: Boolean;
-
-//***** GL_NV_copy_depth_to_color *****//
-const
- GL_DEPTH_STENCIL_TO_RGBA_NV = $886E;
- GL_DEPTH_STENCIL_TO_BGRA_NV = $886F;
-
-function Load_GL_NV_copy_depth_to_color: Boolean;
-
-//***** GL_NV_depth_clamp *****//
-const
- GL_DEPTH_CLAMP_NV = $864F;
-
-function Load_GL_NV_depth_clamp: Boolean;
-
-//***** GL_NV_evaluators *****//
-const
- GL_EVAL_2D_NV = $86C0;
- GL_EVAL_TRIANGULAR_2D_NV = $86C1;
- GL_MAP_TESSELLATION_NV = $86C2;
- GL_MAP_ATTRIB_U_ORDER_NV = $86C3;
- GL_MAP_ATTRIB_V_ORDER_NV = $86C4;
- GL_EVAL_FRACTIONAL_TESSELLATION_NV = $86C5;
- GL_EVAL_VERTEX_ATTRIB0_NV = $86C6;
- GL_EVAL_VERTEX_ATTRIB1_NV = $86C7;
- GL_EVAL_VERTEX_ATTRIB2_NV = $86C8;
- GL_EVAL_VERTEX_ATTRIB3_NV = $86C9;
- GL_EVAL_VERTEX_ATTRIB4_NV = $86CA;
- GL_EVAL_VERTEX_ATTRIB5_NV = $86CB;
- GL_EVAL_VERTEX_ATTRIB6_NV = $86CC;
- GL_EVAL_VERTEX_ATTRIB7_NV = $86CD;
- GL_EVAL_VERTEX_ATTRIB8_NV = $86CE;
- GL_EVAL_VERTEX_ATTRIB9_NV = $86CF;
- GL_EVAL_VERTEX_ATTRIB10_NV = $86D0;
- GL_EVAL_VERTEX_ATTRIB11_NV = $86D1;
- GL_EVAL_VERTEX_ATTRIB12_NV = $86D2;
- GL_EVAL_VERTEX_ATTRIB13_NV = $86D3;
- GL_EVAL_VERTEX_ATTRIB14_NV = $86D4;
- GL_EVAL_VERTEX_ATTRIB15_NV = $86D5;
- GL_MAX_MAP_TESSELLATION_NV = $86D6;
- GL_MAX_RATIONAL_EVAL_ORDER_NV = $86D7;
-var
- glMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; uorder: GLint; vorder: GLint; _packed: GLboolean; const points: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapParameterivNV: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapParameterfvNV: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; _packed: GLboolean; points: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapParameterivNV: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapParameterfvNV: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapAttribParameterivNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetMapAttribParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEvalMapsNV: procedure(target: GLenum; mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_evaluators: Boolean;
-
-//***** GL_NV_fence *****//
-const
- GL_ALL_COMPLETED_NV = $84F2;
- GL_FENCE_STATUS_NV = $84F3;
- GL_FENCE_CONDITION_NV = $84F4;
-var
- glGenFencesNV: procedure(n: GLsizei; fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteFencesNV: procedure(n: GLsizei; const fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSetFenceNV: procedure(fence: GLuint; condition: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTestFenceNV: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFinishFenceNV: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsFenceNV: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetFenceivNV: procedure(fence: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_fence: Boolean;
-
-//***** GL_NV_fog_distance *****//
-const
- GL_FOG_DISTANCE_MODE_NV = $855A;
- GL_EYE_RADIAL_NV = $855B;
- GL_EYE_PLANE_ABSOLUTE_NV = $855C;
-
-function Load_GL_NV_fog_distance: Boolean;
-
-//***** GL_NV_light_max_exponent *****//
-const
- GL_MAX_SHININESS_NV = $8504;
- GL_MAX_SPOT_EXPONENT_NV = $8505;
-
-function Load_GL_NV_light_max_exponent: Boolean;
-
-//***** GL_NV_multisample_filter_hint *****//
-const
- GL_MULTISAMPLE_FILTER_HINT_NV = $8534;
-
-function Load_GL_NV_multisample_filter_hint: Boolean;
-
-//***** GL_NV_occlusion_query *****//
- // GL_OCCLUSION_TEST_HP { already defined }
- // GL_OCCLUSION_TEST_RESULT_HP { already defined }
-const
- GL_PIXEL_COUNTER_BITS_NV = $8864;
- GL_CURRENT_OCCLUSION_QUERY_ID_NV = $8865;
- GL_PIXEL_COUNT_NV = $8866;
- GL_PIXEL_COUNT_AVAILABLE_NV = $8867;
-var
- glGenOcclusionQueriesNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteOcclusionQueriesNV: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsOcclusionQueryNV: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBeginOcclusionQueryNV: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndOcclusionQueryNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetOcclusionQueryivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetOcclusionQueryuivNV: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_occlusion_query: Boolean;
-
-//***** GL_NV_packed_depth_stencil *****//
-const
- GL_DEPTH_STENCIL_NV = $84F9;
- GL_UNSIGNED_INT_24_8_NV = $84FA;
-
-function Load_GL_NV_packed_depth_stencil: Boolean;
-
-//***** GL_NV_point_sprite *****//
-const
- GL_POINT_SPRITE_NV = $8861;
- GL_COORD_REPLACE_NV = $8862;
- GL_POINT_SPRITE_R_MODE_NV = $8863;
-var
- glPointParameteriNV: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameterivNV: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_point_sprite: Boolean;
-
-//***** GL_NV_register_combiners *****//
-const
- GL_REGISTER_COMBINERS_NV = $8522;
- GL_COMBINER0_NV = $8550;
- GL_COMBINER1_NV = $8551;
- GL_COMBINER2_NV = $8552;
- GL_COMBINER3_NV = $8553;
- GL_COMBINER4_NV = $8554;
- GL_COMBINER5_NV = $8555;
- GL_COMBINER6_NV = $8556;
- GL_COMBINER7_NV = $8557;
- GL_VARIABLE_A_NV = $8523;
- GL_VARIABLE_B_NV = $8524;
- GL_VARIABLE_C_NV = $8525;
- GL_VARIABLE_D_NV = $8526;
- GL_VARIABLE_E_NV = $8527;
- GL_VARIABLE_F_NV = $8528;
- GL_VARIABLE_G_NV = $8529;
- GL_CONSTANT_COLOR0_NV = $852A;
- GL_CONSTANT_COLOR1_NV = $852B;
- GL_PRIMARY_COLOR_NV = $852C;
- GL_SECONDARY_COLOR_NV = $852D;
- GL_SPARE0_NV = $852E;
- GL_SPARE1_NV = $852F;
- GL_UNSIGNED_IDENTITY_NV = $8536;
- GL_UNSIGNED_INVERT_NV = $8537;
- GL_EXPAND_NORMAL_NV = $8538;
- GL_EXPAND_NEGATE_NV = $8539;
- GL_HALF_BIAS_NORMAL_NV = $853A;
- GL_HALF_BIAS_NEGATE_NV = $853B;
- GL_SIGNED_IDENTITY_NV = $853C;
- GL_SIGNED_NEGATE_NV = $853D;
- GL_E_TIMES_F_NV = $8531;
- GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532;
- GL_SCALE_BY_TWO_NV = $853E;
- GL_SCALE_BY_FOUR_NV = $853F;
- GL_SCALE_BY_ONE_HALF_NV = $8540;
- GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541;
- GL_DISCARD_NV = $8530;
- GL_COMBINER_INPUT_NV = $8542;
- GL_COMBINER_MAPPING_NV = $8543;
- GL_COMBINER_COMPONENT_USAGE_NV = $8544;
- GL_COMBINER_AB_DOT_PRODUCT_NV = $8545;
- GL_COMBINER_CD_DOT_PRODUCT_NV = $8546;
- GL_COMBINER_MUX_SUM_NV = $8547;
- GL_COMBINER_SCALE_NV = $8548;
- GL_COMBINER_BIAS_NV = $8549;
- GL_COMBINER_AB_OUTPUT_NV = $854A;
- GL_COMBINER_CD_OUTPUT_NV = $854B;
- GL_COMBINER_SUM_OUTPUT_NV = $854C;
- GL_NUM_GENERAL_COMBINERS_NV = $854E;
- GL_COLOR_SUM_CLAMP_NV = $854F;
- GL_MAX_GENERAL_COMBINERS_NV = $854D;
-var
- glCombinerParameterfvNV: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCombinerParameterivNV: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCombinerParameterfNV: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCombinerParameteriNV: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCombinerInputNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCombinerOutputNV: procedure(stage: GLenum; portion: GLenum; abOutput: GLenum; cdOutput: GLenum; sumOutput: GLenum; scale: GLenum; bias: GLenum; abDotProduct: GLboolean; cdDotProduct: GLboolean; muxSum: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFinalCombinerInputNV: procedure(variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCombinerInputParameterfvNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCombinerInputParameterivNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCombinerOutputParameterfvNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCombinerOutputParameterivNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetFinalCombinerInputParameterfvNV: procedure(variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetFinalCombinerInputParameterivNV: procedure(variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_register_combiners: Boolean;
-
-//***** GL_NV_register_combiners2 *****//
-const
- GL_PER_STAGE_CONSTANTS_NV = $8535;
-var
- glCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_register_combiners2: Boolean;
-
-//***** GL_NV_texgen_emboss *****//
-const
- GL_EMBOSS_MAP_NV = $855F;
- GL_EMBOSS_LIGHT_NV = $855D;
- GL_EMBOSS_CONSTANT_NV = $855E;
-
-function Load_GL_NV_texgen_emboss: Boolean;
-
-//***** GL_NV_texgen_reflection *****//
-const
- GL_NORMAL_MAP_NV = $8511;
- GL_REFLECTION_MAP_NV = $8512;
-
-function Load_GL_NV_texgen_reflection: Boolean;
-
-//***** GL_NV_texture_compression_vtc *****//
- // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined }
- // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined }
- // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT { already defined }
- // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT { already defined }
-
-function Load_GL_NV_texture_compression_vtc: Boolean;
-
-//***** GL_NV_texture_env_combine4 *****//
-const
- GL_COMBINE4_NV = $8503;
- GL_SOURCE3_RGB_NV = $8583;
- GL_SOURCE3_ALPHA_NV = $858B;
- GL_OPERAND3_RGB_NV = $8593;
- GL_OPERAND3_ALPHA_NV = $859B;
-
-function Load_GL_NV_texture_env_combine4: Boolean;
-
-//***** GL_NV_texture_rectangle *****//
-const
- GL_TEXTURE_RECTANGLE_NV = $84F5;
- GL_TEXTURE_BINDING_RECTANGLE_NV = $84F6;
- GL_PROXY_TEXTURE_RECTANGLE_NV = $84F7;
- GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = $84F8;
-
-function Load_GL_NV_texture_rectangle: Boolean;
-
-//***** GL_NV_texture_shader *****//
-const
- GL_TEXTURE_SHADER_NV = $86DE;
- GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = $86D9;
- GL_SHADER_OPERATION_NV = $86DF;
- GL_CULL_MODES_NV = $86E0;
- GL_OFFSET_TEXTURE_MATRIX_NV = $86E1;
- GL_OFFSET_TEXTURE_SCALE_NV = $86E2;
- GL_OFFSET_TEXTURE_BIAS_NV = $86E3;
- GL_PREVIOUS_TEXTURE_INPUT_NV = $86E4;
- GL_CONST_EYE_NV = $86E5;
- GL_SHADER_CONSISTENT_NV = $86DD;
- GL_PASS_THROUGH_NV = $86E6;
- GL_CULL_FRAGMENT_NV = $86E7;
- GL_OFFSET_TEXTURE_2D_NV = $86E8;
- GL_OFFSET_TEXTURE_RECTANGLE_NV = $864C;
- GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = $864D;
- GL_DEPENDENT_AR_TEXTURE_2D_NV = $86E9;
- GL_DEPENDENT_GB_TEXTURE_2D_NV = $86EA;
- GL_DOT_PRODUCT_NV = $86EC;
- GL_DOT_PRODUCT_DEPTH_REPLACE_NV = $86ED;
- GL_DOT_PRODUCT_TEXTURE_2D_NV = $86EE;
- GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = $864E;
- GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = $86F0;
- GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = $86F1;
- GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = $86F2;
- GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = $86F3;
- GL_HILO_NV = $86F4;
- GL_DSDT_NV = $86F5;
- GL_DSDT_MAG_NV = $86F6;
- GL_DSDT_MAG_VIB_NV = $86F7;
- GL_UNSIGNED_INT_S8_S8_8_8_NV = $86DA;
- GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = $86DB;
- GL_SIGNED_RGBA_NV = $86FB;
- GL_SIGNED_RGBA8_NV = $86FC;
- GL_SIGNED_RGB_NV = $86FE;
- GL_SIGNED_RGB8_NV = $86FF;
- GL_SIGNED_LUMINANCE_NV = $8701;
- GL_SIGNED_LUMINANCE8_NV = $8702;
- GL_SIGNED_LUMINANCE_ALPHA_NV = $8703;
- GL_SIGNED_LUMINANCE8_ALPHA8_NV = $8704;
- GL_SIGNED_ALPHA_NV = $8705;
- GL_SIGNED_ALPHA8_NV = $8706;
- GL_SIGNED_INTENSITY_NV = $8707;
- GL_SIGNED_INTENSITY8_NV = $8708;
- GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = $870C;
- GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = $870D;
- GL_HILO16_NV = $86F8;
- GL_SIGNED_HILO_NV = $86F9;
- GL_SIGNED_HILO16_NV = $86FA;
- GL_DSDT8_NV = $8709;
- GL_DSDT8_MAG8_NV = $870A;
- GL_DSDT_MAG_INTENSITY_NV = $86DC;
- GL_DSDT8_MAG8_INTENSITY8_NV = $870B;
- GL_HI_SCALE_NV = $870E;
- GL_LO_SCALE_NV = $870F;
- GL_DS_SCALE_NV = $8710;
- GL_DT_SCALE_NV = $8711;
- GL_MAGNITUDE_SCALE_NV = $8712;
- GL_VIBRANCE_SCALE_NV = $8713;
- GL_HI_BIAS_NV = $8714;
- GL_LO_BIAS_NV = $8715;
- GL_DS_BIAS_NV = $8716;
- GL_DT_BIAS_NV = $8717;
- GL_MAGNITUDE_BIAS_NV = $8718;
- GL_VIBRANCE_BIAS_NV = $8719;
- GL_TEXTURE_BORDER_VALUES_NV = $871A;
- GL_TEXTURE_HI_SIZE_NV = $871B;
- GL_TEXTURE_LO_SIZE_NV = $871C;
- GL_TEXTURE_DS_SIZE_NV = $871D;
- GL_TEXTURE_DT_SIZE_NV = $871E;
- GL_TEXTURE_MAG_SIZE_NV = $871F;
-
-function Load_GL_NV_texture_shader: Boolean;
-
-//***** GL_NV_texture_shader2 *****//
-const
- GL_DOT_PRODUCT_TEXTURE_3D_NV = $86EF;
- // GL_HILO_NV { already defined }
- // GL_DSDT_NV { already defined }
- // GL_DSDT_MAG_NV { already defined }
- // GL_DSDT_MAG_VIB_NV { already defined }
- // GL_UNSIGNED_INT_S8_S8_8_8_NV { already defined }
- // GL_UNSIGNED_INT_8_8_S8_S8_REV_NV { already defined }
- // GL_SIGNED_RGBA_NV { already defined }
- // GL_SIGNED_RGBA8_NV { already defined }
- // GL_SIGNED_RGB_NV { already defined }
- // GL_SIGNED_RGB8_NV { already defined }
- // GL_SIGNED_LUMINANCE_NV { already defined }
- // GL_SIGNED_LUMINANCE8_NV { already defined }
- // GL_SIGNED_LUMINANCE_ALPHA_NV { already defined }
- // GL_SIGNED_LUMINANCE8_ALPHA8_NV { already defined }
- // GL_SIGNED_ALPHA_NV { already defined }
- // GL_SIGNED_ALPHA8_NV { already defined }
- // GL_SIGNED_INTENSITY_NV { already defined }
- // GL_SIGNED_INTENSITY8_NV { already defined }
- // GL_SIGNED_RGB_UNSIGNED_ALPHA_NV { already defined }
- // GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV { already defined }
- // GL_HILO16_NV { already defined }
- // GL_SIGNED_HILO_NV { already defined }
- // GL_SIGNED_HILO16_NV { already defined }
- // GL_DSDT8_NV { already defined }
- // GL_DSDT8_MAG8_NV { already defined }
- // GL_DSDT_MAG_INTENSITY_NV { already defined }
- // GL_DSDT8_MAG8_INTENSITY8_NV { already defined }
-
-function Load_GL_NV_texture_shader2: Boolean;
-
-//***** GL_NV_texture_shader3 *****//
-const
- GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = $8850;
- GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = $8851;
- GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8852;
- GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = $8853;
- GL_OFFSET_HILO_TEXTURE_2D_NV = $8854;
- GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = $8855;
- GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = $8856;
- GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8857;
- GL_DEPENDENT_HILO_TEXTURE_2D_NV = $8858;
- GL_DEPENDENT_RGB_TEXTURE_3D_NV = $8859;
- GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = $885A;
- GL_DOT_PRODUCT_PASS_THROUGH_NV = $885B;
- GL_DOT_PRODUCT_TEXTURE_1D_NV = $885C;
- GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = $885D;
- GL_HILO8_NV = $885E;
- GL_SIGNED_HILO8_NV = $885F;
- GL_FORCE_BLUE_TO_ONE_NV = $8860;
-
-function Load_GL_NV_texture_shader3: Boolean;
-
-//***** GL_NV_vertex_array_range *****//
-const
- GL_VERTEX_ARRAY_RANGE_NV = $851D;
- GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E;
- GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F;
- GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520;
- GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521;
-var
- glVertexArrayRangeNV: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFlushVertexArrayRangeNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-{$IFDEF WINDOWS}
- wglAllocateMemoryNV: function(size: GLsizei; readFrequency: GLfloat; writeFrequency: GLfloat; priority: GLfloat): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglFreeMemoryNV: procedure(pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-{$ENDIF}
-
-function Load_GL_NV_vertex_array_range: Boolean;
-
-//***** GL_NV_vertex_array_range2 *****//
-const
- GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = $8533;
-
-function Load_GL_NV_vertex_array_range2: Boolean;
-
-//***** GL_NV_vertex_program *****//
-const
- GL_VERTEX_PROGRAM_NV = $8620;
- GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642;
- GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643;
- GL_VERTEX_STATE_PROGRAM_NV = $8621;
- GL_ATTRIB_ARRAY_SIZE_NV = $8623;
- GL_ATTRIB_ARRAY_STRIDE_NV = $8624;
- GL_ATTRIB_ARRAY_TYPE_NV = $8625;
- GL_CURRENT_ATTRIB_NV = $8626;
- GL_PROGRAM_PARAMETER_NV = $8644;
- GL_ATTRIB_ARRAY_POINTER_NV = $8645;
- GL_PROGRAM_TARGET_NV = $8646;
- GL_PROGRAM_LENGTH_NV = $8627;
- GL_PROGRAM_RESIDENT_NV = $8647;
- GL_PROGRAM_STRING_NV = $8628;
- GL_TRACK_MATRIX_NV = $8648;
- GL_TRACK_MATRIX_TRANSFORM_NV = $8649;
- GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E;
- GL_MAX_TRACK_MATRICES_NV = $862F;
- GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640;
- GL_CURRENT_MATRIX_NV = $8641;
- GL_VERTEX_PROGRAM_BINDING_NV = $864A;
- GL_PROGRAM_ERROR_POSITION_NV = $864B;
- GL_MODELVIEW_PROJECTION_NV = $8629;
- GL_MATRIX0_NV = $8630;
- GL_MATRIX1_NV = $8631;
- GL_MATRIX2_NV = $8632;
- GL_MATRIX3_NV = $8633;
- GL_MATRIX4_NV = $8634;
- GL_MATRIX5_NV = $8635;
- GL_MATRIX6_NV = $8636;
- GL_MATRIX7_NV = $8637;
- GL_IDENTITY_NV = $862A;
- GL_INVERSE_NV = $862B;
- GL_TRANSPOSE_NV = $862C;
- GL_INVERSE_TRANSPOSE_NV = $862D;
- GL_VERTEX_ATTRIB_ARRAY0_NV = $8650;
- GL_VERTEX_ATTRIB_ARRAY1_NV = $8651;
- GL_VERTEX_ATTRIB_ARRAY2_NV = $8652;
- GL_VERTEX_ATTRIB_ARRAY3_NV = $8653;
- GL_VERTEX_ATTRIB_ARRAY4_NV = $8654;
- GL_VERTEX_ATTRIB_ARRAY5_NV = $8655;
- GL_VERTEX_ATTRIB_ARRAY6_NV = $8656;
- GL_VERTEX_ATTRIB_ARRAY7_NV = $8657;
- GL_VERTEX_ATTRIB_ARRAY8_NV = $8658;
- GL_VERTEX_ATTRIB_ARRAY9_NV = $8659;
- GL_VERTEX_ATTRIB_ARRAY10_NV = $865A;
- GL_VERTEX_ATTRIB_ARRAY11_NV = $865B;
- GL_VERTEX_ATTRIB_ARRAY12_NV = $865C;
- GL_VERTEX_ATTRIB_ARRAY13_NV = $865D;
- GL_VERTEX_ATTRIB_ARRAY14_NV = $865E;
- GL_VERTEX_ATTRIB_ARRAY15_NV = $865F;
- GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660;
- GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661;
- GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662;
- GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663;
- GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664;
- GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665;
- GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666;
- GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667;
- GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668;
- GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669;
- GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A;
- GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B;
- GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C;
- GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D;
- GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E;
- GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F;
- GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670;
- GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671;
- GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672;
- GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673;
- GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674;
- GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675;
- GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676;
- GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677;
- GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678;
- GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679;
- GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A;
- GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B;
- GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C;
- GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D;
- GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E;
- GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F;
-var
- glBindProgramNV: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteProgramsNV: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glExecuteProgramNV: procedure(target: GLenum; id: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAreProgramsResidentNV: function(n: GLsizei; const ids: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRequestResidentProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramParameterdvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramStringNV: procedure(id: GLuint; pname: GLenum; _program: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTrackMatrixivNV: procedure(target: GLenum; address: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribdvNV: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribfvNV: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribivNV: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribPointervNV: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsProgramNV: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLoadProgramNV: procedure(target: GLenum; id: GLuint; len: GLsizei; const _program: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramParameter4fNV: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramParameter4fvNV: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramParameters4dvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramParameters4fvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTrackMatrixNV: procedure(target: GLenum; address: GLuint; matrix: GLenum; transform: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribPointerNV: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1sNV: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1fNV: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1dNV: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2sNV: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4ubNV: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4ubvNV: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs1svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs1fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs1dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs2svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs2fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs2dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs3svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs3fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs3dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs4svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs4fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs4dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs4ubvNV: procedure(index: GLuint; n: GLsizei; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_vertex_program: Boolean;
-
-//***** GL_NV_vertex_program1_1 *****//
-
-function Load_GL_NV_vertex_program1_1: Boolean;
-
-//***** GL_ATI_element_array *****//
-const
- GL_ELEMENT_ARRAY_ATI = $8768;
- GL_ELEMENT_ARRAY_TYPE_ATI = $8769;
- GL_ELEMENT_ARRAY_POINTER_ATI = $876A;
-var
- glElementPointerATI: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawElementArrayATI: procedure(mode: GLenum; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawRangeElementArrayATI: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_element_array: Boolean;
-
-//***** GL_ATI_envmap_bumpmap *****//
-const
- GL_BUMP_ROT_MATRIX_ATI = $8775;
- GL_BUMP_ROT_MATRIX_SIZE_ATI = $8776;
- GL_BUMP_NUM_TEX_UNITS_ATI = $8777;
- GL_BUMP_TEX_UNITS_ATI = $8778;
- GL_DUDV_ATI = $8779;
- GL_DU8DV8_ATI = $877A;
- GL_BUMP_ENVMAP_ATI = $877B;
- GL_BUMP_TARGET_ATI = $877C;
-var
- glTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_envmap_bumpmap: Boolean;
-
-//***** GL_ATI_fragment_shader *****//
-const
- GL_FRAGMENT_SHADER_ATI = $8920;
- GL_REG_0_ATI = $8921;
- GL_REG_1_ATI = $8922;
- GL_REG_2_ATI = $8923;
- GL_REG_3_ATI = $8924;
- GL_REG_4_ATI = $8925;
- GL_REG_5_ATI = $8926;
- GL_CON_0_ATI = $8941;
- GL_CON_1_ATI = $8942;
- GL_CON_2_ATI = $8943;
- GL_CON_3_ATI = $8944;
- GL_CON_4_ATI = $8945;
- GL_CON_5_ATI = $8946;
- GL_CON_6_ATI = $8947;
- GL_CON_7_ATI = $8948;
- GL_MOV_ATI = $8961;
- GL_ADD_ATI = $8963;
- GL_MUL_ATI = $8964;
- GL_SUB_ATI = $8965;
- GL_DOT3_ATI = $8966;
- GL_DOT4_ATI = $8967;
- GL_MAD_ATI = $8968;
- GL_LERP_ATI = $8969;
- GL_CND_ATI = $896A;
- GL_CND0_ATI = $896B;
- GL_DOT2_ADD_ATI = $896C;
- GL_SECONDARY_INTERPOLATOR_ATI = $896D;
- GL_SWIZZLE_STR_ATI = $8976;
- GL_SWIZZLE_STQ_ATI = $8977;
- GL_SWIZZLE_STR_DR_ATI = $8978;
- GL_SWIZZLE_STQ_DQ_ATI = $8979;
- GL_RED_BIT_ATI = $0001;
- GL_GREEN_BIT_ATI = $0002;
- GL_BLUE_BIT_ATI = $0004;
- GL_2X_BIT_ATI = $0001;
- GL_4X_BIT_ATI = $0002;
- GL_8X_BIT_ATI = $0004;
- GL_HALF_BIT_ATI = $0008;
- GL_QUARTER_BIT_ATI = $0010;
- GL_EIGHTH_BIT_ATI = $0020;
- GL_SATURATE_BIT_ATI = $0040;
- // GL_2X_BIT_ATI { already defined }
- GL_COMP_BIT_ATI = $0002;
- GL_NEGATE_BIT_ATI = $0004;
- GL_BIAS_BIT_ATI = $0008;
-var
- glGenFragmentShadersATI: function(range: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindFragmentShaderATI: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteFragmentShaderATI: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBeginFragmentShaderATI: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndFragmentShaderATI: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPassTexCoordATI: procedure(dst: GLuint; coord: GLuint; swizzle: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSampleMapATI: procedure(dst: GLuint; interp: GLuint; swizzle: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAlphaFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAlphaFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAlphaFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSetFragmentShaderConstantATI: procedure(dst: GLuint; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_fragment_shader: Boolean;
-
-//***** GL_ATI_pn_triangles *****//
-const
- GL_PN_TRIANGLES_ATI = $87F0;
- GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F1;
- GL_PN_TRIANGLES_POINT_MODE_ATI = $87F2;
- GL_PN_TRIANGLES_NORMAL_MODE_ATI = $87F3;
- GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F4;
- GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = $87F5;
- GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = $87F6;
- GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = $87F7;
- GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = $87F8;
-var
- glPNTrianglesiATI: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPNTrianglesfATI: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_pn_triangles: Boolean;
-
-//***** GL_ATI_texture_mirror_once *****//
-const
- GL_MIRROR_CLAMP_ATI = $8742;
- GL_MIRROR_CLAMP_TO_EDGE_ATI = $8743;
-
-function Load_GL_ATI_texture_mirror_once: Boolean;
-
-//***** GL_ATI_vertex_array_object *****//
-const
- GL_STATIC_ATI = $8760;
- GL_DYNAMIC_ATI = $8761;
- GL_PRESERVE_ATI = $8762;
- GL_DISCARD_ATI = $8763;
- GL_OBJECT_BUFFER_SIZE_ATI = $8764;
- GL_OBJECT_BUFFER_USAGE_ATI = $8765;
- GL_ARRAY_OBJECT_BUFFER_ATI = $8766;
- GL_ARRAY_OBJECT_OFFSET_ATI = $8767;
-var
- glNewObjectBufferATI: function(size: GLsizei; const pointer: PGLvoid; usage: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsObjectBufferATI: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUpdateObjectBufferATI: procedure(buffer: GLuint; offset: GLuint; size: GLsizei; const pointer: PGLvoid; preserve: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetObjectBufferfvATI: procedure(buffer: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetObjectBufferivATI: procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteObjectBufferATI: procedure(buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glArrayObjectATI: procedure(_array: GLenum; size: GLint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetArrayObjectfvATI: procedure(_array: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetArrayObjectivATI: procedure(_array: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVariantArrayObjectATI: procedure(id: GLuint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantArrayObjectfvATI: procedure(id: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVariantArrayObjectivATI: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_vertex_array_object: Boolean;
-
-//***** GL_ATI_vertex_streams *****//
-const
- GL_MAX_VERTEX_STREAMS_ATI = $876B;
- GL_VERTEX_STREAM0_ATI = $876C;
- GL_VERTEX_STREAM1_ATI = $876D;
- GL_VERTEX_STREAM2_ATI = $876E;
- GL_VERTEX_STREAM3_ATI = $876F;
- GL_VERTEX_STREAM4_ATI = $8770;
- GL_VERTEX_STREAM5_ATI = $8771;
- GL_VERTEX_STREAM6_ATI = $8772;
- GL_VERTEX_STREAM7_ATI = $8773;
- GL_VERTEX_SOURCE_ATI = $8774;
-var
- glVertexStream1s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream1dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream2dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream3dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexStream4dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3b: procedure(stream: GLenum; coords: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3bv: procedure(stream: GLenum; coords: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalStream3dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glClientActiveVertexStream: procedure(stream: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexBlendEnvi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexBlendEnvf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_vertex_streams: Boolean;
-
-{$IFDEF WINDOWS}
-//***** WGL_I3D_image_buffer *****//
-const
- WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = $0001;
- WGL_IMAGE_BUFFER_LOCK_I3D = $0002;
-var
- wglCreateImageBufferI3D: function(hDC: HDC; dwSize: DWORD; uFlags: UINT): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDestroyImageBufferI3D: function(hDC: HDC; pAddress: PGLvoid): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglAssociateImageBufferEventsI3D: function(hdc: HDC; pEvent: PHandle; pAddress: PGLvoid; pSize: PDWORD; count: UINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglReleaseImageBufferEventsI3D: function(hdc: HDC; pAddress: PGLvoid; count: UINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_image_buffer: Boolean;
-
-//***** WGL_I3D_swap_frame_lock *****//
-var
- wglEnableFrameLockI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDisableFrameLockI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglIsEnabledFrameLockI3D: function(pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglQueryFrameLockMasterI3D: function(pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_swap_frame_lock: Boolean;
-
-//***** WGL_I3D_swap_frame_usage *****//
-var
- wglGetFrameUsageI3D: function(pUsage: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglBeginFrameTrackingI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglEndFrameTrackingI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglQueryFrameTrackingI3D: function(pFrameCount: PDWORD; pMissedFrames: PDWORD; pLastMissedUsage: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_swap_frame_usage: Boolean;
-{$ENDIF}
-
-//***** GL_3DFX_texture_compression_FXT1 *****//
-const
- GL_COMPRESSED_RGB_FXT1_3DFX = $86B0;
- GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1;
-
-function Load_GL_3DFX_texture_compression_FXT1: Boolean;
-
-//***** GL_IBM_cull_vertex *****//
-const
- GL_CULL_VERTEX_IBM = $1928A;
-
-function Load_GL_IBM_cull_vertex: Boolean;
-
-//***** GL_IBM_multimode_draw_arrays *****//
-var
- glMultiModeDrawArraysIBM: procedure(mode: PGLenum; first: PGLint; count: PGLsizei; primcount: GLsizei; modestride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiModeDrawElementsIBM: procedure(mode: PGLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; modestride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_IBM_multimode_draw_arrays: Boolean;
-
-//***** GL_IBM_raster_pos_clip *****//
-const
- GL_RASTER_POSITION_UNCLIPPED_IBM = $19262;
-
-function Load_GL_IBM_raster_pos_clip: Boolean;
-
-//***** GL_IBM_texture_mirrored_repeat *****//
-const
- GL_MIRRORED_REPEAT_IBM = $8370;
-
-function Load_GL_IBM_texture_mirrored_repeat: Boolean;
-
-//***** GL_IBM_vertex_array_lists *****//
-const
- GL_VERTEX_ARRAY_LIST_IBM = $1929E;
- GL_NORMAL_ARRAY_LIST_IBM = $1929F;
- GL_COLOR_ARRAY_LIST_IBM = $192A0;
- GL_INDEX_ARRAY_LIST_IBM = $192A1;
- GL_TEXTURE_COORD_ARRAY_LIST_IBM = $192A2;
- GL_EDGE_FLAG_ARRAY_LIST_IBM = $192A3;
- GL_FOG_COORDINATE_ARRAY_LIST_IBM = $192A4;
- GL_SECONDARY_COLOR_ARRAY_LIST_IBM = $192A5;
- GL_VERTEX_ARRAY_LIST_STRIDE_IBM = $192A8;
- GL_NORMAL_ARRAY_LIST_STRIDE_IBM = $192A9;
- GL_COLOR_ARRAY_LIST_STRIDE_IBM = $192AA;
- GL_INDEX_ARRAY_LIST_STRIDE_IBM = $192AB;
- GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = $192AC;
- GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = $192AD;
- GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = $192AE;
- GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = $192AF;
-var
- glColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEdgeFlagPointerListIBM: procedure(stride: GLint; const pointer: PGLboolean; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormalPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoordPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_IBM_vertex_array_lists: Boolean;
-
-//***** GL_MESA_resize_buffers *****//
-var
- glResizeBuffersMESA: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_MESA_resize_buffers: Boolean;
-
-//***** GL_MESA_window_pos *****//
-var
- glWindowPos2dMESA: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2fMESA: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2iMESA: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2sMESA: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3iMESA: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3sMESA: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4iMESA: procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4sMESA: procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos4dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_MESA_window_pos: Boolean;
-
-//***** GL_OML_interlace *****//
-const
- GL_INTERLACE_OML = $8980;
- GL_INTERLACE_READ_OML = $8981;
-
-function Load_GL_OML_interlace: Boolean;
-
-//***** GL_OML_resample *****//
-const
- GL_PACK_RESAMPLE_OML = $8984;
- GL_UNPACK_RESAMPLE_OML = $8985;
- GL_RESAMPLE_REPLICATE_OML = $8986;
- GL_RESAMPLE_ZERO_FILL_OML = $8987;
- GL_RESAMPLE_AVERAGE_OML = $8988;
- GL_RESAMPLE_DECIMATE_OML = $8989;
- // GL_RESAMPLE_AVERAGE_OML { already defined }
-
-function Load_GL_OML_resample: Boolean;
-
-//***** GL_OML_subsample *****//
-const
- GL_FORMAT_SUBSAMPLE_24_24_OML = $8982;
- GL_FORMAT_SUBSAMPLE_244_244_OML = $8983;
-
-function Load_GL_OML_subsample: Boolean;
-
-//***** GL_SGIS_generate_mipmap *****//
-const
- GL_GENERATE_MIPMAP_SGIS = $8191;
- GL_GENERATE_MIPMAP_HINT_SGIS = $8192;
-
-function Load_GL_SGIS_generate_mipmap: Boolean;
-
-//***** GL_SGIS_multisample *****//
-const
- GLX_SAMPLE_BUFFERS_SGIS = $186A0;
- GLX_SAMPLES_SGIS = $186A1;
- GL_MULTISAMPLE_SGIS = $809D;
- GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E;
- GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F;
- GL_SAMPLE_MASK_SGIS = $80A0;
- GL_MULTISAMPLE_BIT_EXT = $20000000;
- GL_1PASS_SGIS = $80A1;
- GL_2PASS_0_SGIS = $80A2;
- GL_2PASS_1_SGIS = $80A3;
- GL_4PASS_0_SGIS = $80A4;
- GL_4PASS_1_SGIS = $80A5;
- GL_4PASS_2_SGIS = $80A6;
- GL_4PASS_3_SGIS = $80A7;
- GL_SAMPLE_BUFFERS_SGIS = $80A8;
- GL_SAMPLES_SGIS = $80A9;
- GL_SAMPLE_MASK_VALUE_SGIS = $80AA;
- GL_SAMPLE_MASK_INVERT_SGIS = $80AB;
- GL_SAMPLE_PATTERN_SGIS = $80AC;
-var
- glSampleMaskSGIS: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSamplePatternSGIS: procedure(pattern: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_SGIS_multisample: Boolean;
-
-//***** GL_SGIS_pixel_texture *****//
-const
- GL_PIXEL_TEXTURE_SGIS = $8353;
- GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354;
- GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355;
- GL_PIXEL_GROUP_COLOR_SGIS = $8356;
-var
- glPixelTexGenParameteriSGIS: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPixelTexGenParameterfSGIS: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPixelTexGenParameterivSGIS: procedure(pname: GLenum; params: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetPixelTexGenParameterfvSGIS: procedure(pname: GLenum; params: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_SGIS_pixel_texture: Boolean;
-
-//***** GL_SGIS_texture_border_clamp *****//
- // GL_CLAMP_TO_BORDER_SGIS { already defined }
-
-function Load_GL_SGIS_texture_border_clamp: Boolean;
-
-//***** GL_SGIS_texture_color_mask *****//
-const
- GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF;
-var
- glTextureColorMaskSGIS: procedure(r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_SGIS_texture_color_mask: Boolean;
-
-//***** GL_SGIS_texture_edge_clamp *****//
-const
- GL_CLAMP_TO_EDGE_SGIS = $812F;
-
-function Load_GL_SGIS_texture_edge_clamp: Boolean;
-
-//***** GL_SGIS_texture_lod *****//
-const
- GL_TEXTURE_MIN_LOD_SGIS = $813A;
- GL_TEXTURE_MAX_LOD_SGIS = $813B;
- GL_TEXTURE_BASE_LEVEL_SGIS = $813C;
- GL_TEXTURE_MAX_LEVEL_SGIS = $813D;
-
-function Load_GL_SGIS_texture_lod: Boolean;
-
-//***** GL_SGIS_depth_texture *****//
-const
- GL_DEPTH_COMPONENT16_SGIX = $81A5;
- GL_DEPTH_COMPONENT24_SGIX = $81A6;
- GL_DEPTH_COMPONENT32_SGIX = $81A7;
-
-function Load_GL_SGIS_depth_texture: Boolean;
-
-//***** GL_SGIX_fog_offset *****//
-const
- GL_FOG_OFFSET_SGIX = $8198;
- GL_FOG_OFFSET_VALUE_SGIX = $8199;
-
-function Load_GL_SGIX_fog_offset: Boolean;
-
-//***** GL_SGIX_interlace *****//
-const
- GL_INTERLACE_SGIX = $8094;
-
-function Load_GL_SGIX_interlace: Boolean;
-
-//***** GL_SGIX_shadow_ambient *****//
-const
- GL_SHADOW_AMBIENT_SGIX = $80BF;
-
-function Load_GL_SGIX_shadow_ambient: Boolean;
-
-//***** GL_SGI_color_matrix *****//
-const
- GL_COLOR_MATRIX_SGI = $80B1;
- GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2;
- GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3;
- GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4;
- GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5;
- GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6;
- GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7;
- GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8;
- GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9;
- GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA;
- GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB;
-
-function Load_GL_SGI_color_matrix: Boolean;
-
-//***** GL_SGI_color_table *****//
-const
- GL_COLOR_TABLE_SGI = $80D0;
- GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1;
- GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2;
- GL_PROXY_COLOR_TABLE_SGI = $80D3;
- GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4;
- GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5;
- GL_COLOR_TABLE_SCALE_SGI = $80D6;
- GL_COLOR_TABLE_BIAS_SGI = $80D7;
- GL_COLOR_TABLE_FORMAT_SGI = $80D8;
- GL_COLOR_TABLE_WIDTH_SGI = $80D9;
- GL_COLOR_TABLE_RED_SIZE_SGI = $80DA;
- GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB;
- GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC;
- GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD;
- GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE;
- GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF;
-var
- glColorTableSGI: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCopyColorTableSGI: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableSGI: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_SGI_color_table: Boolean;
-
-//***** GL_SGI_texture_color_table *****//
-const
- GL_TEXTURE_COLOR_TABLE_SGI = $80BC;
- GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD;
-
-function Load_GL_SGI_texture_color_table: Boolean;
-
-//***** GL_SUN_vertex *****//
-var
- glColor4ubVertex2fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ubVertex2fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ubVertex3fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4ubVertex3fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3fVertex3fvSUN: procedure(const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3fVertex3fSUN: procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3fVertex3fvSUN: procedure(const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4fNormal3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4fNormal3fVertex3fvSUN: procedure(const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fVertex3fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4fVertex4fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor4ubVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor4ubVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor4fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4fColor4fNormal3fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4fColor4fNormal3fVertex4fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiVertex3fSUN: procedure(rc: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiVertex3fvSUN: procedure(const rc: PGLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor4ubVertex3fSUN: procedure(rc: GLuint; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor4ubVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiNormal3fVertex3fSUN: procedure(rc: GLuint; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_SUN_vertex: Boolean;
-
-//***** GL_ARB_fragment_program *****//
-const
- GL_FRAGMENT_PROGRAM_ARB = $8804;
- // GL_PROGRAM_FORMAT_ASCII_ARB { already defined }
- // GL_PROGRAM_LENGTH_ARB { already defined }
- // GL_PROGRAM_FORMAT_ARB { already defined }
- // GL_PROGRAM_BINDING_ARB { already defined }
- // GL_PROGRAM_INSTRUCTIONS_ARB { already defined }
- // GL_MAX_PROGRAM_INSTRUCTIONS_ARB { already defined }
- // GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined }
- // GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined }
- // GL_PROGRAM_TEMPORARIES_ARB { already defined }
- // GL_MAX_PROGRAM_TEMPORARIES_ARB { already defined }
- // GL_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined }
- // GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined }
- // GL_PROGRAM_PARAMETERS_ARB { already defined }
- // GL_MAX_PROGRAM_PARAMETERS_ARB { already defined }
- // GL_PROGRAM_NATIVE_PARAMETERS_ARB { already defined }
- // GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB { already defined }
- // GL_PROGRAM_ATTRIBS_ARB { already defined }
- // GL_MAX_PROGRAM_ATTRIBS_ARB { already defined }
- // GL_PROGRAM_NATIVE_ATTRIBS_ARB { already defined }
- // GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB { already defined }
- // GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB { already defined }
- // GL_MAX_PROGRAM_ENV_PARAMETERS_ARB { already defined }
- // GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB { already defined }
- GL_PROGRAM_ALU_INSTRUCTIONS_ARB = $8805;
- GL_PROGRAM_TEX_INSTRUCTIONS_ARB = $8806;
- GL_PROGRAM_TEX_INDIRECTIONS_ARB = $8807;
- GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $8808;
- GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $8809;
- GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $880A;
- GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = $880B;
- GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = $880C;
- GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = $880D;
- GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $880E;
- GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $880F;
- GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $8810;
- // GL_PROGRAM_STRING_ARB { already defined }
- // GL_PROGRAM_ERROR_POSITION_ARB { already defined }
- // GL_CURRENT_MATRIX_ARB { already defined }
- // GL_TRANSPOSE_CURRENT_MATRIX_ARB { already defined }
- // GL_CURRENT_MATRIX_STACK_DEPTH_ARB { already defined }
- // GL_MAX_PROGRAM_MATRICES_ARB { already defined }
- // GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB { already defined }
- GL_MAX_TEXTURE_COORDS_ARB = $8871;
- GL_MAX_TEXTURE_IMAGE_UNITS_ARB = $8872;
- // GL_PROGRAM_ERROR_STRING_ARB { already defined }
- // GL_MATRIX0_ARB { already defined }
- // GL_MATRIX1_ARB { already defined }
- // GL_MATRIX2_ARB { already defined }
- // GL_MATRIX3_ARB { already defined }
- // GL_MATRIX4_ARB { already defined }
- // GL_MATRIX5_ARB { already defined }
- // GL_MATRIX6_ARB { already defined }
- // GL_MATRIX7_ARB { already defined }
- // GL_MATRIX8_ARB { already defined }
- // GL_MATRIX9_ARB { already defined }
- // GL_MATRIX10_ARB { already defined }
- // GL_MATRIX11_ARB { already defined }
- // GL_MATRIX12_ARB { already defined }
- // GL_MATRIX13_ARB { already defined }
- // GL_MATRIX14_ARB { already defined }
- // GL_MATRIX15_ARB { already defined }
- // GL_MATRIX16_ARB { already defined }
- // GL_MATRIX17_ARB { already defined }
- // GL_MATRIX18_ARB { already defined }
- // GL_MATRIX19_ARB { already defined }
- // GL_MATRIX20_ARB { already defined }
- // GL_MATRIX21_ARB { already defined }
- // GL_MATRIX22_ARB { already defined }
- // GL_MATRIX23_ARB { already defined }
- // GL_MATRIX24_ARB { already defined }
- // GL_MATRIX25_ARB { already defined }
- // GL_MATRIX26_ARB { already defined }
- // GL_MATRIX27_ARB { already defined }
- // GL_MATRIX28_ARB { already defined }
- // GL_MATRIX29_ARB { already defined }
- // GL_MATRIX30_ARB { already defined }
- // GL_MATRIX31_ARB { already defined }
- // glProgramStringARB { already defined }
- // glBindProgramARB { already defined }
- // glDeleteProgramsARB { already defined }
- // glGenProgramsARB { already defined }
- // glProgramEnvParameter4dARB { already defined }
- // glProgramEnvParameter4dvARB { already defined }
- // glProgramEnvParameter4fARB { already defined }
- // glProgramEnvParameter4fvARB { already defined }
- // glProgramLocalParameter4dARB { already defined }
- // glProgramLocalParameter4dvARB { already defined }
- // glProgramLocalParameter4fARB { already defined }
- // glProgramLocalParameter4fvARB { already defined }
- // glGetProgramEnvParameterdvARB { already defined }
- // glGetProgramEnvParameterfvARB { already defined }
- // glGetProgramLocalParameterdvARB { already defined }
- // glGetProgramLocalParameterfvARB { already defined }
- // glGetProgramivARB { already defined }
- // glGetProgramStringARB { already defined }
- // glIsProgramARB { already defined }
-
-function Load_GL_ARB_fragment_program: Boolean;
-
-//***** GL_ATI_text_fragment_shader *****//
-const
- GL_TEXT_FRAGMENT_SHADER_ATI = $8200;
-
-function Load_GL_ATI_text_fragment_shader: Boolean;
-
-//***** GL_APPLE_client_storage *****//
-const
- GL_UNPACK_CLIENT_STORAGE_APPLE = $85B2;
-
-function Load_GL_APPLE_client_storage: Boolean;
-
-//***** GL_APPLE_element_array *****//
-const
- GL_ELEMENT_ARRAY_APPLE = $8768;
- GL_ELEMENT_ARRAY_TYPE_APPLE = $8769;
- GL_ELEMENT_ARRAY_POINTER_APPLE = $876A;
-var
- glElementPointerAPPLE: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawElementArrayAPPLE: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawElementArrayAPPLE: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_APPLE_element_array: Boolean;
-
-//***** GL_APPLE_fence *****//
-const
- GL_DRAW_PIXELS_APPLE = $8A0A;
- GL_FENCE_APPLE = $8A0B;
-var
- glGenFencesAPPLE: procedure(n: GLsizei; fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteFencesAPPLE: procedure(n: GLsizei; const fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSetFenceAPPLE: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsFenceAPPLE: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTestFenceAPPLE: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFinishFenceAPPLE: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTestObjectAPPLE: function(_object: GLenum; name: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFinishObjectAPPLE: procedure(_object: GLenum; name: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_APPLE_fence: Boolean;
-
-//***** GL_APPLE_vertex_array_object *****//
-const
- GL_VERTEX_ARRAY_BINDING_APPLE = $85B5;
-var
- glBindVertexArrayAPPLE: procedure(_array: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsVertexArrayAPPLE: function(_array: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_APPLE_vertex_array_object: Boolean;
-
-//***** GL_APPLE_vertex_array_range *****//
-const
- GL_VERTEX_ARRAY_RANGE_APPLE = $851D;
- GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = $851E;
- GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE = $8520;
- GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = $8521;
- GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = $851F;
- GL_STORAGE_CACHED_APPLE = $85BE;
- GL_STORAGE_SHARED_APPLE = $85BF;
-var
- glVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFlushVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexArrayParameteriAPPLE: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_APPLE_vertex_array_range: Boolean;
-
-{$IFDEF WINDOWS}
-//***** WGL_ARB_pixel_format *****//
-const
- WGL_NUMBER_PIXEL_FORMATS_ARB = $2000;
- WGL_DRAW_TO_WINDOW_ARB = $2001;
- WGL_DRAW_TO_BITMAP_ARB = $2002;
- WGL_ACCELERATION_ARB = $2003;
- WGL_NEED_PALETTE_ARB = $2004;
- WGL_NEED_SYSTEM_PALETTE_ARB = $2005;
- WGL_SWAP_LAYER_BUFFERS_ARB = $2006;
- WGL_SWAP_METHOD_ARB = $2007;
- WGL_NUMBER_OVERLAYS_ARB = $2008;
- WGL_NUMBER_UNDERLAYS_ARB = $2009;
- WGL_TRANSPARENT_ARB = $200A;
- WGL_TRANSPARENT_RED_VALUE_ARB = $2037;
- WGL_TRANSPARENT_GREEN_VALUE_ARB = $2038;
- WGL_TRANSPARENT_BLUE_VALUE_ARB = $2039;
- WGL_TRANSPARENT_ALPHA_VALUE_ARB = $203A;
- WGL_TRANSPARENT_INDEX_VALUE_ARB = $203B;
- WGL_SHARE_DEPTH_ARB = $200C;
- WGL_SHARE_STENCIL_ARB = $200D;
- WGL_SHARE_ACCUM_ARB = $200E;
- WGL_SUPPORT_GDI_ARB = $200F;
- WGL_SUPPORT_OPENGL_ARB = $2010;
- WGL_DOUBLE_BUFFER_ARB = $2011;
- WGL_STEREO_ARB = $2012;
- WGL_PIXEL_TYPE_ARB = $2013;
- WGL_COLOR_BITS_ARB = $2014;
- WGL_RED_BITS_ARB = $2015;
- WGL_RED_SHIFT_ARB = $2016;
- WGL_GREEN_BITS_ARB = $2017;
- WGL_GREEN_SHIFT_ARB = $2018;
- WGL_BLUE_BITS_ARB = $2019;
- WGL_BLUE_SHIFT_ARB = $201A;
- WGL_ALPHA_BITS_ARB = $201B;
- WGL_ALPHA_SHIFT_ARB = $201C;
- WGL_ACCUM_BITS_ARB = $201D;
- WGL_ACCUM_RED_BITS_ARB = $201E;
- WGL_ACCUM_GREEN_BITS_ARB = $201F;
- WGL_ACCUM_BLUE_BITS_ARB = $2020;
- WGL_ACCUM_ALPHA_BITS_ARB = $2021;
- WGL_DEPTH_BITS_ARB = $2022;
- WGL_STENCIL_BITS_ARB = $2023;
- WGL_AUX_BUFFERS_ARB = $2024;
- WGL_NO_ACCELERATION_ARB = $2025;
- WGL_GENERIC_ACCELERATION_ARB = $2026;
- WGL_FULL_ACCELERATION_ARB = $2027;
- WGL_SWAP_EXCHANGE_ARB = $2028;
- WGL_SWAP_COPY_ARB = $2029;
- WGL_SWAP_UNDEFINED_ARB = $202A;
- WGL_TYPE_RGBA_ARB = $202B;
- WGL_TYPE_COLORINDEX_ARB = $202C;
-var
- wglGetPixelFormatAttribivARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetPixelFormatAttribfvARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglChoosePixelFormatARB: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_pixel_format: Boolean;
-
-//***** WGL_ARB_make_current_read *****//
-const
- WGL_ERROR_INVALID_PIXEL_TYPE_ARB = $2043;
- WGL_ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = $2054;
-var
- wglMakeContextCurrentARB: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetCurrentReadDCARB: function(): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_make_current_read: Boolean;
-
-//***** WGL_ARB_pbuffer *****//
-const
- WGL_DRAW_TO_PBUFFER_ARB = $202D;
- // WGL_DRAW_TO_PBUFFER_ARB { already defined }
- WGL_MAX_PBUFFER_PIXELS_ARB = $202E;
- WGL_MAX_PBUFFER_WIDTH_ARB = $202F;
- WGL_MAX_PBUFFER_HEIGHT_ARB = $2030;
- WGL_PBUFFER_LARGEST_ARB = $2033;
- WGL_PBUFFER_WIDTH_ARB = $2034;
- WGL_PBUFFER_HEIGHT_ARB = $2035;
- WGL_PBUFFER_LOST_ARB = $2036;
-var
- wglCreatePbufferARB: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetPbufferDCARB: function(hPbuffer: THandle): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglReleasePbufferDCARB: function(hPbuffer: THandle; hDC: HDC): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDestroyPbufferARB: function(hPbuffer: THandle): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglQueryPbufferARB: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_pbuffer: Boolean;
-
-//***** WGL_EXT_swap_control *****//
-var
- wglSwapIntervalEXT: function(interval: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetSwapIntervalEXT: function(): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_EXT_swap_control: Boolean;
-
-//***** WGL_ARB_render_texture *****//
-const
- WGL_BIND_TO_TEXTURE_RGB_ARB = $2070;
- WGL_BIND_TO_TEXTURE_RGBA_ARB = $2071;
- WGL_TEXTURE_FORMAT_ARB = $2072;
- WGL_TEXTURE_TARGET_ARB = $2073;
- WGL_MIPMAP_TEXTURE_ARB = $2074;
- WGL_TEXTURE_RGB_ARB = $2075;
- WGL_TEXTURE_RGBA_ARB = $2076;
- WGL_NO_TEXTURE_ARB = $2077;
- WGL_TEXTURE_CUBE_MAP_ARB = $2078;
- WGL_TEXTURE_1D_ARB = $2079;
- WGL_TEXTURE_2D_ARB = $207A;
- // WGL_NO_TEXTURE_ARB { already defined }
- WGL_MIPMAP_LEVEL_ARB = $207B;
- WGL_CUBE_MAP_FACE_ARB = $207C;
- WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $207D;
- WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $207E;
- WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $207F;
- WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $2080;
- WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $2081;
- WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $2082;
- WGL_FRONT_LEFT_ARB = $2083;
- WGL_FRONT_RIGHT_ARB = $2084;
- WGL_BACK_LEFT_ARB = $2085;
- WGL_BACK_RIGHT_ARB = $2086;
- WGL_AUX0_ARB = $2087;
- WGL_AUX1_ARB = $2088;
- WGL_AUX2_ARB = $2089;
- WGL_AUX3_ARB = $208A;
- WGL_AUX4_ARB = $208B;
- WGL_AUX5_ARB = $208C;
- WGL_AUX6_ARB = $208D;
- WGL_AUX7_ARB = $208E;
- WGL_AUX8_ARB = $208F;
- WGL_AUX9_ARB = $2090;
-var
- wglBindTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglReleaseTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglSetPbufferAttribARB: function(hPbuffer: THandle; const piAttribList: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_ARB_render_texture: Boolean;
-
-//***** WGL_EXT_extensions_string *****//
-var
- wglGetExtensionsStringEXT: function(): Pchar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_EXT_extensions_string: Boolean;
-
-//***** WGL_EXT_make_current_read *****//
-var
- wglMakeContextCurrentEXT: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetCurrentReadDCEXT: function(): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_EXT_make_current_read: Boolean;
-
-//***** WGL_EXT_pbuffer *****//
-const
- WGL_DRAW_TO_PBUFFER_EXT = $202D;
- WGL_MAX_PBUFFER_PIXELS_EXT = $202E;
- WGL_MAX_PBUFFER_WIDTH_EXT = $202F;
- WGL_MAX_PBUFFER_HEIGHT_EXT = $2030;
- WGL_OPTIMAL_PBUFFER_WIDTH_EXT = $2031;
- WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = $2032;
- WGL_PBUFFER_LARGEST_EXT = $2033;
- WGL_PBUFFER_WIDTH_EXT = $2034;
- WGL_PBUFFER_HEIGHT_EXT = $2035;
-var
- wglCreatePbufferEXT: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetPbufferDCEXT: function(hPbuffer: THandle): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglReleasePbufferDCEXT: function(hPbuffer: THandle; hDC: HDC): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDestroyPbufferEXT: function(hPbuffer: THandle): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglQueryPbufferEXT: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_EXT_pbuffer: Boolean;
-
-//***** WGL_EXT_pixel_format *****//
-const
- WGL_NUMBER_PIXEL_FORMATS_EXT = $2000;
- WGL_DRAW_TO_WINDOW_EXT = $2001;
- WGL_DRAW_TO_BITMAP_EXT = $2002;
- WGL_ACCELERATION_EXT = $2003;
- WGL_NEED_PALETTE_EXT = $2004;
- WGL_NEED_SYSTEM_PALETTE_EXT = $2005;
- WGL_SWAP_LAYER_BUFFERS_EXT = $2006;
- WGL_SWAP_METHOD_EXT = $2007;
- WGL_NUMBER_OVERLAYS_EXT = $2008;
- WGL_NUMBER_UNDERLAYS_EXT = $2009;
- WGL_TRANSPARENT_EXT = $200A;
- WGL_TRANSPARENT_VALUE_EXT = $200B;
- WGL_SHARE_DEPTH_EXT = $200C;
- WGL_SHARE_STENCIL_EXT = $200D;
- WGL_SHARE_ACCUM_EXT = $200E;
- WGL_SUPPORT_GDI_EXT = $200F;
- WGL_SUPPORT_OPENGL_EXT = $2010;
- WGL_DOUBLE_BUFFER_EXT = $2011;
- WGL_STEREO_EXT = $2012;
- WGL_PIXEL_TYPE_EXT = $2013;
- WGL_COLOR_BITS_EXT = $2014;
- WGL_RED_BITS_EXT = $2015;
- WGL_RED_SHIFT_EXT = $2016;
- WGL_GREEN_BITS_EXT = $2017;
- WGL_GREEN_SHIFT_EXT = $2018;
- WGL_BLUE_BITS_EXT = $2019;
- WGL_BLUE_SHIFT_EXT = $201A;
- WGL_ALPHA_BITS_EXT = $201B;
- WGL_ALPHA_SHIFT_EXT = $201C;
- WGL_ACCUM_BITS_EXT = $201D;
- WGL_ACCUM_RED_BITS_EXT = $201E;
- WGL_ACCUM_GREEN_BITS_EXT = $201F;
- WGL_ACCUM_BLUE_BITS_EXT = $2020;
- WGL_ACCUM_ALPHA_BITS_EXT = $2021;
- WGL_DEPTH_BITS_EXT = $2022;
- WGL_STENCIL_BITS_EXT = $2023;
- WGL_AUX_BUFFERS_EXT = $2024;
- WGL_NO_ACCELERATION_EXT = $2025;
- WGL_GENERIC_ACCELERATION_EXT = $2026;
- WGL_FULL_ACCELERATION_EXT = $2027;
- WGL_SWAP_EXCHANGE_EXT = $2028;
- WGL_SWAP_COPY_EXT = $2029;
- WGL_SWAP_UNDEFINED_EXT = $202A;
- WGL_TYPE_RGBA_EXT = $202B;
- WGL_TYPE_COLORINDEX_EXT = $202C;
-var
- wglGetPixelFormatAttribivEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; piValues: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetPixelFormatAttribfvEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglChoosePixelFormatEXT: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_EXT_pixel_format: Boolean;
-
-//***** WGL_I3D_digital_video_control *****//
-const
- WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = $2050;
- WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = $2051;
- WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = $2052;
- WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = $2053;
-var
- wglGetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglSetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_digital_video_control: Boolean;
-
-//***** WGL_I3D_gamma *****//
-const
- WGL_GAMMA_TABLE_SIZE_I3D = $204E;
- WGL_GAMMA_EXCLUDE_DESKTOP_I3D = $204F;
- // WGL_GAMMA_EXCLUDE_DESKTOP_I3D { already defined }
-var
- wglGetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglSetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetGammaTableI3D: function(hDC: HDC; iEntries: GLint; puRed: PGLUSHORT; puGreen: PGLUSHORT; puBlue: PGLUSHORT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglSetGammaTableI3D: function(hDC: HDC; iEntries: GLint; const puRed: PGLUSHORT; const puGreen: PGLUSHORT; const puBlue: PGLUSHORT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_gamma: Boolean;
-
-//***** WGL_I3D_genlock *****//
-const
- WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = $2044;
- WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = $2045;
- WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = $2046;
- WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = $2047;
- WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = $2048;
- WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = $2049;
- WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = $204A;
- WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = $204B;
- WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = $204C;
-var
- wglEnableGenlockI3D: function(hDC: HDC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglDisableGenlockI3D: function(hDC: HDC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglIsEnabledGenlockI3D: function(hDC: HDC; pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGenlockSourceI3D: function(hDC: HDC; uSource: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetGenlockSourceI3D: function(hDC: HDC; uSource: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGenlockSampleRateI3D: function(hDC: HDC; uRate: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetGenlockSampleRateI3D: function(hDC: HDC; uRate: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGenlockSourceDelayI3D: function(hDC: HDC; uDelay: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglGetGenlockSourceDelayI3D: function(hDC: HDC; uDelay: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- wglQueryGenlockMaxSourceDelayI3D: function(hDC: HDC; uMaxLineDelay: PGLUINT; uMaxPixelDelay: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_WGL_I3D_genlock: Boolean;
-{$ENDIF}
-
-//***** GL_ARB_matrix_palette *****//
-const
- GL_MATRIX_PALETTE_ARB = $8840;
- GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = $8841;
- GL_MAX_PALETTE_MATRICES_ARB = $8842;
- GL_CURRENT_PALETTE_MATRIX_ARB = $8843;
- GL_MATRIX_INDEX_ARRAY_ARB = $8844;
- GL_CURRENT_MATRIX_INDEX_ARB = $8845;
- GL_MATRIX_INDEX_ARRAY_SIZE_ARB = $8846;
- GL_MATRIX_INDEX_ARRAY_TYPE_ARB = $8847;
- GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = $8848;
- GL_MATRIX_INDEX_ARRAY_POINTER_ARB = $8849;
-var
- glCurrentPaletteMatrixARB: procedure(index: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMatrixIndexubvARB: procedure(size: GLint; indices: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMatrixIndexusvARB: procedure(size: GLint; indices: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMatrixIndexuivARB: procedure(size: GLint; indices: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMatrixIndexPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_matrix_palette: Boolean;
-
-//***** GL_NV_element_array *****//
-const
- GL_ELEMENT_ARRAY_TYPE_NV = $8769;
- GL_ELEMENT_ARRAY_POINTER_NV = $876A;
-var
- glElementPointerNV: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawElementArrayNV: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawElementArrayNV: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_element_array: Boolean;
-
-//***** GL_NV_float_buffer *****//
-const
- GL_FLOAT_R_NV = $8880;
- GL_FLOAT_RG_NV = $8881;
- GL_FLOAT_RGB_NV = $8882;
- GL_FLOAT_RGBA_NV = $8883;
- GL_FLOAT_R16_NV = $8884;
- GL_FLOAT_R32_NV = $8885;
- GL_FLOAT_RG16_NV = $8886;
- GL_FLOAT_RG32_NV = $8887;
- GL_FLOAT_RGB16_NV = $8888;
- GL_FLOAT_RGB32_NV = $8889;
- GL_FLOAT_RGBA16_NV = $888A;
- GL_FLOAT_RGBA32_NV = $888B;
- GL_TEXTURE_FLOAT_COMPONENTS_NV = $888C;
- GL_FLOAT_CLEAR_COLOR_VALUE_NV = $888D;
- GL_FLOAT_RGBA_MODE_NV = $888E;
-{$IFDEF WINDOWS}
- WGL_FLOAT_COMPONENTS_NV = $20B0;
- WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = $20B1;
- WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = $20B2;
- WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = $20B3;
- WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = $20B4;
- WGL_TEXTURE_FLOAT_R_NV = $20B5;
- WGL_TEXTURE_FLOAT_RG_NV = $20B6;
- WGL_TEXTURE_FLOAT_RGB_NV = $20B7;
- WGL_TEXTURE_FLOAT_RGBA_NV = $20B8;
-{$ENDIF}
-
-function Load_GL_NV_float_buffer: Boolean;
-
-//***** GL_NV_fragment_program *****//
-const
- GL_FRAGMENT_PROGRAM_NV = $8870;
- GL_MAX_TEXTURE_COORDS_NV = $8871;
- GL_MAX_TEXTURE_IMAGE_UNITS_NV = $8872;
- GL_FRAGMENT_PROGRAM_BINDING_NV = $8873;
- GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = $8868;
- GL_PROGRAM_ERROR_STRING_NV = $8874;
-var
- glProgramNamedParameter4fNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glProgramNamedParameter4dNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramNamedParameterfvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramNamedParameterdvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- // glProgramLocalParameter4dARB { already defined }
- // glProgramLocalParameter4dvARB { already defined }
- // glProgramLocalParameter4fARB { already defined }
- // glProgramLocalParameter4fvARB { already defined }
- // glGetProgramLocalParameterdvARB { already defined }
- // glGetProgramLocalParameterfvARB { already defined }
-
-function Load_GL_NV_fragment_program: Boolean;
-
-//***** GL_NV_primitive_restart *****//
-const
- GL_PRIMITIVE_RESTART_NV = $8558;
- GL_PRIMITIVE_RESTART_INDEX_NV = $8559;
-var
- glPrimitiveRestartNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPrimitiveRestartIndexNV: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_primitive_restart: Boolean;
-
-//***** GL_NV_vertex_program2 *****//
-
-function Load_GL_NV_vertex_program2: Boolean;
-
-{$IFDEF WINDOWS}
-//***** WGL_NV_render_texture_rectangle *****//
-const
- WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = $20A0;
- WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = $20A1;
- WGL_TEXTURE_RECTANGLE_NV = $20A2;
-
-function Load_WGL_NV_render_texture_rectangle: Boolean;
-{$ENDIF}
-
-//***** GL_NV_pixel_data_range *****//
-const
- GL_WRITE_PIXEL_DATA_RANGE_NV = $8878;
- GL_READ_PIXEL_DATA_RANGE_NV = $8879;
- GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = $887A;
- GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = $887B;
- GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = $887C;
- GL_READ_PIXEL_DATA_RANGE_POINTER_NV = $887D;
-var
- glPixelDataRangeNV: procedure(target: GLenum; length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFlushPixelDataRangeNV: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- // wglAllocateMemoryNV { already defined }
- // wglFreeMemoryNV { already defined }
-
-function Load_GL_NV_pixel_data_range: Boolean;
-
-//***** GL_EXT_texture_rectangle *****//
-const
- GL_TEXTURE_RECTANGLE_EXT = $84F5;
- GL_TEXTURE_BINDING_RECTANGLE_EXT = $84F6;
- GL_PROXY_TEXTURE_RECTANGLE_EXT = $84F7;
- GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = $84F8;
-
-function Load_GL_EXT_texture_rectangle: Boolean;
-
-//***** GL_S3_s3tc *****//
-const
- GL_RGB_S3TC = $83A0;
- GL_RGB4_S3TC = $83A1;
- GL_RGBA_S3TC = $83A2;
- GL_RGBA4_S3TC = $83A3;
-
-function Load_GL_S3_s3tc: Boolean;
-
-//***** GL_ATI_draw_buffers *****//
-const
- GL_MAX_DRAW_BUFFERS_ATI = $8824;
- GL_DRAW_BUFFER0_ATI = $8825;
- GL_DRAW_BUFFER1_ATI = $8826;
- GL_DRAW_BUFFER2_ATI = $8827;
- GL_DRAW_BUFFER3_ATI = $8828;
- GL_DRAW_BUFFER4_ATI = $8829;
- GL_DRAW_BUFFER5_ATI = $882A;
- GL_DRAW_BUFFER6_ATI = $882B;
- GL_DRAW_BUFFER7_ATI = $882C;
- GL_DRAW_BUFFER8_ATI = $882D;
- GL_DRAW_BUFFER9_ATI = $882E;
- GL_DRAW_BUFFER10_ATI = $882F;
- GL_DRAW_BUFFER11_ATI = $8830;
- GL_DRAW_BUFFER12_ATI = $8831;
- GL_DRAW_BUFFER13_ATI = $8832;
- GL_DRAW_BUFFER14_ATI = $8833;
- GL_DRAW_BUFFER15_ATI = $8834;
-var
- glDrawBuffersATI: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_draw_buffers: Boolean;
-
-{$IFDEF WINDOWS}
-//***** WGL_ATI_pixel_format_float *****//
-const
- WGL_RGBA_FLOAT_MODE_ATI = $8820;
- WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = $8835;
- WGL_TYPE_RGBA_FLOAT_ATI = $21A0;
-
-function Load_WGL_ATI_pixel_format_float: Boolean;
-{$ENDIF}
-
-//***** GL_ATI_texture_env_combine3 *****//
-const
- GL_MODULATE_ADD_ATI = $8744;
- GL_MODULATE_SIGNED_ADD_ATI = $8745;
- GL_MODULATE_SUBTRACT_ATI = $8746;
-
-function Load_GL_ATI_texture_env_combine3: Boolean;
-
-//***** GL_ATI_texture_float *****//
-const
- GL_RGBA_FLOAT32_ATI = $8814;
- GL_RGB_FLOAT32_ATI = $8815;
- GL_ALPHA_FLOAT32_ATI = $8816;
- GL_INTENSITY_FLOAT32_ATI = $8817;
- GL_LUMINANCE_FLOAT32_ATI = $8818;
- GL_LUMINANCE_ALPHA_FLOAT32_ATI = $8819;
- GL_RGBA_FLOAT16_ATI = $881A;
- GL_RGB_FLOAT16_ATI = $881B;
- GL_ALPHA_FLOAT16_ATI = $881C;
- GL_INTENSITY_FLOAT16_ATI = $881D;
- GL_LUMINANCE_FLOAT16_ATI = $881E;
- GL_LUMINANCE_ALPHA_FLOAT16_ATI = $881F;
-
-function Load_GL_ATI_texture_float: Boolean;
-
-//***** GL_NV_texture_expand_normal *****//
-const
- GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = $888F;
-
-function Load_GL_NV_texture_expand_normal: Boolean;
-
-//***** GL_NV_half_float *****//
-const
- GL_HALF_FLOAT_NV = $140B;
-var
- glVertex2hNV: procedure(x: GLushort; y: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex2hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3hNV: procedure(x: GLushort; y: GLushort; z: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4hNV: procedure(x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertex4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3hNV: procedure(nx: GLushort; ny: GLushort; nz: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glNormal3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4hNV: procedure(red: GLushort; green: GLushort; blue: GLushort; alpha: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glColor4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1hNV: procedure(s: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord1hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2hNV: procedure(s: GLushort; t: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord2hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3hNV: procedure(s: GLushort; t: GLushort; r: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4hNV: procedure(s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glTexCoord4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1hNV: procedure(target: GLenum; s: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord1hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2hNV: procedure(target: GLenum; s: GLushort; t: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord2hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord3hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiTexCoord4hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordhNV: procedure(fog: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordhvNV: procedure(const fog: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexWeighthNV: procedure(weight: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexWeighthvNV: procedure(const weight: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1hNV: procedure(index: GLuint; x: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2hNV: procedure(index: GLuint; x: GLushort; y: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs1hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs2hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs3hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribs4hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_NV_half_float: Boolean;
-
-//***** GL_ATI_map_object_buffer *****//
-var
- glMapObjectBufferATI: function(buffer: GLuint): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUnmapObjectBufferATI: procedure(buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_map_object_buffer: Boolean;
-
-//***** GL_ATI_separate_stencil *****//
-const
- GL_KEEP = $1E00;
- GL_ZERO = $0000;
- GL_REPLACE = $1E01;
- GL_INCR = $1E02;
- GL_DECR = $1E03;
- GL_INVERT = $150A;
- GL_NEVER = $0200;
- GL_LESS = $0201;
- GL_LEQUAL = $0203;
- GL_GREATER = $0204;
- GL_GEQUAL = $0206;
- GL_EQUAL = $0202;
- GL_NOTEQUAL = $0205;
- GL_ALWAYS = $0207;
- GL_FRONT = $0404;
- GL_BACK = $0405;
- GL_FRONT_AND_BACK = $0408;
- GL_STENCIL_BACK_FUNC_ATI = $8800;
- GL_STENCIL_BACK_FAIL_ATI = $8801;
- GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = $8802;
- GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = $8803;
-var
- glStencilOpSeparateATI: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilFuncSeparateATI: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_separate_stencil: Boolean;
-
-//***** GL_ATI_vertex_attrib_array_object *****//
-var
- glVertexAttribArrayObjectATI: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribArrayObjectfvATI: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribArrayObjectivATI: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ATI_vertex_attrib_array_object: Boolean;
-
-//***** GL_ARB_vertex_buffer_object *****//
-const
- GL_ARRAY_BUFFER_ARB = $8892;
- GL_ELEMENT_ARRAY_BUFFER_ARB = $8893;
- GL_ARRAY_BUFFER_BINDING_ARB = $8894;
- GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = $8895;
- GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = $8896;
- GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = $8897;
- GL_COLOR_ARRAY_BUFFER_BINDING_ARB = $8898;
- GL_INDEX_ARRAY_BUFFER_BINDING_ARB = $8899;
- GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = $889A;
- GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = $889B;
- GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = $889C;
- GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = $889D;
- GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = $889E;
- GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = $889F;
- GL_STREAM_DRAW_ARB = $88E0;
- GL_STREAM_READ_ARB = $88E1;
- GL_STREAM_COPY_ARB = $88E2;
- GL_STATIC_DRAW_ARB = $88E4;
- GL_STATIC_READ_ARB = $88E5;
- GL_STATIC_COPY_ARB = $88E6;
- GL_DYNAMIC_DRAW_ARB = $88E8;
- GL_DYNAMIC_READ_ARB = $88E9;
- GL_DYNAMIC_COPY_ARB = $88EA;
- GL_READ_ONLY_ARB = $88B8;
- GL_WRITE_ONLY_ARB = $88B9;
- GL_READ_WRITE_ARB = $88BA;
- GL_BUFFER_SIZE_ARB = $8764;
- GL_BUFFER_USAGE_ARB = $8765;
- GL_BUFFER_ACCESS_ARB = $88BB;
- GL_BUFFER_MAPPED_ARB = $88BC;
- GL_BUFFER_MAP_POINTER_ARB = $88BD;
-var
- glBindBufferARB: procedure(target: GLenum; buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteBuffersARB: procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenBuffersARB: procedure(n: GLsizei; buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsBufferARB: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBufferDataARB: procedure(target: GLenum; size: GLsizeiptrARB; const data: PGLvoid; usage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBufferSubDataARB: procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferSubDataARB: procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapBufferARB: function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUnmapBufferARB: function(target: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferParameterivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferPointervARB: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_vertex_buffer_object: Boolean;
-
-//***** GL_ARB_occlusion_query *****//
-const
- GL_SAMPLES_PASSED_ARB = $8914;
- GL_QUERY_COUNTER_BITS_ARB = $8864;
- GL_CURRENT_QUERY_ARB = $8865;
- GL_QUERY_RESULT_ARB = $8866;
- GL_QUERY_RESULT_AVAILABLE_ARB = $8867;
-var
- glGenQueriesARB: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteQueriesARB: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsQueryARB: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBeginQueryARB: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndQueryARB: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryObjectivARB: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryObjectuivARB: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_occlusion_query: Boolean;
-
-//***** GL_ARB_shader_objects *****//
-const
- GL_PROGRAM_OBJECT_ARB = $8B40;
- GL_OBJECT_TYPE_ARB = $8B4E;
- GL_OBJECT_SUBTYPE_ARB = $8B4F;
- GL_OBJECT_DELETE_STATUS_ARB = $8B80;
- GL_OBJECT_COMPILE_STATUS_ARB = $8B81;
- GL_OBJECT_LINK_STATUS_ARB = $8B82;
- GL_OBJECT_VALIDATE_STATUS_ARB = $8B83;
- GL_OBJECT_INFO_LOG_LENGTH_ARB = $8B84;
- GL_OBJECT_ATTACHED_OBJECTS_ARB = $8B85;
- GL_OBJECT_ACTIVE_UNIFORMS_ARB = $8B86;
- GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = $8B87;
- GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = $8B88;
- GL_SHADER_OBJECT_ARB = $8B48;
- GL_FLOAT = $1406;
- GL_FLOAT_VEC2_ARB = $8B50;
- GL_FLOAT_VEC3_ARB = $8B51;
- GL_FLOAT_VEC4_ARB = $8B52;
- GL_INT = $1404;
- GL_INT_VEC2_ARB = $8B53;
- GL_INT_VEC3_ARB = $8B54;
- GL_INT_VEC4_ARB = $8B55;
- GL_BOOL_ARB = $8B56;
- GL_BOOL_VEC2_ARB = $8B57;
- GL_BOOL_VEC3_ARB = $8B58;
- GL_BOOL_VEC4_ARB = $8B59;
- GL_FLOAT_MAT2_ARB = $8B5A;
- GL_FLOAT_MAT3_ARB = $8B5B;
- GL_FLOAT_MAT4_ARB = $8B5C;
-var
- glDeleteObjectARB: procedure(obj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetHandleARB: function(pname: GLenum): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDetachObjectARB: procedure(containerObj: GLhandleARB; attachedObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCreateShaderObjectARB: function(shaderType: GLenum): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShaderSourceARB: procedure(shaderObj: GLhandleARB; count: GLsizei; const _string: PGLvoid; const length: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompileShaderARB: procedure(shaderObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCreateProgramObjectARB: function(): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAttachObjectARB: procedure(containerObj: GLhandleARB; obj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLinkProgramARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUseProgramObjectARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glValidateProgramARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1fARB: procedure(location: GLint; v0: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1iARB: procedure(location: GLint; v0: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2iARB: procedure(location: GLint; v0: GLint; v1: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix2fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix3fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix4fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetObjectParameterfvARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetObjectParameterivARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetInfoLogARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; infoLog: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetAttachedObjectsARB: procedure(containerObj: GLhandleARB; maxCount: GLsizei; count: PGLsizei; obj: PGLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetActiveUniformARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformfvARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformivARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetShaderSourceARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; source: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_shader_objects: Boolean;
-
-//***** GL_ARB_vertex_shader *****//
-const
- GL_VERTEX_SHADER_ARB = $8B31;
- GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = $8B4A;
- GL_MAX_VARYING_FLOATS_ARB = $8B4B;
- // GL_MAX_VERTEX_ATTRIBS_ARB { already defined }
- // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined }
- GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C;
- GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = $8B4D;
- // GL_MAX_TEXTURE_COORDS_ARB { already defined }
- // GL_VERTEX_PROGRAM_POINT_SIZE_ARB { already defined }
- // GL_VERTEX_PROGRAM_TWO_SIDE_ARB { already defined }
- // GL_OBJECT_TYPE_ARB { already defined }
- // GL_OBJECT_SUBTYPE_ARB { already defined }
- GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = $8B89;
- GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = $8B8A;
- // GL_SHADER_OBJECT_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB { already defined }
- // GL_CURRENT_VERTEX_ATTRIB_ARB { already defined }
- // GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB { already defined }
- // GL_FLOAT { already defined }
- // GL_FLOAT_VEC2_ARB { already defined }
- // GL_FLOAT_VEC3_ARB { already defined }
- // GL_FLOAT_VEC4_ARB { already defined }
- // GL_FLOAT_MAT2_ARB { already defined }
- // GL_FLOAT_MAT3_ARB { already defined }
- // GL_FLOAT_MAT4_ARB { already defined }
- // glVertexAttrib1fARB { already defined }
- // glVertexAttrib1sARB { already defined }
- // glVertexAttrib1dARB { already defined }
- // glVertexAttrib2fARB { already defined }
- // glVertexAttrib2sARB { already defined }
- // glVertexAttrib2dARB { already defined }
- // glVertexAttrib3fARB { already defined }
- // glVertexAttrib3sARB { already defined }
- // glVertexAttrib3dARB { already defined }
- // glVertexAttrib4fARB { already defined }
- // glVertexAttrib4sARB { already defined }
- // glVertexAttrib4dARB { already defined }
- // glVertexAttrib4NubARB { already defined }
- // glVertexAttrib1fvARB { already defined }
- // glVertexAttrib1svARB { already defined }
- // glVertexAttrib1dvARB { already defined }
- // glVertexAttrib2fvARB { already defined }
- // glVertexAttrib2svARB { already defined }
- // glVertexAttrib2dvARB { already defined }
- // glVertexAttrib3fvARB { already defined }
- // glVertexAttrib3svARB { already defined }
- // glVertexAttrib3dvARB { already defined }
- // glVertexAttrib4fvARB { already defined }
- // glVertexAttrib4svARB { already defined }
- // glVertexAttrib4dvARB { already defined }
- // glVertexAttrib4ivARB { already defined }
- // glVertexAttrib4bvARB { already defined }
- // glVertexAttrib4ubvARB { already defined }
- // glVertexAttrib4usvARB { already defined }
- // glVertexAttrib4uivARB { already defined }
- // glVertexAttrib4NbvARB { already defined }
- // glVertexAttrib4NsvARB { already defined }
- // glVertexAttrib4NivARB { already defined }
- // glVertexAttrib4NubvARB { already defined }
- // glVertexAttrib4NusvARB { already defined }
- // glVertexAttrib4NuivARB { already defined }
- // glVertexAttribPointerARB { already defined }
- // glEnableVertexAttribArrayARB { already defined }
- // glDisableVertexAttribArrayARB { already defined }
-var
- glBindAttribLocationARB: procedure(programObj: GLhandleARB; index: GLuint; const name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetActiveAttribARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetAttribLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- // glGetVertexAttribdvARB { already defined }
- // glGetVertexAttribfvARB { already defined }
- // glGetVertexAttribivARB { already defined }
- // glGetVertexAttribPointervARB { already defined }
-
-function Load_GL_ARB_vertex_shader: Boolean;
-
-//***** GL_ARB_fragment_shader *****//
-const
- GL_FRAGMENT_SHADER_ARB = $8B30;
- GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = $8B49;
- // GL_MAX_TEXTURE_COORDS_ARB { already defined }
- // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined }
- // GL_OBJECT_TYPE_ARB { already defined }
- // GL_OBJECT_SUBTYPE_ARB { already defined }
- // GL_SHADER_OBJECT_ARB { already defined }
-
-function Load_GL_ARB_fragment_shader: Boolean;
-
-//***** GL_ARB_shading_language_100 *****//
-
-function Load_GL_ARB_shading_language_100: Boolean;
-
-//***** GL_ARB_texture_non_power_of_two *****//
-
-function Load_GL_ARB_texture_non_power_of_two: Boolean;
-
-//***** GL_ARB_point_sprite *****//
-const
- GL_POINT_SPRITE_ARB = $8861;
- GL_COORD_REPLACE_ARB = $8862;
-
-function Load_GL_ARB_point_sprite: Boolean;
-
-//***** GL_EXT_depth_bounds_test *****//
-const
- GL_DEPTH_BOUNDS_TEST_EXT = $8890;
- GL_DEPTH_BOUNDS_EXT = $8891;
-var
- glDepthBoundsEXT: procedure(zmin: GLclampd; zmax: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_depth_bounds_test: Boolean;
-
-//***** GL_EXT_secondary_color *****//
-const
- GL_COLOR_SUM_EXT = $8458;
- GL_CURRENT_SECONDARY_COLOR_EXT = $8459;
- GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A;
- GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B;
- GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C;
- GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D;
- GL_SECONDARY_COLOR_ARRAY_EXT = $845E;
-var
- glSecondaryColor3bEXT: procedure(r: GLbyte; g: GLbyte; b: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3sEXT: procedure(r: GLshort; g: GLshort; b: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3iEXT: procedure(r: GLint; g: GLint; b: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3fEXT: procedure(r: GLfloat; g: GLfloat; b: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3dEXT: procedure(r: GLdouble; g: GLdouble; b: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ubEXT: procedure(r: GLubyte; g: GLubyte; b: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3usEXT: procedure(r: GLushort; g: GLushort; b: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3uiEXT: procedure(r: GLuint; g: GLuint; b: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3bvEXT: procedure(components: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3svEXT: procedure(components: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ivEXT: procedure(components: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3fvEXT: procedure(components: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3dvEXT: procedure(components: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ubvEXT: procedure(components: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3usvEXT: procedure(components: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3uivEXT: procedure(components: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_secondary_color: Boolean;
-
-//***** GL_EXT_texture_mirror_clamp *****//
-const
- GL_MIRROR_CLAMP_EXT = $8742;
- GL_MIRROR_CLAMP_TO_EDGE_EXT = $8743;
- GL_MIRROR_CLAMP_TO_BORDER_EXT = $8912;
-
-function Load_GL_EXT_texture_mirror_clamp: Boolean;
-
-//***** GL_EXT_blend_equation_separate *****//
-const
- GL_BLEND_EQUATION_RGB_EXT = $8009;
- GL_BLEND_EQUATION_ALPHA_EXT = $883D;
-var
- glBlendEquationSeparateEXT: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_blend_equation_separate: Boolean;
-
-//***** GL_MESA_pack_invert *****//
-const
- GL_PACK_INVERT_MESA = $8758;
-
-function Load_GL_MESA_pack_invert: Boolean;
-
-//***** GL_MESA_ycbcr_texture *****//
-const
- GL_YCBCR_MESA = $8757;
- GL_UNSIGNED_SHORT_8_8_MESA = $85BA;
- GL_UNSIGNED_SHORT_8_8_REV_MESA = $85BB;
-
-function Load_GL_MESA_ycbcr_texture: Boolean;
-
-//***** GL_ARB_fragment_program_shadow *****//
-
-function Load_GL_ARB_fragment_program_shadow: Boolean;
-
-//***** GL_EXT_fog_coord *****//
-const
- GL_FOG_COORDINATE_SOURCE_EXT = $8450;
- GL_FOG_COORDINATE_EXT = $8451;
- GL_FRAGMENT_DEPTH_EXT = $8452;
- GL_CURRENT_FOG_COORDINATE_EXT = $8453;
- GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454;
- GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455;
- GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456;
- GL_FOG_COORDINATE_ARRAY_EXT = $8457;
-var
- glFogCoordfEXT: procedure(coord: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoorddEXT: procedure(coord: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordfvEXT: procedure(coord: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoorddvEXT: procedure(coord: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordPointerEXT: procedure(_type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_fog_coord: Boolean;
-
-//***** GL_NV_fragment_program_option *****//
-
-function Load_GL_NV_fragment_program_option: Boolean;
-
-//***** GL_EXT_pixel_buffer_object *****//
-const
- GL_PIXEL_PACK_BUFFER_EXT = $88EB;
- GL_PIXEL_UNPACK_BUFFER_EXT = $88EC;
- GL_PIXEL_PACK_BUFFER_BINDING_EXT = $88ED;
- GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = $88EF;
-
-function Load_GL_EXT_pixel_buffer_object: Boolean;
-
-//***** GL_NV_fragment_program2 *****//
-const
- GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = $88F4;
- GL_MAX_PROGRAM_CALL_DEPTH_NV = $88F5;
- GL_MAX_PROGRAM_IF_DEPTH_NV = $88F6;
- GL_MAX_PROGRAM_LOOP_DEPTH_NV = $88F7;
- GL_MAX_PROGRAM_LOOP_COUNT_NV = $88F8;
-
-function Load_GL_NV_fragment_program2: Boolean;
-
-//***** GL_NV_vertex_program2_option *****//
- // GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV { already defined }
- // GL_MAX_PROGRAM_CALL_DEPTH_NV { already defined }
-
-function Load_GL_NV_vertex_program2_option: Boolean;
-
-//***** GL_NV_vertex_program3 *****//
- // GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB { already defined }
-
-function Load_GL_NV_vertex_program3: Boolean;
-
-//***** GL_ARB_draw_buffers *****//
-const
- GL_MAX_DRAW_BUFFERS_ARB = $8824;
- GL_DRAW_BUFFER0_ARB = $8825;
- GL_DRAW_BUFFER1_ARB = $8826;
- GL_DRAW_BUFFER2_ARB = $8827;
- GL_DRAW_BUFFER3_ARB = $8828;
- GL_DRAW_BUFFER4_ARB = $8829;
- GL_DRAW_BUFFER5_ARB = $882A;
- GL_DRAW_BUFFER6_ARB = $882B;
- GL_DRAW_BUFFER7_ARB = $882C;
- GL_DRAW_BUFFER8_ARB = $882D;
- GL_DRAW_BUFFER9_ARB = $882E;
- GL_DRAW_BUFFER10_ARB = $882F;
- GL_DRAW_BUFFER11_ARB = $8830;
- GL_DRAW_BUFFER12_ARB = $8831;
- GL_DRAW_BUFFER13_ARB = $8832;
- GL_DRAW_BUFFER14_ARB = $8833;
- GL_DRAW_BUFFER15_ARB = $8834;
-var
- glDrawBuffersARB: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_draw_buffers: Boolean;
-
-//***** GL_ARB_texture_rectangle *****//
-const
- GL_TEXTURE_RECTANGLE_ARB = $84F5;
- GL_TEXTURE_BINDING_RECTANGLE_ARB = $84F6;
- GL_PROXY_TEXTURE_RECTANGLE_ARB = $84F7;
- GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = $84F8;
-
-function Load_GL_ARB_texture_rectangle: Boolean;
-
-//***** GL_ARB_color_buffer_float *****//
-const
- GL_RGBA_FLOAT_MODE_ARB = $8820;
- GL_CLAMP_VERTEX_COLOR_ARB = $891A;
- GL_CLAMP_FRAGMENT_COLOR_ARB = $891B;
- GL_CLAMP_READ_COLOR_ARB = $891C;
- GL_FIXED_ONLY_ARB = $891D;
- WGL_TYPE_RGBA_FLOAT_ARB = $21A0;
-var
- glClampColorARB: procedure(target: GLenum; clamp: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_ARB_color_buffer_float: Boolean;
-
-//***** GL_ARB_half_float_pixel *****//
-const
- GL_HALF_FLOAT_ARB = $140B;
-
-function Load_GL_ARB_half_float_pixel: Boolean;
-
-//***** GL_ARB_texture_float *****//
-const
- GL_TEXTURE_RED_TYPE_ARB = $8C10;
- GL_TEXTURE_GREEN_TYPE_ARB = $8C11;
- GL_TEXTURE_BLUE_TYPE_ARB = $8C12;
- GL_TEXTURE_ALPHA_TYPE_ARB = $8C13;
- GL_TEXTURE_LUMINANCE_TYPE_ARB = $8C14;
- GL_TEXTURE_INTENSITY_TYPE_ARB = $8C15;
- GL_TEXTURE_DEPTH_TYPE_ARB = $8C16;
- GL_UNSIGNED_NORMALIZED_ARB = $8C17;
- GL_RGBA32F_ARB = $8814;
- GL_RGB32F_ARB = $8815;
- GL_ALPHA32F_ARB = $8816;
- GL_INTENSITY32F_ARB = $8817;
- GL_LUMINANCE32F_ARB = $8818;
- GL_LUMINANCE_ALPHA32F_ARB = $8819;
- GL_RGBA16F_ARB = $881A;
- GL_RGB16F_ARB = $881B;
- GL_ALPHA16F_ARB = $881C;
- GL_INTENSITY16F_ARB = $881D;
- GL_LUMINANCE16F_ARB = $881E;
- GL_LUMINANCE_ALPHA16F_ARB = $881F;
-
-function Load_GL_ARB_texture_float: Boolean;
-
-//***** GL_EXT_texture_compression_dxt1 *****//
- // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined }
- // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined }
-
-function Load_GL_EXT_texture_compression_dxt1: Boolean;
-
-//***** GL_ARB_pixel_buffer_object *****//
-const
- GL_PIXEL_PACK_BUFFER_ARB = $88EB;
- GL_PIXEL_UNPACK_BUFFER_ARB = $88EC;
- GL_PIXEL_PACK_BUFFER_BINDING_ARB = $88ED;
- GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = $88EF;
-
-function Load_GL_ARB_pixel_buffer_object: Boolean;
-
-//***** GL_EXT_framebuffer_object *****//
-const
- GL_FRAMEBUFFER_EXT = $8D40;
- GL_RENDERBUFFER_EXT = $8D41;
- GL_STENCIL_INDEX_EXT = $8D45;
- GL_STENCIL_INDEX1_EXT = $8D46;
- GL_STENCIL_INDEX4_EXT = $8D47;
- GL_STENCIL_INDEX8_EXT = $8D48;
- GL_STENCIL_INDEX16_EXT = $8D49;
- GL_RENDERBUFFER_WIDTH_EXT = $8D42;
- GL_RENDERBUFFER_HEIGHT_EXT = $8D43;
- GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = $8D44;
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = $8CD0;
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = $8CD1;
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = $8CD2;
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = $8CD3;
- GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = $8CD4;
- GL_COLOR_ATTACHMENT0_EXT = $8CE0;
- GL_COLOR_ATTACHMENT1_EXT = $8CE1;
- GL_COLOR_ATTACHMENT2_EXT = $8CE2;
- GL_COLOR_ATTACHMENT3_EXT = $8CE3;
- GL_COLOR_ATTACHMENT4_EXT = $8CE4;
- GL_COLOR_ATTACHMENT5_EXT = $8CE5;
- GL_COLOR_ATTACHMENT6_EXT = $8CE6;
- GL_COLOR_ATTACHMENT7_EXT = $8CE7;
- GL_COLOR_ATTACHMENT8_EXT = $8CE8;
- GL_COLOR_ATTACHMENT9_EXT = $8CE9;
- GL_COLOR_ATTACHMENT10_EXT = $8CEA;
- GL_COLOR_ATTACHMENT11_EXT = $8CEB;
- GL_COLOR_ATTACHMENT12_EXT = $8CEC;
- GL_COLOR_ATTACHMENT13_EXT = $8CED;
- GL_COLOR_ATTACHMENT14_EXT = $8CEE;
- GL_COLOR_ATTACHMENT15_EXT = $8CEF;
- GL_DEPTH_ATTACHMENT_EXT = $8D00;
- GL_STENCIL_ATTACHMENT_EXT = $8D20;
- GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5;
- GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = $8CD6;
- GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = $8CD7;
- GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT = $8CD8;
- GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = $8CD9;
- GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = $8CDA;
- GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = $8CDB;
- GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = $8CDC;
- GL_FRAMEBUFFER_UNSUPPORTED_EXT = $8CDD;
- GL_FRAMEBUFFER_STATUS_ERROR_EXT = $8CDE;
- GL_FRAMEBUFFER_BINDING_EXT = $8CA6;
- GL_RENDERBUFFER_BINDING_EXT = $8CA7;
- GL_MAX_COLOR_ATTACHMENTS_EXT = $8CDF;
- GL_MAX_RENDERBUFFER_SIZE_EXT = $84E8;
- GL_INVALID_FRAMEBUFFER_OPERATION_EXT = $0506;
-var
- glIsRenderbufferEXT: function(renderbuffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindRenderbufferEXT: procedure(target: GLenum; renderbuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteRenderbuffersEXT: procedure(n: GLsizei; const renderbuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenRenderbuffersEXT: procedure(n: GLsizei; renderbuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glRenderbufferStorageEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetRenderbufferParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsFramebufferEXT: function(framebuffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindFramebufferEXT: procedure(target: GLenum; framebuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteFramebuffersEXT: procedure(n: GLsizei; const framebuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenFramebuffersEXT: procedure(n: GLsizei; framebuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCheckFramebufferStatusEXT: function(target: GLenum): GLenum; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFramebufferTexture1DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFramebufferTexture2DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFramebufferTexture3DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFramebufferRenderbufferEXT: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetFramebufferAttachmentParameterivEXT: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenerateMipmapEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_EXT_framebuffer_object: Boolean;
-
-//***** GL_version_1_4 *****//
-const
- GL_BLEND_DST_RGB = $80C8;
- GL_BLEND_SRC_RGB = $80C9;
- GL_BLEND_DST_ALPHA = $80CA;
- GL_BLEND_SRC_ALPHA = $80CB;
- GL_POINT_SIZE_MIN = $8126;
- GL_POINT_SIZE_MAX = $8127;
- GL_POINT_FADE_THRESHOLD_SIZE = $8128;
- GL_POINT_DISTANCE_ATTENUATION = $8129;
- GL_GENERATE_MIPMAP = $8191;
- GL_GENERATE_MIPMAP_HINT = $8192;
- GL_DEPTH_COMPONENT16 = $81A5;
- GL_DEPTH_COMPONENT24 = $81A6;
- GL_DEPTH_COMPONENT32 = $81A7;
- GL_MIRRORED_REPEAT = $8370;
- GL_FOG_COORDINATE_SOURCE = $8450;
- GL_FOG_COORDINATE = $8451;
- GL_FRAGMENT_DEPTH = $8452;
- GL_CURRENT_FOG_COORDINATE = $8453;
- GL_FOG_COORDINATE_ARRAY_TYPE = $8454;
- GL_FOG_COORDINATE_ARRAY_STRIDE = $8455;
- GL_FOG_COORDINATE_ARRAY_POINTER = $8456;
- GL_FOG_COORDINATE_ARRAY = $8457;
- GL_COLOR_SUM = $8458;
- GL_CURRENT_SECONDARY_COLOR = $8459;
- GL_SECONDARY_COLOR_ARRAY_SIZE = $845A;
- GL_SECONDARY_COLOR_ARRAY_TYPE = $845B;
- GL_SECONDARY_COLOR_ARRAY_STRIDE = $845C;
- GL_SECONDARY_COLOR_ARRAY_POINTER = $845D;
- GL_SECONDARY_COLOR_ARRAY = $845E;
- GL_MAX_TEXTURE_LOD_BIAS = $84FD;
- GL_TEXTURE_FILTER_CONTROL = $8500;
- GL_TEXTURE_LOD_BIAS = $8501;
- GL_INCR_WRAP = $8507;
- GL_DECR_WRAP = $8508;
- GL_TEXTURE_DEPTH_SIZE = $884A;
- GL_DEPTH_TEXTURE_MODE = $884B;
- GL_TEXTURE_COMPARE_MODE = $884C;
- GL_TEXTURE_COMPARE_FUNC = $884D;
- GL_COMPARE_R_TO_TEXTURE = $884E;
-var
- glBlendFuncSeparate: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordf: procedure(coord: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordfv: procedure(const coord: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordd: procedure(coord: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoorddv: procedure(const coord: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glFogCoordPointer: procedure(_type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawArrays: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMultiDrawElements: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameterf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameterfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameteri: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glPointParameteriv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3b: procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3d: procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3f: procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3i: procedure(red: GLint; green: GLint; blue: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3s: procedure(red: GLshort; green: GLshort; blue: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ub: procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3ui: procedure(red: GLuint; green: GLuint; blue: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3us: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColor3usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glSecondaryColorPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2d: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2f: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2i: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2s: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3d: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3f: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3i: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3s: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glWindowPos3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_version_1_4: Boolean;
-
-//***** GL_version_1_5 *****//
-const
- GL_BUFFER_SIZE = $8764;
- GL_BUFFER_USAGE = $8765;
- GL_QUERY_COUNTER_BITS = $8864;
- GL_CURRENT_QUERY = $8865;
- GL_QUERY_RESULT = $8866;
- GL_QUERY_RESULT_AVAILABLE = $8867;
- GL_ARRAY_BUFFER = $8892;
- GL_ELEMENT_ARRAY_BUFFER = $8893;
- GL_ARRAY_BUFFER_BINDING = $8894;
- GL_ELEMENT_ARRAY_BUFFER_BINDING = $8895;
- GL_VERTEX_ARRAY_BUFFER_BINDING = $8896;
- GL_NORMAL_ARRAY_BUFFER_BINDING = $8897;
- GL_COLOR_ARRAY_BUFFER_BINDING = $8898;
- GL_INDEX_ARRAY_BUFFER_BINDING = $8899;
- GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = $889A;
- GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = $889B;
- GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = $889C;
- GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = $889D;
- GL_WEIGHT_ARRAY_BUFFER_BINDING = $889E;
- GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = $889F;
- GL_READ_ONLY = $88B8;
- GL_WRITE_ONLY = $88B9;
- GL_READ_WRITE = $88BA;
- GL_BUFFER_ACCESS = $88BB;
- GL_BUFFER_MAPPED = $88BC;
- GL_BUFFER_MAP_POINTER = $88BD;
- GL_STREAM_DRAW = $88E0;
- GL_STREAM_READ = $88E1;
- GL_STREAM_COPY = $88E2;
- GL_STATIC_DRAW = $88E4;
- GL_STATIC_READ = $88E5;
- GL_STATIC_COPY = $88E6;
- GL_DYNAMIC_DRAW = $88E8;
- GL_DYNAMIC_READ = $88E9;
- GL_DYNAMIC_COPY = $88EA;
- GL_SAMPLES_PASSED = $8914;
- GL_FOG_COORD_SRC = $8450;
- GL_FOG_COORD = $8451;
- GL_CURRENT_FOG_COORD = $8453;
- GL_FOG_COORD_ARRAY_TYPE = $8454;
- GL_FOG_COORD_ARRAY_STRIDE = $8455;
- GL_FOG_COORD_ARRAY_POINTER = $8456;
- GL_FOG_COORD_ARRAY = $8457;
- GL_FOG_COORD_ARRAY_BUFFER_BINDING = $889D;
- GL_SRC0_RGB = $8580;
- GL_SRC1_RGB = $8581;
- GL_SRC2_RGB = $8582;
- GL_SRC0_ALPHA = $8588;
- GL_SRC1_ALPHA = $8589;
- GL_SRC2_ALPHA = $858A;
-var
- glGenQueries: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteQueries: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsQuery: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBeginQuery: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEndQuery: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryObjectiv: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetQueryObjectuiv: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindBuffer: procedure(target: GLenum; buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteBuffers: procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGenBuffers: procedure(n: GLsizei; buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsBuffer: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBufferData: procedure(target: GLenum; size: GLsizeiptr; const data: PGLvoid; usage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glMapBuffer: function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUnmapBuffer: function(target: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetBufferPointerv: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_version_1_5: Boolean;
-
-//***** GL_version_2_0 *****//
-const
- GL_BLEND_EQUATION_RGB = $8009;
- GL_VERTEX_ATTRIB_ARRAY_ENABLED = $8622;
- GL_VERTEX_ATTRIB_ARRAY_SIZE = $8623;
- GL_VERTEX_ATTRIB_ARRAY_STRIDE = $8624;
- GL_VERTEX_ATTRIB_ARRAY_TYPE = $8625;
- GL_CURRENT_VERTEX_ATTRIB = $8626;
- GL_VERTEX_PROGRAM_POINT_SIZE = $8642;
- GL_VERTEX_PROGRAM_TWO_SIDE = $8643;
- GL_VERTEX_ATTRIB_ARRAY_POINTER = $8645;
- GL_STENCIL_BACK_FUNC = $8800;
- GL_STENCIL_BACK_FAIL = $8801;
- GL_STENCIL_BACK_PASS_DEPTH_FAIL = $8802;
- GL_STENCIL_BACK_PASS_DEPTH_PASS = $8803;
- GL_MAX_DRAW_BUFFERS = $8824;
- GL_DRAW_BUFFER0 = $8825;
- GL_DRAW_BUFFER1 = $8826;
- GL_DRAW_BUFFER2 = $8827;
- GL_DRAW_BUFFER3 = $8828;
- GL_DRAW_BUFFER4 = $8829;
- GL_DRAW_BUFFER5 = $882A;
- GL_DRAW_BUFFER6 = $882B;
- GL_DRAW_BUFFER7 = $882C;
- GL_DRAW_BUFFER8 = $882D;
- GL_DRAW_BUFFER9 = $882E;
- GL_DRAW_BUFFER10 = $882F;
- GL_DRAW_BUFFER11 = $8830;
- GL_DRAW_BUFFER12 = $8831;
- GL_DRAW_BUFFER13 = $8832;
- GL_DRAW_BUFFER14 = $8833;
- GL_DRAW_BUFFER15 = $8834;
- GL_BLEND_EQUATION_ALPHA = $883D;
- GL_POINT_SPRITE = $8861;
- GL_COORD_REPLACE = $8862;
- GL_MAX_VERTEX_ATTRIBS = $8869;
- GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = $886A;
- GL_MAX_TEXTURE_COORDS = $8871;
- GL_MAX_TEXTURE_IMAGE_UNITS = $8872;
- GL_FRAGMENT_SHADER = $8B30;
- GL_VERTEX_SHADER = $8B31;
- GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = $8B49;
- GL_MAX_VERTEX_UNIFORM_COMPONENTS = $8B4A;
- GL_MAX_VARYING_FLOATS = $8B4B;
- GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = $8B4C;
- GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = $8B4D;
- GL_SHADER_TYPE = $8B4F;
- GL_FLOAT_VEC2 = $8B50;
- GL_FLOAT_VEC3 = $8B51;
- GL_FLOAT_VEC4 = $8B52;
- GL_INT_VEC2 = $8B53;
- GL_INT_VEC3 = $8B54;
- GL_INT_VEC4 = $8B55;
- GL_BOOL = $8B56;
- GL_BOOL_VEC2 = $8B57;
- GL_BOOL_VEC3 = $8B58;
- GL_BOOL_VEC4 = $8B59;
- GL_FLOAT_MAT2 = $8B5A;
- GL_FLOAT_MAT3 = $8B5B;
- GL_FLOAT_MAT4 = $8B5C;
- GL_SAMPLER_1D = $8B5D;
- GL_SAMPLER_2D = $8B5E;
- GL_SAMPLER_3D = $8B5F;
- GL_SAMPLER_CUBE = $8B60;
- GL_SAMPLER_1D_SHADOW = $8B61;
- GL_SAMPLER_2D_SHADOW = $8B62;
- GL_DELETE_STATUS = $8B80;
- GL_COMPILE_STATUS = $8B81;
- GL_LINK_STATUS = $8B82;
- GL_VALIDATE_STATUS = $8B83;
- GL_INFO_LOG_LENGTH = $8B84;
- GL_ATTACHED_SHADERS = $8B85;
- GL_ACTIVE_UNIFORMS = $8B86;
- GL_ACTIVE_UNIFORM_MAX_LENGTH = $8B87;
- GL_SHADER_SOURCE_LENGTH = $8B88;
- GL_ACTIVE_ATTRIBUTES = $8B89;
- GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = $8B8A;
- GL_FRAGMENT_SHADER_DERIVATIVE_HINT = $8B8B;
- GL_SHADING_LANGUAGE_VERSION = $8B8C;
- GL_CURRENT_PROGRAM = $8B8D;
- GL_POINT_SPRITE_COORD_ORIGIN = $8CA0;
- GL_LOWER_LEFT = $8CA1;
- GL_UPPER_LEFT = $8CA2;
- GL_STENCIL_BACK_REF = $8CA3;
- GL_STENCIL_BACK_VALUE_MASK = $8CA4;
- GL_STENCIL_BACK_WRITEMASK = $8CA5;
-var
- glBlendEquationSeparate: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDrawBuffers: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilOpSeparate: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilFuncSeparate: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glStencilMaskSeparate: procedure(face: GLenum; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glAttachShader: procedure(_program: GLuint; shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glBindAttribLocation: procedure(_program: GLuint; index: GLuint; const name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCompileShader: procedure(shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCreateProgram: function(): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glCreateShader: function(_type: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDeleteShader: procedure(shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDetachShader: procedure(_program: GLuint; shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glDisableVertexAttribArray: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glEnableVertexAttribArray: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetActiveAttrib: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetActiveUniform: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetAttachedShaders: procedure(_program: GLuint; maxCount: GLsizei; count: PGLsizei; obj: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetAttribLocation: function(_program: GLuint; const name: PGLchar): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramiv: procedure(_program: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetProgramInfoLog: procedure(_program: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetShaderiv: procedure(shader: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetShaderInfoLog: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetShaderSource: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; source: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformLocation: function(_program: GLuint; const name: PGLchar): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformfv: procedure(_program: GLuint; location: GLint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetUniformiv: procedure(_program: GLuint; location: GLint; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribdv: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribfv: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glGetVertexAttribPointerv: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsProgram: function(_program: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glIsShader: function(shader: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glLinkProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glShaderSource: procedure(shader: GLuint; count: GLsizei; const _string: PGLchar; const length: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUseProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1f: procedure(location: GLint; v0: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2f: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1i: procedure(location: GLint; v0: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2i: procedure(location: GLint; v0: GLint; v1: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform1iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform2iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform3iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniform4iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glUniformMatrix4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glValidateProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1d: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1f: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1s: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib1sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2d: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2f: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2s: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib2sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib3sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nbv: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Niv: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nsv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nub: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nubv: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nuiv: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4Nusv: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4bv: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4iv: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4ubv: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4uiv: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttrib4usv: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glVertexAttribPointer: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-function Load_GL_version_2_0: Boolean;
-
-implementation
-
-uses
- sdl;
-
-function glext_ExtensionSupported(const extension: PChar; const searchIn: PChar): Boolean;
-var
- extensions: PChar;
- start: PChar;
- where, terminator: PChar;
-begin
-
- if (Pos(' ', extension) <> 0) or (extension = '') then
- begin
- Result := FALSE;
- Exit;
- end;
-
- if searchIn = '' then
- extensions := glGetString(GL_EXTENSIONS)
- else
- //StrLCopy( extensions, searchIn, StrLen(searchIn)+1 );
- extensions := searchIn;
- start := extensions;
- while TRUE do
- begin
- where := StrPos(start, extension );
- if where = nil then Break;
- terminator := Pointer(Integer(where) + Integer( strlen( extension ) ) );
- if (where = start) or (PChar(Integer(where) - 1)^ = ' ') then
- begin
- if (terminator^ = ' ') or (terminator^ = #0) then
- begin
- Result := TRUE;
- Exit;
- end;
- end;
- start := terminator;
- end;
- Result := FALSE;
-
-end;
-
-function Load_GL_version_1_2: Boolean;
-{var
- extstring : PChar;}
-begin
-
- Result := FALSE;
- //extstring := glGetString( GL_EXTENSIONS );
-
- @glCopyTexSubImage3D := SDL_GL_GetProcAddress('glCopyTexSubImage3D');
- if not Assigned(glCopyTexSubImage3D) then Exit;
- @glDrawRangeElements := SDL_GL_GetProcAddress('glDrawRangeElements');
- if not Assigned(glDrawRangeElements) then Exit;
- @glTexImage3D := SDL_GL_GetProcAddress('glTexImage3D');
- if not Assigned(glTexImage3D) then Exit;
- @glTexSubImage3D := SDL_GL_GetProcAddress('glTexSubImage3D');
- if not Assigned(glTexSubImage3D) then Exit;
-
- Result := TRUE;
-
-end;
-
-function Load_GL_ARB_imaging: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_imaging', extstring) then
- begin
- @glColorTable := SDL_GL_GetProcAddress('glColorTable');
- if not Assigned(glColorTable) then Exit;
- @glColorTableParameterfv := SDL_GL_GetProcAddress('glColorTableParameterfv');
- if not Assigned(glColorTableParameterfv) then Exit;
- @glColorTableParameteriv := SDL_GL_GetProcAddress('glColorTableParameteriv');
- if not Assigned(glColorTableParameteriv) then Exit;
- @glCopyColorTable := SDL_GL_GetProcAddress('glCopyColorTable');
- if not Assigned(glCopyColorTable) then Exit;
- @glGetColorTable := SDL_GL_GetProcAddress('glGetColorTable');
- if not Assigned(glGetColorTable) then Exit;
- @glGetColorTableParameterfv := SDL_GL_GetProcAddress('glGetColorTableParameterfv');
- if not Assigned(glGetColorTableParameterfv) then Exit;
- @glGetColorTableParameteriv := SDL_GL_GetProcAddress('glGetColorTableParameteriv');
- if not Assigned(glGetColorTableParameteriv) then Exit;
- @glColorSubTable := SDL_GL_GetProcAddress('glColorSubTable');
- if not Assigned(glColorSubTable) then Exit;
- @glCopyColorSubTable := SDL_GL_GetProcAddress('glCopyColorSubTable');
- if not Assigned(glCopyColorSubTable) then Exit;
- @glConvolutionFilter1D := SDL_GL_GetProcAddress('glConvolutionFilter1D');
- if not Assigned(glConvolutionFilter1D) then Exit;
- @glConvolutionFilter2D := SDL_GL_GetProcAddress('glConvolutionFilter2D');
- if not Assigned(glConvolutionFilter2D) then Exit;
- @glConvolutionParameterf := SDL_GL_GetProcAddress('glConvolutionParameterf');
- if not Assigned(glConvolutionParameterf) then Exit;
- @glConvolutionParameterfv := SDL_GL_GetProcAddress('glConvolutionParameterfv');
- if not Assigned(glConvolutionParameterfv) then Exit;
- @glConvolutionParameteri := SDL_GL_GetProcAddress('glConvolutionParameteri');
- if not Assigned(glConvolutionParameteri) then Exit;
- @glConvolutionParameteriv := SDL_GL_GetProcAddress('glConvolutionParameteriv');
- if not Assigned(glConvolutionParameteriv) then Exit;
- @glCopyConvolutionFilter1D := SDL_GL_GetProcAddress('glCopyConvolutionFilter1D');
- if not Assigned(glCopyConvolutionFilter1D) then Exit;
- @glCopyConvolutionFilter2D := SDL_GL_GetProcAddress('glCopyConvolutionFilter2D');
- if not Assigned(glCopyConvolutionFilter2D) then Exit;
- @glGetConvolutionFilter := SDL_GL_GetProcAddress('glGetConvolutionFilter');
- if not Assigned(glGetConvolutionFilter) then Exit;
- @glGetConvolutionParameterfv := SDL_GL_GetProcAddress('glGetConvolutionParameterfv');
- if not Assigned(glGetConvolutionParameterfv) then Exit;
- @glGetConvolutionParameteriv := SDL_GL_GetProcAddress('glGetConvolutionParameteriv');
- if not Assigned(glGetConvolutionParameteriv) then Exit;
- @glGetSeparableFilter := SDL_GL_GetProcAddress('glGetSeparableFilter');
- if not Assigned(glGetSeparableFilter) then Exit;
- @glSeparableFilter2D := SDL_GL_GetProcAddress('glSeparableFilter2D');
- if not Assigned(glSeparableFilter2D) then Exit;
- @glGetHistogram := SDL_GL_GetProcAddress('glGetHistogram');
- if not Assigned(glGetHistogram) then Exit;
- @glGetHistogramParameterfv := SDL_GL_GetProcAddress('glGetHistogramParameterfv');
- if not Assigned(glGetHistogramParameterfv) then Exit;
- @glGetHistogramParameteriv := SDL_GL_GetProcAddress('glGetHistogramParameteriv');
- if not Assigned(glGetHistogramParameteriv) then Exit;
- @glGetMinmax := SDL_GL_GetProcAddress('glGetMinmax');
- if not Assigned(glGetMinmax) then Exit;
- @glGetMinmaxParameterfv := SDL_GL_GetProcAddress('glGetMinmaxParameterfv');
- if not Assigned(glGetMinmaxParameterfv) then Exit;
- @glGetMinmaxParameteriv := SDL_GL_GetProcAddress('glGetMinmaxParameteriv');
- if not Assigned(glGetMinmaxParameteriv) then Exit;
- @glHistogram := SDL_GL_GetProcAddress('glHistogram');
- if not Assigned(glHistogram) then Exit;
- @glMinmax := SDL_GL_GetProcAddress('glMinmax');
- if not Assigned(glMinmax) then Exit;
- @glResetHistogram := SDL_GL_GetProcAddress('glResetHistogram');
- if not Assigned(glResetHistogram) then Exit;
- @glResetMinmax := SDL_GL_GetProcAddress('glResetMinmax');
- if not Assigned(glResetMinmax) then Exit;
- @glBlendEquation := SDL_GL_GetProcAddress('glBlendEquation');
- if not Assigned(glBlendEquation) then Exit;
- @glBlendColor := SDL_GL_GetProcAddress('glBlendColor');
- if not Assigned(glBlendColor) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_version_1_3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- @glActiveTexture := SDL_GL_GetProcAddress('glActiveTexture');
- if not Assigned(glActiveTexture) then Exit;
- @glClientActiveTexture := SDL_GL_GetProcAddress('glClientActiveTexture');
- if not Assigned(glClientActiveTexture) then Exit;
- @glMultiTexCoord1d := SDL_GL_GetProcAddress('glMultiTexCoord1d');
- if not Assigned(glMultiTexCoord1d) then Exit;
- @glMultiTexCoord1dv := SDL_GL_GetProcAddress('glMultiTexCoord1dv');
- if not Assigned(glMultiTexCoord1dv) then Exit;
- @glMultiTexCoord1f := SDL_GL_GetProcAddress('glMultiTexCoord1f');
- if not Assigned(glMultiTexCoord1f) then Exit;
- @glMultiTexCoord1fv := SDL_GL_GetProcAddress('glMultiTexCoord1fv');
- if not Assigned(glMultiTexCoord1fv) then Exit;
- @glMultiTexCoord1i := SDL_GL_GetProcAddress('glMultiTexCoord1i');
- if not Assigned(glMultiTexCoord1i) then Exit;
- @glMultiTexCoord1iv := SDL_GL_GetProcAddress('glMultiTexCoord1iv');
- if not Assigned(glMultiTexCoord1iv) then Exit;
- @glMultiTexCoord1s := SDL_GL_GetProcAddress('glMultiTexCoord1s');
- if not Assigned(glMultiTexCoord1s) then Exit;
- @glMultiTexCoord1sv := SDL_GL_GetProcAddress('glMultiTexCoord1sv');
- if not Assigned(glMultiTexCoord1sv) then Exit;
- @glMultiTexCoord2d := SDL_GL_GetProcAddress('glMultiTexCoord2d');
- if not Assigned(glMultiTexCoord2d) then Exit;
- @glMultiTexCoord2dv := SDL_GL_GetProcAddress('glMultiTexCoord2dv');
- if not Assigned(glMultiTexCoord2dv) then Exit;
- @glMultiTexCoord2f := SDL_GL_GetProcAddress('glMultiTexCoord2f');
- if not Assigned(glMultiTexCoord2f) then Exit;
- @glMultiTexCoord2fv := SDL_GL_GetProcAddress('glMultiTexCoord2fv');
- if not Assigned(glMultiTexCoord2fv) then Exit;
- @glMultiTexCoord2i := SDL_GL_GetProcAddress('glMultiTexCoord2i');
- if not Assigned(glMultiTexCoord2i) then Exit;
- @glMultiTexCoord2iv := SDL_GL_GetProcAddress('glMultiTexCoord2iv');
- if not Assigned(glMultiTexCoord2iv) then Exit;
- @glMultiTexCoord2s := SDL_GL_GetProcAddress('glMultiTexCoord2s');
- if not Assigned(glMultiTexCoord2s) then Exit;
- @glMultiTexCoord2sv := SDL_GL_GetProcAddress('glMultiTexCoord2sv');
- if not Assigned(glMultiTexCoord2sv) then Exit;
- @glMultiTexCoord3d := SDL_GL_GetProcAddress('glMultiTexCoord3d');
- if not Assigned(glMultiTexCoord3d) then Exit;
- @glMultiTexCoord3dv := SDL_GL_GetProcAddress('glMultiTexCoord3dv');
- if not Assigned(glMultiTexCoord3dv) then Exit;
- @glMultiTexCoord3f := SDL_GL_GetProcAddress('glMultiTexCoord3f');
- if not Assigned(glMultiTexCoord3f) then Exit;
- @glMultiTexCoord3fv := SDL_GL_GetProcAddress('glMultiTexCoord3fv');
- if not Assigned(glMultiTexCoord3fv) then Exit;
- @glMultiTexCoord3i := SDL_GL_GetProcAddress('glMultiTexCoord3i');
- if not Assigned(glMultiTexCoord3i) then Exit;
- @glMultiTexCoord3iv := SDL_GL_GetProcAddress('glMultiTexCoord3iv');
- if not Assigned(glMultiTexCoord3iv) then Exit;
- @glMultiTexCoord3s := SDL_GL_GetProcAddress('glMultiTexCoord3s');
- if not Assigned(glMultiTexCoord3s) then Exit;
- @glMultiTexCoord3sv := SDL_GL_GetProcAddress('glMultiTexCoord3sv');
- if not Assigned(glMultiTexCoord3sv) then Exit;
- @glMultiTexCoord4d := SDL_GL_GetProcAddress('glMultiTexCoord4d');
- if not Assigned(glMultiTexCoord4d) then Exit;
- @glMultiTexCoord4dv := SDL_GL_GetProcAddress('glMultiTexCoord4dv');
- if not Assigned(glMultiTexCoord4dv) then Exit;
- @glMultiTexCoord4f := SDL_GL_GetProcAddress('glMultiTexCoord4f');
- if not Assigned(glMultiTexCoord4f) then Exit;
- @glMultiTexCoord4fv := SDL_GL_GetProcAddress('glMultiTexCoord4fv');
- if not Assigned(glMultiTexCoord4fv) then Exit;
- @glMultiTexCoord4i := SDL_GL_GetProcAddress('glMultiTexCoord4i');
- if not Assigned(glMultiTexCoord4i) then Exit;
- @glMultiTexCoord4iv := SDL_GL_GetProcAddress('glMultiTexCoord4iv');
- if not Assigned(glMultiTexCoord4iv) then Exit;
- @glMultiTexCoord4s := SDL_GL_GetProcAddress('glMultiTexCoord4s');
- if not Assigned(glMultiTexCoord4s) then Exit;
- @glMultiTexCoord4sv := SDL_GL_GetProcAddress('glMultiTexCoord4sv');
- if not Assigned(glMultiTexCoord4sv) then Exit;
- @glLoadTransposeMatrixf := SDL_GL_GetProcAddress('glLoadTransposeMatrixf');
- if not Assigned(glLoadTransposeMatrixf) then Exit;
- @glLoadTransposeMatrixd := SDL_GL_GetProcAddress('glLoadTransposeMatrixd');
- if not Assigned(glLoadTransposeMatrixd) then Exit;
- @glMultTransposeMatrixf := SDL_GL_GetProcAddress('glMultTransposeMatrixf');
- if not Assigned(glMultTransposeMatrixf) then Exit;
- @glMultTransposeMatrixd := SDL_GL_GetProcAddress('glMultTransposeMatrixd');
- if not Assigned(glMultTransposeMatrixd) then Exit;
- @glSampleCoverage := SDL_GL_GetProcAddress('glSampleCoverage');
- if not Assigned(glSampleCoverage) then Exit;
- @glCompressedTexImage3D := SDL_GL_GetProcAddress('glCompressedTexImage3D');
- if not Assigned(glCompressedTexImage3D) then Exit;
- @glCompressedTexImage2D := SDL_GL_GetProcAddress('glCompressedTexImage2D');
- if not Assigned(glCompressedTexImage2D) then Exit;
- @glCompressedTexImage1D := SDL_GL_GetProcAddress('glCompressedTexImage1D');
- if not Assigned(glCompressedTexImage1D) then Exit;
- @glCompressedTexSubImage3D := SDL_GL_GetProcAddress('glCompressedTexSubImage3D');
- if not Assigned(glCompressedTexSubImage3D) then Exit;
- @glCompressedTexSubImage2D := SDL_GL_GetProcAddress('glCompressedTexSubImage2D');
- if not Assigned(glCompressedTexSubImage2D) then Exit;
- @glCompressedTexSubImage1D := SDL_GL_GetProcAddress('glCompressedTexSubImage1D');
- if not Assigned(glCompressedTexSubImage1D) then Exit;
- @glGetCompressedTexImage := SDL_GL_GetProcAddress('glGetCompressedTexImage');
- if not Assigned(glGetCompressedTexImage) then Exit;
- Result := TRUE;
-
-end;
-
-function Load_GL_ARB_multitexture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_multitexture', extstring) then
- begin
- @glActiveTextureARB := SDL_GL_GetProcAddress('glActiveTextureARB');
- if not Assigned(glActiveTextureARB) then Exit;
- @glClientActiveTextureARB := SDL_GL_GetProcAddress('glClientActiveTextureARB');
- if not Assigned(glClientActiveTextureARB) then Exit;
- @glMultiTexCoord1dARB := SDL_GL_GetProcAddress('glMultiTexCoord1dARB');
- if not Assigned(glMultiTexCoord1dARB) then Exit;
- @glMultiTexCoord1dvARB := SDL_GL_GetProcAddress('glMultiTexCoord1dvARB');
- if not Assigned(glMultiTexCoord1dvARB) then Exit;
- @glMultiTexCoord1fARB := SDL_GL_GetProcAddress('glMultiTexCoord1fARB');
- if not Assigned(glMultiTexCoord1fARB) then Exit;
- @glMultiTexCoord1fvARB := SDL_GL_GetProcAddress('glMultiTexCoord1fvARB');
- if not Assigned(glMultiTexCoord1fvARB) then Exit;
- @glMultiTexCoord1iARB := SDL_GL_GetProcAddress('glMultiTexCoord1iARB');
- if not Assigned(glMultiTexCoord1iARB) then Exit;
- @glMultiTexCoord1ivARB := SDL_GL_GetProcAddress('glMultiTexCoord1ivARB');
- if not Assigned(glMultiTexCoord1ivARB) then Exit;
- @glMultiTexCoord1sARB := SDL_GL_GetProcAddress('glMultiTexCoord1sARB');
- if not Assigned(glMultiTexCoord1sARB) then Exit;
- @glMultiTexCoord1svARB := SDL_GL_GetProcAddress('glMultiTexCoord1svARB');
- if not Assigned(glMultiTexCoord1svARB) then Exit;
- @glMultiTexCoord2dARB := SDL_GL_GetProcAddress('glMultiTexCoord2dARB');
- if not Assigned(glMultiTexCoord2dARB) then Exit;
- @glMultiTexCoord2dvARB := SDL_GL_GetProcAddress('glMultiTexCoord2dvARB');
- if not Assigned(glMultiTexCoord2dvARB) then Exit;
- @glMultiTexCoord2fARB := SDL_GL_GetProcAddress('glMultiTexCoord2fARB');
- if not Assigned(glMultiTexCoord2fARB) then Exit;
- @glMultiTexCoord2fvARB := SDL_GL_GetProcAddress('glMultiTexCoord2fvARB');
- if not Assigned(glMultiTexCoord2fvARB) then Exit;
- @glMultiTexCoord2iARB := SDL_GL_GetProcAddress('glMultiTexCoord2iARB');
- if not Assigned(glMultiTexCoord2iARB) then Exit;
- @glMultiTexCoord2ivARB := SDL_GL_GetProcAddress('glMultiTexCoord2ivARB');
- if not Assigned(glMultiTexCoord2ivARB) then Exit;
- @glMultiTexCoord2sARB := SDL_GL_GetProcAddress('glMultiTexCoord2sARB');
- if not Assigned(glMultiTexCoord2sARB) then Exit;
- @glMultiTexCoord2svARB := SDL_GL_GetProcAddress('glMultiTexCoord2svARB');
- if not Assigned(glMultiTexCoord2svARB) then Exit;
- @glMultiTexCoord3dARB := SDL_GL_GetProcAddress('glMultiTexCoord3dARB');
- if not Assigned(glMultiTexCoord3dARB) then Exit;
- @glMultiTexCoord3dvARB := SDL_GL_GetProcAddress('glMultiTexCoord3dvARB');
- if not Assigned(glMultiTexCoord3dvARB) then Exit;
- @glMultiTexCoord3fARB := SDL_GL_GetProcAddress('glMultiTexCoord3fARB');
- if not Assigned(glMultiTexCoord3fARB) then Exit;
- @glMultiTexCoord3fvARB := SDL_GL_GetProcAddress('glMultiTexCoord3fvARB');
- if not Assigned(glMultiTexCoord3fvARB) then Exit;
- @glMultiTexCoord3iARB := SDL_GL_GetProcAddress('glMultiTexCoord3iARB');
- if not Assigned(glMultiTexCoord3iARB) then Exit;
- @glMultiTexCoord3ivARB := SDL_GL_GetProcAddress('glMultiTexCoord3ivARB');
- if not Assigned(glMultiTexCoord3ivARB) then Exit;
- @glMultiTexCoord3sARB := SDL_GL_GetProcAddress('glMultiTexCoord3sARB');
- if not Assigned(glMultiTexCoord3sARB) then Exit;
- @glMultiTexCoord3svARB := SDL_GL_GetProcAddress('glMultiTexCoord3svARB');
- if not Assigned(glMultiTexCoord3svARB) then Exit;
- @glMultiTexCoord4dARB := SDL_GL_GetProcAddress('glMultiTexCoord4dARB');
- if not Assigned(glMultiTexCoord4dARB) then Exit;
- @glMultiTexCoord4dvARB := SDL_GL_GetProcAddress('glMultiTexCoord4dvARB');
- if not Assigned(glMultiTexCoord4dvARB) then Exit;
- @glMultiTexCoord4fARB := SDL_GL_GetProcAddress('glMultiTexCoord4fARB');
- if not Assigned(glMultiTexCoord4fARB) then Exit;
- @glMultiTexCoord4fvARB := SDL_GL_GetProcAddress('glMultiTexCoord4fvARB');
- if not Assigned(glMultiTexCoord4fvARB) then Exit;
- @glMultiTexCoord4iARB := SDL_GL_GetProcAddress('glMultiTexCoord4iARB');
- if not Assigned(glMultiTexCoord4iARB) then Exit;
- @glMultiTexCoord4ivARB := SDL_GL_GetProcAddress('glMultiTexCoord4ivARB');
- if not Assigned(glMultiTexCoord4ivARB) then Exit;
- @glMultiTexCoord4sARB := SDL_GL_GetProcAddress('glMultiTexCoord4sARB');
- if not Assigned(glMultiTexCoord4sARB) then Exit;
- @glMultiTexCoord4svARB := SDL_GL_GetProcAddress('glMultiTexCoord4svARB');
- if not Assigned(glMultiTexCoord4svARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_transpose_matrix: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_transpose_matrix', extstring) then
- begin
- @glLoadTransposeMatrixfARB := SDL_GL_GetProcAddress('glLoadTransposeMatrixfARB');
- if not Assigned(glLoadTransposeMatrixfARB) then Exit;
- @glLoadTransposeMatrixdARB := SDL_GL_GetProcAddress('glLoadTransposeMatrixdARB');
- if not Assigned(glLoadTransposeMatrixdARB) then Exit;
- @glMultTransposeMatrixfARB := SDL_GL_GetProcAddress('glMultTransposeMatrixfARB');
- if not Assigned(glMultTransposeMatrixfARB) then Exit;
- @glMultTransposeMatrixdARB := SDL_GL_GetProcAddress('glMultTransposeMatrixdARB');
- if not Assigned(glMultTransposeMatrixdARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_multisample: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_multisample', extstring) then
- begin
- @glSampleCoverageARB := SDL_GL_GetProcAddress('glSampleCoverageARB');
- if not Assigned(glSampleCoverageARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_env_add: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_env_add', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-{$IFDEF WINDOWS}
-function Load_WGL_ARB_extensions_string: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_extensions_string', extstring) then
- begin
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_ARB_buffer_region: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_buffer_region', extstring) then
- begin
- @wglCreateBufferRegionARB := SDL_GL_GetProcAddress('wglCreateBufferRegionARB');
- if not Assigned(wglCreateBufferRegionARB) then Exit;
- @wglDeleteBufferRegionARB := SDL_GL_GetProcAddress('wglDeleteBufferRegionARB');
- if not Assigned(wglDeleteBufferRegionARB) then Exit;
- @wglSaveBufferRegionARB := SDL_GL_GetProcAddress('wglSaveBufferRegionARB');
- if not Assigned(wglSaveBufferRegionARB) then Exit;
- @wglRestoreBufferRegionARB := SDL_GL_GetProcAddress('wglRestoreBufferRegionARB');
- if not Assigned(wglRestoreBufferRegionARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-{$ENDIF}
-
-function Load_GL_ARB_texture_cube_map: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_cube_map', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_depth_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_depth_texture', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_point_parameters: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_point_parameters', extstring) then
- begin
- @glPointParameterfARB := SDL_GL_GetProcAddress('glPointParameterfARB');
- if not Assigned(glPointParameterfARB) then Exit;
- @glPointParameterfvARB := SDL_GL_GetProcAddress('glPointParameterfvARB');
- if not Assigned(glPointParameterfvARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_shadow: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_shadow', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_shadow_ambient: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_shadow_ambient', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_border_clamp: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_border_clamp', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_compression: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_compression', extstring) then
- begin
- @glCompressedTexImage3DARB := SDL_GL_GetProcAddress('glCompressedTexImage3DARB');
- if not Assigned(glCompressedTexImage3DARB) then Exit;
- @glCompressedTexImage2DARB := SDL_GL_GetProcAddress('glCompressedTexImage2DARB');
- if not Assigned(glCompressedTexImage2DARB) then Exit;
- @glCompressedTexImage1DARB := SDL_GL_GetProcAddress('glCompressedTexImage1DARB');
- if not Assigned(glCompressedTexImage1DARB) then Exit;
- @glCompressedTexSubImage3DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage3DARB');
- if not Assigned(glCompressedTexSubImage3DARB) then Exit;
- @glCompressedTexSubImage2DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage2DARB');
- if not Assigned(glCompressedTexSubImage2DARB) then Exit;
- @glCompressedTexSubImage1DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage1DARB');
- if not Assigned(glCompressedTexSubImage1DARB) then Exit;
- @glGetCompressedTexImageARB := SDL_GL_GetProcAddress('glGetCompressedTexImageARB');
- if not Assigned(glGetCompressedTexImageARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_env_combine: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_env_combine', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_env_crossbar: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_env_crossbar', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_env_dot3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_env_dot3', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_mirrored_repeat: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_mirrored_repeat', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_vertex_blend: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_vertex_blend', extstring) then
- begin
- @glWeightbvARB := SDL_GL_GetProcAddress('glWeightbvARB');
- if not Assigned(glWeightbvARB) then Exit;
- @glWeightsvARB := SDL_GL_GetProcAddress('glWeightsvARB');
- if not Assigned(glWeightsvARB) then Exit;
- @glWeightivARB := SDL_GL_GetProcAddress('glWeightivARB');
- if not Assigned(glWeightivARB) then Exit;
- @glWeightfvARB := SDL_GL_GetProcAddress('glWeightfvARB');
- if not Assigned(glWeightfvARB) then Exit;
- @glWeightdvARB := SDL_GL_GetProcAddress('glWeightdvARB');
- if not Assigned(glWeightdvARB) then Exit;
- @glWeightvARB := SDL_GL_GetProcAddress('glWeightvARB');
- if not Assigned(glWeightvARB) then Exit;
- @glWeightubvARB := SDL_GL_GetProcAddress('glWeightubvARB');
- if not Assigned(glWeightubvARB) then Exit;
- @glWeightusvARB := SDL_GL_GetProcAddress('glWeightusvARB');
- if not Assigned(glWeightusvARB) then Exit;
- @glWeightuivARB := SDL_GL_GetProcAddress('glWeightuivARB');
- if not Assigned(glWeightuivARB) then Exit;
- @glWeightPointerARB := SDL_GL_GetProcAddress('glWeightPointerARB');
- if not Assigned(glWeightPointerARB) then Exit;
- @glVertexBlendARB := SDL_GL_GetProcAddress('glVertexBlendARB');
- if not Assigned(glVertexBlendARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_vertex_program: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_vertex_program', extstring) then
- begin
- @glVertexAttrib1sARB := SDL_GL_GetProcAddress('glVertexAttrib1sARB');
- if not Assigned(glVertexAttrib1sARB) then Exit;
- @glVertexAttrib1fARB := SDL_GL_GetProcAddress('glVertexAttrib1fARB');
- if not Assigned(glVertexAttrib1fARB) then Exit;
- @glVertexAttrib1dARB := SDL_GL_GetProcAddress('glVertexAttrib1dARB');
- if not Assigned(glVertexAttrib1dARB) then Exit;
- @glVertexAttrib2sARB := SDL_GL_GetProcAddress('glVertexAttrib2sARB');
- if not Assigned(glVertexAttrib2sARB) then Exit;
- @glVertexAttrib2fARB := SDL_GL_GetProcAddress('glVertexAttrib2fARB');
- if not Assigned(glVertexAttrib2fARB) then Exit;
- @glVertexAttrib2dARB := SDL_GL_GetProcAddress('glVertexAttrib2dARB');
- if not Assigned(glVertexAttrib2dARB) then Exit;
- @glVertexAttrib3sARB := SDL_GL_GetProcAddress('glVertexAttrib3sARB');
- if not Assigned(glVertexAttrib3sARB) then Exit;
- @glVertexAttrib3fARB := SDL_GL_GetProcAddress('glVertexAttrib3fARB');
- if not Assigned(glVertexAttrib3fARB) then Exit;
- @glVertexAttrib3dARB := SDL_GL_GetProcAddress('glVertexAttrib3dARB');
- if not Assigned(glVertexAttrib3dARB) then Exit;
- @glVertexAttrib4sARB := SDL_GL_GetProcAddress('glVertexAttrib4sARB');
- if not Assigned(glVertexAttrib4sARB) then Exit;
- @glVertexAttrib4fARB := SDL_GL_GetProcAddress('glVertexAttrib4fARB');
- if not Assigned(glVertexAttrib4fARB) then Exit;
- @glVertexAttrib4dARB := SDL_GL_GetProcAddress('glVertexAttrib4dARB');
- if not Assigned(glVertexAttrib4dARB) then Exit;
- @glVertexAttrib4NubARB := SDL_GL_GetProcAddress('glVertexAttrib4NubARB');
- if not Assigned(glVertexAttrib4NubARB) then Exit;
- @glVertexAttrib1svARB := SDL_GL_GetProcAddress('glVertexAttrib1svARB');
- if not Assigned(glVertexAttrib1svARB) then Exit;
- @glVertexAttrib1fvARB := SDL_GL_GetProcAddress('glVertexAttrib1fvARB');
- if not Assigned(glVertexAttrib1fvARB) then Exit;
- @glVertexAttrib1dvARB := SDL_GL_GetProcAddress('glVertexAttrib1dvARB');
- if not Assigned(glVertexAttrib1dvARB) then Exit;
- @glVertexAttrib2svARB := SDL_GL_GetProcAddress('glVertexAttrib2svARB');
- if not Assigned(glVertexAttrib2svARB) then Exit;
- @glVertexAttrib2fvARB := SDL_GL_GetProcAddress('glVertexAttrib2fvARB');
- if not Assigned(glVertexAttrib2fvARB) then Exit;
- @glVertexAttrib2dvARB := SDL_GL_GetProcAddress('glVertexAttrib2dvARB');
- if not Assigned(glVertexAttrib2dvARB) then Exit;
- @glVertexAttrib3svARB := SDL_GL_GetProcAddress('glVertexAttrib3svARB');
- if not Assigned(glVertexAttrib3svARB) then Exit;
- @glVertexAttrib3fvARB := SDL_GL_GetProcAddress('glVertexAttrib3fvARB');
- if not Assigned(glVertexAttrib3fvARB) then Exit;
- @glVertexAttrib3dvARB := SDL_GL_GetProcAddress('glVertexAttrib3dvARB');
- if not Assigned(glVertexAttrib3dvARB) then Exit;
- @glVertexAttrib4bvARB := SDL_GL_GetProcAddress('glVertexAttrib4bvARB');
- if not Assigned(glVertexAttrib4bvARB) then Exit;
- @glVertexAttrib4svARB := SDL_GL_GetProcAddress('glVertexAttrib4svARB');
- if not Assigned(glVertexAttrib4svARB) then Exit;
- @glVertexAttrib4ivARB := SDL_GL_GetProcAddress('glVertexAttrib4ivARB');
- if not Assigned(glVertexAttrib4ivARB) then Exit;
- @glVertexAttrib4ubvARB := SDL_GL_GetProcAddress('glVertexAttrib4ubvARB');
- if not Assigned(glVertexAttrib4ubvARB) then Exit;
- @glVertexAttrib4usvARB := SDL_GL_GetProcAddress('glVertexAttrib4usvARB');
- if not Assigned(glVertexAttrib4usvARB) then Exit;
- @glVertexAttrib4uivARB := SDL_GL_GetProcAddress('glVertexAttrib4uivARB');
- if not Assigned(glVertexAttrib4uivARB) then Exit;
- @glVertexAttrib4fvARB := SDL_GL_GetProcAddress('glVertexAttrib4fvARB');
- if not Assigned(glVertexAttrib4fvARB) then Exit;
- @glVertexAttrib4dvARB := SDL_GL_GetProcAddress('glVertexAttrib4dvARB');
- if not Assigned(glVertexAttrib4dvARB) then Exit;
- @glVertexAttrib4NbvARB := SDL_GL_GetProcAddress('glVertexAttrib4NbvARB');
- if not Assigned(glVertexAttrib4NbvARB) then Exit;
- @glVertexAttrib4NsvARB := SDL_GL_GetProcAddress('glVertexAttrib4NsvARB');
- if not Assigned(glVertexAttrib4NsvARB) then Exit;
- @glVertexAttrib4NivARB := SDL_GL_GetProcAddress('glVertexAttrib4NivARB');
- if not Assigned(glVertexAttrib4NivARB) then Exit;
- @glVertexAttrib4NubvARB := SDL_GL_GetProcAddress('glVertexAttrib4NubvARB');
- if not Assigned(glVertexAttrib4NubvARB) then Exit;
- @glVertexAttrib4NusvARB := SDL_GL_GetProcAddress('glVertexAttrib4NusvARB');
- if not Assigned(glVertexAttrib4NusvARB) then Exit;
- @glVertexAttrib4NuivARB := SDL_GL_GetProcAddress('glVertexAttrib4NuivARB');
- if not Assigned(glVertexAttrib4NuivARB) then Exit;
- @glVertexAttribPointerARB := SDL_GL_GetProcAddress('glVertexAttribPointerARB');
- if not Assigned(glVertexAttribPointerARB) then Exit;
- @glEnableVertexAttribArrayARB := SDL_GL_GetProcAddress('glEnableVertexAttribArrayARB');
- if not Assigned(glEnableVertexAttribArrayARB) then Exit;
- @glDisableVertexAttribArrayARB := SDL_GL_GetProcAddress('glDisableVertexAttribArrayARB');
- if not Assigned(glDisableVertexAttribArrayARB) then Exit;
- @glProgramStringARB := SDL_GL_GetProcAddress('glProgramStringARB');
- if not Assigned(glProgramStringARB) then Exit;
- @glBindProgramARB := SDL_GL_GetProcAddress('glBindProgramARB');
- if not Assigned(glBindProgramARB) then Exit;
- @glDeleteProgramsARB := SDL_GL_GetProcAddress('glDeleteProgramsARB');
- if not Assigned(glDeleteProgramsARB) then Exit;
- @glGenProgramsARB := SDL_GL_GetProcAddress('glGenProgramsARB');
- if not Assigned(glGenProgramsARB) then Exit;
- @glProgramEnvParameter4dARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dARB');
- if not Assigned(glProgramEnvParameter4dARB) then Exit;
- @glProgramEnvParameter4dvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dvARB');
- if not Assigned(glProgramEnvParameter4dvARB) then Exit;
- @glProgramEnvParameter4fARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fARB');
- if not Assigned(glProgramEnvParameter4fARB) then Exit;
- @glProgramEnvParameter4fvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fvARB');
- if not Assigned(glProgramEnvParameter4fvARB) then Exit;
- @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
- if not Assigned(glProgramLocalParameter4dARB) then Exit;
- @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
- if not Assigned(glProgramLocalParameter4dvARB) then Exit;
- @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
- if not Assigned(glProgramLocalParameter4fARB) then Exit;
- @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
- if not Assigned(glProgramLocalParameter4fvARB) then Exit;
- @glGetProgramEnvParameterdvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterdvARB');
- if not Assigned(glGetProgramEnvParameterdvARB) then Exit;
- @glGetProgramEnvParameterfvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterfvARB');
- if not Assigned(glGetProgramEnvParameterfvARB) then Exit;
- @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
- if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
- @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
- if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
- @glGetProgramivARB := SDL_GL_GetProcAddress('glGetProgramivARB');
- if not Assigned(glGetProgramivARB) then Exit;
- @glGetProgramStringARB := SDL_GL_GetProcAddress('glGetProgramStringARB');
- if not Assigned(glGetProgramStringARB) then Exit;
- @glGetVertexAttribdvARB := SDL_GL_GetProcAddress('glGetVertexAttribdvARB');
- if not Assigned(glGetVertexAttribdvARB) then Exit;
- @glGetVertexAttribfvARB := SDL_GL_GetProcAddress('glGetVertexAttribfvARB');
- if not Assigned(glGetVertexAttribfvARB) then Exit;
- @glGetVertexAttribivARB := SDL_GL_GetProcAddress('glGetVertexAttribivARB');
- if not Assigned(glGetVertexAttribivARB) then Exit;
- @glGetVertexAttribPointervARB := SDL_GL_GetProcAddress('glGetVertexAttribPointervARB');
- if not Assigned(glGetVertexAttribPointervARB) then Exit;
- @glIsProgramARB := SDL_GL_GetProcAddress('glIsProgramARB');
- if not Assigned(glIsProgramARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_window_pos: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_window_pos', extstring) then
- begin
- @glWindowPos2dARB := SDL_GL_GetProcAddress('glWindowPos2dARB');
- if not Assigned(glWindowPos2dARB) then Exit;
- @glWindowPos2fARB := SDL_GL_GetProcAddress('glWindowPos2fARB');
- if not Assigned(glWindowPos2fARB) then Exit;
- @glWindowPos2iARB := SDL_GL_GetProcAddress('glWindowPos2iARB');
- if not Assigned(glWindowPos2iARB) then Exit;
- @glWindowPos2sARB := SDL_GL_GetProcAddress('glWindowPos2sARB');
- if not Assigned(glWindowPos2sARB) then Exit;
- @glWindowPos2dvARB := SDL_GL_GetProcAddress('glWindowPos2dvARB');
- if not Assigned(glWindowPos2dvARB) then Exit;
- @glWindowPos2fvARB := SDL_GL_GetProcAddress('glWindowPos2fvARB');
- if not Assigned(glWindowPos2fvARB) then Exit;
- @glWindowPos2ivARB := SDL_GL_GetProcAddress('glWindowPos2ivARB');
- if not Assigned(glWindowPos2ivARB) then Exit;
- @glWindowPos2svARB := SDL_GL_GetProcAddress('glWindowPos2svARB');
- if not Assigned(glWindowPos2svARB) then Exit;
- @glWindowPos3dARB := SDL_GL_GetProcAddress('glWindowPos3dARB');
- if not Assigned(glWindowPos3dARB) then Exit;
- @glWindowPos3fARB := SDL_GL_GetProcAddress('glWindowPos3fARB');
- if not Assigned(glWindowPos3fARB) then Exit;
- @glWindowPos3iARB := SDL_GL_GetProcAddress('glWindowPos3iARB');
- if not Assigned(glWindowPos3iARB) then Exit;
- @glWindowPos3sARB := SDL_GL_GetProcAddress('glWindowPos3sARB');
- if not Assigned(glWindowPos3sARB) then Exit;
- @glWindowPos3dvARB := SDL_GL_GetProcAddress('glWindowPos3dvARB');
- if not Assigned(glWindowPos3dvARB) then Exit;
- @glWindowPos3fvARB := SDL_GL_GetProcAddress('glWindowPos3fvARB');
- if not Assigned(glWindowPos3fvARB) then Exit;
- @glWindowPos3ivARB := SDL_GL_GetProcAddress('glWindowPos3ivARB');
- if not Assigned(glWindowPos3ivARB) then Exit;
- @glWindowPos3svARB := SDL_GL_GetProcAddress('glWindowPos3svARB');
- if not Assigned(glWindowPos3svARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_422_pixels: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_422_pixels', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_abgr: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_abgr', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_bgra: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_bgra', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_color: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_color', extstring) then
- begin
- @glBlendColorEXT := SDL_GL_GetProcAddress('glBlendColorEXT');
- if not Assigned(glBlendColorEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_func_separate: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_func_separate', extstring) then
- begin
- @glBlendFuncSeparateEXT := SDL_GL_GetProcAddress('glBlendFuncSeparateEXT');
- if not Assigned(glBlendFuncSeparateEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_logic_op: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_logic_op', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_minmax: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_minmax', extstring) then
- begin
- @glBlendEquationEXT := SDL_GL_GetProcAddress('glBlendEquationEXT');
- if not Assigned(glBlendEquationEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_subtract: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_subtract', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_clip_volume_hint: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_clip_volume_hint', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_color_subtable: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_color_subtable', extstring) then
- begin
- @glColorSubTableEXT := SDL_GL_GetProcAddress('glColorSubTableEXT');
- if not Assigned(glColorSubTableEXT) then Exit;
- @glCopyColorSubTableEXT := SDL_GL_GetProcAddress('glCopyColorSubTableEXT');
- if not Assigned(glCopyColorSubTableEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_compiled_vertex_array: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_compiled_vertex_array', extstring) then
- begin
- @glLockArraysEXT := SDL_GL_GetProcAddress('glLockArraysEXT');
- if not Assigned(glLockArraysEXT) then Exit;
- @glUnlockArraysEXT := SDL_GL_GetProcAddress('glUnlockArraysEXT');
- if not Assigned(glUnlockArraysEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_convolution: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_convolution', extstring) then
- begin
- @glConvolutionFilter1DEXT := SDL_GL_GetProcAddress('glConvolutionFilter1DEXT');
- if not Assigned(glConvolutionFilter1DEXT) then Exit;
- @glConvolutionFilter2DEXT := SDL_GL_GetProcAddress('glConvolutionFilter2DEXT');
- if not Assigned(glConvolutionFilter2DEXT) then Exit;
- @glCopyConvolutionFilter1DEXT := SDL_GL_GetProcAddress('glCopyConvolutionFilter1DEXT');
- if not Assigned(glCopyConvolutionFilter1DEXT) then Exit;
- @glCopyConvolutionFilter2DEXT := SDL_GL_GetProcAddress('glCopyConvolutionFilter2DEXT');
- if not Assigned(glCopyConvolutionFilter2DEXT) then Exit;
- @glGetConvolutionFilterEXT := SDL_GL_GetProcAddress('glGetConvolutionFilterEXT');
- if not Assigned(glGetConvolutionFilterEXT) then Exit;
- @glSeparableFilter2DEXT := SDL_GL_GetProcAddress('glSeparableFilter2DEXT');
- if not Assigned(glSeparableFilter2DEXT) then Exit;
- @glGetSeparableFilterEXT := SDL_GL_GetProcAddress('glGetSeparableFilterEXT');
- if not Assigned(glGetSeparableFilterEXT) then Exit;
- @glConvolutionParameteriEXT := SDL_GL_GetProcAddress('glConvolutionParameteriEXT');
- if not Assigned(glConvolutionParameteriEXT) then Exit;
- @glConvolutionParameterivEXT := SDL_GL_GetProcAddress('glConvolutionParameterivEXT');
- if not Assigned(glConvolutionParameterivEXT) then Exit;
- @glConvolutionParameterfEXT := SDL_GL_GetProcAddress('glConvolutionParameterfEXT');
- if not Assigned(glConvolutionParameterfEXT) then Exit;
- @glConvolutionParameterfvEXT := SDL_GL_GetProcAddress('glConvolutionParameterfvEXT');
- if not Assigned(glConvolutionParameterfvEXT) then Exit;
- @glGetConvolutionParameterivEXT := SDL_GL_GetProcAddress('glGetConvolutionParameterivEXT');
- if not Assigned(glGetConvolutionParameterivEXT) then Exit;
- @glGetConvolutionParameterfvEXT := SDL_GL_GetProcAddress('glGetConvolutionParameterfvEXT');
- if not Assigned(glGetConvolutionParameterfvEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_histogram: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_histogram', extstring) then
- begin
- @glHistogramEXT := SDL_GL_GetProcAddress('glHistogramEXT');
- if not Assigned(glHistogramEXT) then Exit;
- @glResetHistogramEXT := SDL_GL_GetProcAddress('glResetHistogramEXT');
- if not Assigned(glResetHistogramEXT) then Exit;
- @glGetHistogramEXT := SDL_GL_GetProcAddress('glGetHistogramEXT');
- if not Assigned(glGetHistogramEXT) then Exit;
- @glGetHistogramParameterivEXT := SDL_GL_GetProcAddress('glGetHistogramParameterivEXT');
- if not Assigned(glGetHistogramParameterivEXT) then Exit;
- @glGetHistogramParameterfvEXT := SDL_GL_GetProcAddress('glGetHistogramParameterfvEXT');
- if not Assigned(glGetHistogramParameterfvEXT) then Exit;
- @glMinmaxEXT := SDL_GL_GetProcAddress('glMinmaxEXT');
- if not Assigned(glMinmaxEXT) then Exit;
- @glResetMinmaxEXT := SDL_GL_GetProcAddress('glResetMinmaxEXT');
- if not Assigned(glResetMinmaxEXT) then Exit;
- @glGetMinmaxEXT := SDL_GL_GetProcAddress('glGetMinmaxEXT');
- if not Assigned(glGetMinmaxEXT) then Exit;
- @glGetMinmaxParameterivEXT := SDL_GL_GetProcAddress('glGetMinmaxParameterivEXT');
- if not Assigned(glGetMinmaxParameterivEXT) then Exit;
- @glGetMinmaxParameterfvEXT := SDL_GL_GetProcAddress('glGetMinmaxParameterfvEXT');
- if not Assigned(glGetMinmaxParameterfvEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_multi_draw_arrays: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_multi_draw_arrays', extstring) then
- begin
- @glMultiDrawArraysEXT := SDL_GL_GetProcAddress('glMultiDrawArraysEXT');
- if not Assigned(glMultiDrawArraysEXT) then Exit;
- @glMultiDrawElementsEXT := SDL_GL_GetProcAddress('glMultiDrawElementsEXT');
- if not Assigned(glMultiDrawElementsEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_packed_pixels: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_packed_pixels', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_paletted_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_paletted_texture', extstring) then
- begin
- @glColorTableEXT := SDL_GL_GetProcAddress('glColorTableEXT');
- if not Assigned(glColorTableEXT) then Exit;
- @glColorSubTableEXT := SDL_GL_GetProcAddress('glColorSubTableEXT');
- if not Assigned(glColorSubTableEXT) then Exit;
- @glGetColorTableEXT := SDL_GL_GetProcAddress('glGetColorTableEXT');
- if not Assigned(glGetColorTableEXT) then Exit;
- @glGetColorTableParameterivEXT := SDL_GL_GetProcAddress('glGetColorTableParameterivEXT');
- if not Assigned(glGetColorTableParameterivEXT) then Exit;
- @glGetColorTableParameterfvEXT := SDL_GL_GetProcAddress('glGetColorTableParameterfvEXT');
- if not Assigned(glGetColorTableParameterfvEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_point_parameters: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_point_parameters', extstring) then
- begin
- @glPointParameterfEXT := SDL_GL_GetProcAddress('glPointParameterfEXT');
- if not Assigned(glPointParameterfEXT) then Exit;
- @glPointParameterfvEXT := SDL_GL_GetProcAddress('glPointParameterfvEXT');
- if not Assigned(glPointParameterfvEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_polygon_offset: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_polygon_offset', extstring) then
- begin
- @glPolygonOffsetEXT := SDL_GL_GetProcAddress('glPolygonOffsetEXT');
- if not Assigned(glPolygonOffsetEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_separate_specular_color: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_separate_specular_color', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_shadow_funcs: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_shadow_funcs', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_shared_texture_palette: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_shared_texture_palette', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_stencil_two_side: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_stencil_two_side', extstring) then
- begin
- @glActiveStencilFaceEXT := SDL_GL_GetProcAddress('glActiveStencilFaceEXT');
- if not Assigned(glActiveStencilFaceEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_stencil_wrap: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_stencil_wrap', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_subtexture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_subtexture', extstring) then
- begin
- @glTexSubImage1DEXT := SDL_GL_GetProcAddress('glTexSubImage1DEXT');
- if not Assigned(glTexSubImage1DEXT) then Exit;
- @glTexSubImage2DEXT := SDL_GL_GetProcAddress('glTexSubImage2DEXT');
- if not Assigned(glTexSubImage2DEXT) then Exit;
- @glTexSubImage3DEXT := SDL_GL_GetProcAddress('glTexSubImage3DEXT');
- if not Assigned(glTexSubImage3DEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture3D: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture3D', extstring) then
- begin
- glTexImage3DEXT := SDL_GL_GetProcAddress('glTexImage3DEXT');
- if not Assigned(glTexImage3DEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_compression_s3tc: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_compression_s3tc', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_env_add: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_env_add', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_env_combine: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_env_combine', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_env_dot3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_env_dot3', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_filter_anisotropic: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_filter_anisotropic', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_lod_bias: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_lod_bias', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_object', extstring) then
- begin
- @glGenTexturesEXT := SDL_GL_GetProcAddress('glGenTexturesEXT');
- if not Assigned(glGenTexturesEXT) then Exit;
- @glDeleteTexturesEXT := SDL_GL_GetProcAddress('glDeleteTexturesEXT');
- if not Assigned(glDeleteTexturesEXT) then Exit;
- @glBindTextureEXT := SDL_GL_GetProcAddress('glBindTextureEXT');
- if not Assigned(glBindTextureEXT) then Exit;
- @glPrioritizeTexturesEXT := SDL_GL_GetProcAddress('glPrioritizeTexturesEXT');
- if not Assigned(glPrioritizeTexturesEXT) then Exit;
- @glAreTexturesResidentEXT := SDL_GL_GetProcAddress('glAreTexturesResidentEXT');
- if not Assigned(glAreTexturesResidentEXT) then Exit;
- @glIsTextureEXT := SDL_GL_GetProcAddress('glIsTextureEXT');
- if not Assigned(glIsTextureEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_vertex_array: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_vertex_array', extstring) then
- begin
- @glArrayElementEXT := SDL_GL_GetProcAddress('glArrayElementEXT');
- if not Assigned(glArrayElementEXT) then Exit;
- @glDrawArraysEXT := SDL_GL_GetProcAddress('glDrawArraysEXT');
- if not Assigned(glDrawArraysEXT) then Exit;
- @glVertexPointerEXT := SDL_GL_GetProcAddress('glVertexPointerEXT');
- if not Assigned(glVertexPointerEXT) then Exit;
- @glNormalPointerEXT := SDL_GL_GetProcAddress('glNormalPointerEXT');
- if not Assigned(glNormalPointerEXT) then Exit;
- @glColorPointerEXT := SDL_GL_GetProcAddress('glColorPointerEXT');
- if not Assigned(glColorPointerEXT) then Exit;
- @glIndexPointerEXT := SDL_GL_GetProcAddress('glIndexPointerEXT');
- if not Assigned(glIndexPointerEXT) then Exit;
- @glTexCoordPointerEXT := SDL_GL_GetProcAddress('glTexCoordPointerEXT');
- if not Assigned(glTexCoordPointerEXT) then Exit;
- @glEdgeFlagPointerEXT := SDL_GL_GetProcAddress('glEdgeFlagPointerEXT');
- if not Assigned(glEdgeFlagPointerEXT) then Exit;
- @glGetPointervEXT := SDL_GL_GetProcAddress('glGetPointervEXT');
- if not Assigned(glGetPointervEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_vertex_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_vertex_shader', extstring) then
- begin
- @glBeginVertexShaderEXT := SDL_GL_GetProcAddress('glBeginVertexShaderEXT');
- if not Assigned(glBeginVertexShaderEXT) then Exit;
- @glEndVertexShaderEXT := SDL_GL_GetProcAddress('glEndVertexShaderEXT');
- if not Assigned(glEndVertexShaderEXT) then Exit;
- @glBindVertexShaderEXT := SDL_GL_GetProcAddress('glBindVertexShaderEXT');
- if not Assigned(glBindVertexShaderEXT) then Exit;
- @glGenVertexShadersEXT := SDL_GL_GetProcAddress('glGenVertexShadersEXT');
- if not Assigned(glGenVertexShadersEXT) then Exit;
- @glDeleteVertexShaderEXT := SDL_GL_GetProcAddress('glDeleteVertexShaderEXT');
- if not Assigned(glDeleteVertexShaderEXT) then Exit;
- @glShaderOp1EXT := SDL_GL_GetProcAddress('glShaderOp1EXT');
- if not Assigned(glShaderOp1EXT) then Exit;
- @glShaderOp2EXT := SDL_GL_GetProcAddress('glShaderOp2EXT');
- if not Assigned(glShaderOp2EXT) then Exit;
- @glShaderOp3EXT := SDL_GL_GetProcAddress('glShaderOp3EXT');
- if not Assigned(glShaderOp3EXT) then Exit;
- @glSwizzleEXT := SDL_GL_GetProcAddress('glSwizzleEXT');
- if not Assigned(glSwizzleEXT) then Exit;
- @glWriteMaskEXT := SDL_GL_GetProcAddress('glWriteMaskEXT');
- if not Assigned(glWriteMaskEXT) then Exit;
- @glInsertComponentEXT := SDL_GL_GetProcAddress('glInsertComponentEXT');
- if not Assigned(glInsertComponentEXT) then Exit;
- @glExtractComponentEXT := SDL_GL_GetProcAddress('glExtractComponentEXT');
- if not Assigned(glExtractComponentEXT) then Exit;
- @glGenSymbolsEXT := SDL_GL_GetProcAddress('glGenSymbolsEXT');
- if not Assigned(glGenSymbolsEXT) then Exit;
- @glSetInvariantEXT := SDL_GL_GetProcAddress('glSetInvariantEXT');
- if not Assigned(glSetInvariantEXT) then Exit;
- @glSetLocalConstantEXT := SDL_GL_GetProcAddress('glSetLocalConstantEXT');
- if not Assigned(glSetLocalConstantEXT) then Exit;
- @glVariantbvEXT := SDL_GL_GetProcAddress('glVariantbvEXT');
- if not Assigned(glVariantbvEXT) then Exit;
- @glVariantsvEXT := SDL_GL_GetProcAddress('glVariantsvEXT');
- if not Assigned(glVariantsvEXT) then Exit;
- @glVariantivEXT := SDL_GL_GetProcAddress('glVariantivEXT');
- if not Assigned(glVariantivEXT) then Exit;
- @glVariantfvEXT := SDL_GL_GetProcAddress('glVariantfvEXT');
- if not Assigned(glVariantfvEXT) then Exit;
- @glVariantdvEXT := SDL_GL_GetProcAddress('glVariantdvEXT');
- if not Assigned(glVariantdvEXT) then Exit;
- @glVariantubvEXT := SDL_GL_GetProcAddress('glVariantubvEXT');
- if not Assigned(glVariantubvEXT) then Exit;
- @glVariantusvEXT := SDL_GL_GetProcAddress('glVariantusvEXT');
- if not Assigned(glVariantusvEXT) then Exit;
- @glVariantuivEXT := SDL_GL_GetProcAddress('glVariantuivEXT');
- if not Assigned(glVariantuivEXT) then Exit;
- @glVariantPointerEXT := SDL_GL_GetProcAddress('glVariantPointerEXT');
- if not Assigned(glVariantPointerEXT) then Exit;
- @glEnableVariantClientStateEXT := SDL_GL_GetProcAddress('glEnableVariantClientStateEXT');
- if not Assigned(glEnableVariantClientStateEXT) then Exit;
- @glDisableVariantClientStateEXT := SDL_GL_GetProcAddress('glDisableVariantClientStateEXT');
- if not Assigned(glDisableVariantClientStateEXT) then Exit;
- @glBindLightParameterEXT := SDL_GL_GetProcAddress('glBindLightParameterEXT');
- if not Assigned(glBindLightParameterEXT) then Exit;
- @glBindMaterialParameterEXT := SDL_GL_GetProcAddress('glBindMaterialParameterEXT');
- if not Assigned(glBindMaterialParameterEXT) then Exit;
- @glBindTexGenParameterEXT := SDL_GL_GetProcAddress('glBindTexGenParameterEXT');
- if not Assigned(glBindTexGenParameterEXT) then Exit;
- @glBindTextureUnitParameterEXT := SDL_GL_GetProcAddress('glBindTextureUnitParameterEXT');
- if not Assigned(glBindTextureUnitParameterEXT) then Exit;
- @glBindParameterEXT := SDL_GL_GetProcAddress('glBindParameterEXT');
- if not Assigned(glBindParameterEXT) then Exit;
- @glIsVariantEnabledEXT := SDL_GL_GetProcAddress('glIsVariantEnabledEXT');
- if not Assigned(glIsVariantEnabledEXT) then Exit;
- @glGetVariantBooleanvEXT := SDL_GL_GetProcAddress('glGetVariantBooleanvEXT');
- if not Assigned(glGetVariantBooleanvEXT) then Exit;
- @glGetVariantIntegervEXT := SDL_GL_GetProcAddress('glGetVariantIntegervEXT');
- if not Assigned(glGetVariantIntegervEXT) then Exit;
- @glGetVariantFloatvEXT := SDL_GL_GetProcAddress('glGetVariantFloatvEXT');
- if not Assigned(glGetVariantFloatvEXT) then Exit;
- @glGetVariantPointervEXT := SDL_GL_GetProcAddress('glGetVariantPointervEXT');
- if not Assigned(glGetVariantPointervEXT) then Exit;
- @glGetInvariantBooleanvEXT := SDL_GL_GetProcAddress('glGetInvariantBooleanvEXT');
- if not Assigned(glGetInvariantBooleanvEXT) then Exit;
- @glGetInvariantIntegervEXT := SDL_GL_GetProcAddress('glGetInvariantIntegervEXT');
- if not Assigned(glGetInvariantIntegervEXT) then Exit;
- @glGetInvariantFloatvEXT := SDL_GL_GetProcAddress('glGetInvariantFloatvEXT');
- if not Assigned(glGetInvariantFloatvEXT) then Exit;
- @glGetLocalConstantBooleanvEXT := SDL_GL_GetProcAddress('glGetLocalConstantBooleanvEXT');
- if not Assigned(glGetLocalConstantBooleanvEXT) then Exit;
- @glGetLocalConstantIntegervEXT := SDL_GL_GetProcAddress('glGetLocalConstantIntegervEXT');
- if not Assigned(glGetLocalConstantIntegervEXT) then Exit;
- @glGetLocalConstantFloatvEXT := SDL_GL_GetProcAddress('glGetLocalConstantFloatvEXT');
- if not Assigned(glGetLocalConstantFloatvEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_vertex_weighting: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_vertex_weighting', extstring) then
- begin
- @glVertexWeightfEXT := SDL_GL_GetProcAddress('glVertexWeightfEXT');
- if not Assigned(glVertexWeightfEXT) then Exit;
- @glVertexWeightfvEXT := SDL_GL_GetProcAddress('glVertexWeightfvEXT');
- if not Assigned(glVertexWeightfvEXT) then Exit;
- @glVertexWeightPointerEXT := SDL_GL_GetProcAddress('glVertexWeightPointerEXT');
- if not Assigned(glVertexWeightPointerEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_HP_occlusion_test: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_HP_occlusion_test', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_blend_square: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_blend_square', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_copy_depth_to_color: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_copy_depth_to_color', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_depth_clamp: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_depth_clamp', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_evaluators: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_evaluators', extstring) then
- begin
- @glMapControlPointsNV := SDL_GL_GetProcAddress('glMapControlPointsNV');
- if not Assigned(glMapControlPointsNV) then Exit;
- @glMapParameterivNV := SDL_GL_GetProcAddress('glMapParameterivNV');
- if not Assigned(glMapParameterivNV) then Exit;
- @glMapParameterfvNV := SDL_GL_GetProcAddress('glMapParameterfvNV');
- if not Assigned(glMapParameterfvNV) then Exit;
- @glGetMapControlPointsNV := SDL_GL_GetProcAddress('glGetMapControlPointsNV');
- if not Assigned(glGetMapControlPointsNV) then Exit;
- @glGetMapParameterivNV := SDL_GL_GetProcAddress('glGetMapParameterivNV');
- if not Assigned(glGetMapParameterivNV) then Exit;
- @glGetMapParameterfvNV := SDL_GL_GetProcAddress('glGetMapParameterfvNV');
- if not Assigned(glGetMapParameterfvNV) then Exit;
- @glGetMapAttribParameterivNV := SDL_GL_GetProcAddress('glGetMapAttribParameterivNV');
- if not Assigned(glGetMapAttribParameterivNV) then Exit;
- @glGetMapAttribParameterfvNV := SDL_GL_GetProcAddress('glGetMapAttribParameterfvNV');
- if not Assigned(glGetMapAttribParameterfvNV) then Exit;
- @glEvalMapsNV := SDL_GL_GetProcAddress('glEvalMapsNV');
- if not Assigned(glEvalMapsNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_fence: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_fence', extstring) then
- begin
- @glGenFencesNV := SDL_GL_GetProcAddress('glGenFencesNV');
- if not Assigned(glGenFencesNV) then Exit;
- @glDeleteFencesNV := SDL_GL_GetProcAddress('glDeleteFencesNV');
- if not Assigned(glDeleteFencesNV) then Exit;
- @glSetFenceNV := SDL_GL_GetProcAddress('glSetFenceNV');
- if not Assigned(glSetFenceNV) then Exit;
- @glTestFenceNV := SDL_GL_GetProcAddress('glTestFenceNV');
- if not Assigned(glTestFenceNV) then Exit;
- @glFinishFenceNV := SDL_GL_GetProcAddress('glFinishFenceNV');
- if not Assigned(glFinishFenceNV) then Exit;
- @glIsFenceNV := SDL_GL_GetProcAddress('glIsFenceNV');
- if not Assigned(glIsFenceNV) then Exit;
- @glGetFenceivNV := SDL_GL_GetProcAddress('glGetFenceivNV');
- if not Assigned(glGetFenceivNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_fog_distance: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_fog_distance', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_light_max_exponent: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_light_max_exponent', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_multisample_filter_hint: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_multisample_filter_hint', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_occlusion_query: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_occlusion_query', extstring) then
- begin
- @glGenOcclusionQueriesNV := SDL_GL_GetProcAddress('glGenOcclusionQueriesNV');
- if not Assigned(glGenOcclusionQueriesNV) then Exit;
- @glDeleteOcclusionQueriesNV := SDL_GL_GetProcAddress('glDeleteOcclusionQueriesNV');
- if not Assigned(glDeleteOcclusionQueriesNV) then Exit;
- @glIsOcclusionQueryNV := SDL_GL_GetProcAddress('glIsOcclusionQueryNV');
- if not Assigned(glIsOcclusionQueryNV) then Exit;
- @glBeginOcclusionQueryNV := SDL_GL_GetProcAddress('glBeginOcclusionQueryNV');
- if not Assigned(glBeginOcclusionQueryNV) then Exit;
- @glEndOcclusionQueryNV := SDL_GL_GetProcAddress('glEndOcclusionQueryNV');
- if not Assigned(glEndOcclusionQueryNV) then Exit;
- @glGetOcclusionQueryivNV := SDL_GL_GetProcAddress('glGetOcclusionQueryivNV');
- if not Assigned(glGetOcclusionQueryivNV) then Exit;
- @glGetOcclusionQueryuivNV := SDL_GL_GetProcAddress('glGetOcclusionQueryuivNV');
- if not Assigned(glGetOcclusionQueryuivNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_packed_depth_stencil: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_packed_depth_stencil', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_point_sprite: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_point_sprite', extstring) then
- begin
- @glPointParameteriNV := SDL_GL_GetProcAddress('glPointParameteriNV');
- if not Assigned(glPointParameteriNV) then Exit;
- @glPointParameterivNV := SDL_GL_GetProcAddress('glPointParameterivNV');
- if not Assigned(glPointParameterivNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_register_combiners: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_register_combiners', extstring) then
- begin
- @glCombinerParameterfvNV := SDL_GL_GetProcAddress('glCombinerParameterfvNV');
- if not Assigned(glCombinerParameterfvNV) then Exit;
- @glCombinerParameterivNV := SDL_GL_GetProcAddress('glCombinerParameterivNV');
- if not Assigned(glCombinerParameterivNV) then Exit;
- @glCombinerParameterfNV := SDL_GL_GetProcAddress('glCombinerParameterfNV');
- if not Assigned(glCombinerParameterfNV) then Exit;
- @glCombinerParameteriNV := SDL_GL_GetProcAddress('glCombinerParameteriNV');
- if not Assigned(glCombinerParameteriNV) then Exit;
- @glCombinerInputNV := SDL_GL_GetProcAddress('glCombinerInputNV');
- if not Assigned(glCombinerInputNV) then Exit;
- @glCombinerOutputNV := SDL_GL_GetProcAddress('glCombinerOutputNV');
- if not Assigned(glCombinerOutputNV) then Exit;
- @glFinalCombinerInputNV := SDL_GL_GetProcAddress('glFinalCombinerInputNV');
- if not Assigned(glFinalCombinerInputNV) then Exit;
- @glGetCombinerInputParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerInputParameterfvNV');
- if not Assigned(glGetCombinerInputParameterfvNV) then Exit;
- @glGetCombinerInputParameterivNV := SDL_GL_GetProcAddress('glGetCombinerInputParameterivNV');
- if not Assigned(glGetCombinerInputParameterivNV) then Exit;
- @glGetCombinerOutputParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerOutputParameterfvNV');
- if not Assigned(glGetCombinerOutputParameterfvNV) then Exit;
- @glGetCombinerOutputParameterivNV := SDL_GL_GetProcAddress('glGetCombinerOutputParameterivNV');
- if not Assigned(glGetCombinerOutputParameterivNV) then Exit;
- @glGetFinalCombinerInputParameterfvNV := SDL_GL_GetProcAddress('glGetFinalCombinerInputParameterfvNV');
- if not Assigned(glGetFinalCombinerInputParameterfvNV) then Exit;
- @glGetFinalCombinerInputParameterivNV := SDL_GL_GetProcAddress('glGetFinalCombinerInputParameterivNV');
- if not Assigned(glGetFinalCombinerInputParameterivNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_register_combiners2: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_register_combiners2', extstring) then
- begin
- @glCombinerStageParameterfvNV := SDL_GL_GetProcAddress('glCombinerStageParameterfvNV');
- if not Assigned(glCombinerStageParameterfvNV) then Exit;
- @glGetCombinerStageParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerStageParameterfvNV');
- if not Assigned(glGetCombinerStageParameterfvNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texgen_emboss: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texgen_emboss', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texgen_reflection: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texgen_reflection', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_compression_vtc: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_compression_vtc', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_env_combine4: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_env_combine4', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_rectangle: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_rectangle', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_shader', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_shader2: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_shader2', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_shader3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_shader3', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_array_range: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_array_range', extstring) then
- begin
- @glVertexArrayRangeNV := SDL_GL_GetProcAddress('glVertexArrayRangeNV');
- if not Assigned(glVertexArrayRangeNV) then Exit;
- @glFlushVertexArrayRangeNV := SDL_GL_GetProcAddress('glFlushVertexArrayRangeNV');
- if not Assigned(glFlushVertexArrayRangeNV) then Exit;
- {$IFDEF WINDOWS}
- @wglAllocateMemoryNV := SDL_GL_GetProcAddress('wglAllocateMemoryNV');
- if not Assigned(wglAllocateMemoryNV) then Exit;
- @wglFreeMemoryNV := SDL_GL_GetProcAddress('wglFreeMemoryNV');
- if not Assigned(wglFreeMemoryNV) then Exit;
- {$ENDIF}
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_array_range2: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_array_range2', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_program: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_program', extstring) then
- begin
- @glBindProgramNV := SDL_GL_GetProcAddress('glBindProgramNV');
- if not Assigned(glBindProgramNV) then Exit;
- @glDeleteProgramsNV := SDL_GL_GetProcAddress('glDeleteProgramsNV');
- if not Assigned(glDeleteProgramsNV) then Exit;
- @glExecuteProgramNV := SDL_GL_GetProcAddress('glExecuteProgramNV');
- if not Assigned(glExecuteProgramNV) then Exit;
- @glGenProgramsNV := SDL_GL_GetProcAddress('glGenProgramsNV');
- if not Assigned(glGenProgramsNV) then Exit;
- @glAreProgramsResidentNV := SDL_GL_GetProcAddress('glAreProgramsResidentNV');
- if not Assigned(glAreProgramsResidentNV) then Exit;
- @glRequestResidentProgramsNV := SDL_GL_GetProcAddress('glRequestResidentProgramsNV');
- if not Assigned(glRequestResidentProgramsNV) then Exit;
- @glGetProgramParameterfvNV := SDL_GL_GetProcAddress('glGetProgramParameterfvNV');
- if not Assigned(glGetProgramParameterfvNV) then Exit;
- @glGetProgramParameterdvNV := SDL_GL_GetProcAddress('glGetProgramParameterdvNV');
- if not Assigned(glGetProgramParameterdvNV) then Exit;
- @glGetProgramivNV := SDL_GL_GetProcAddress('glGetProgramivNV');
- if not Assigned(glGetProgramivNV) then Exit;
- @glGetProgramStringNV := SDL_GL_GetProcAddress('glGetProgramStringNV');
- if not Assigned(glGetProgramStringNV) then Exit;
- @glGetTrackMatrixivNV := SDL_GL_GetProcAddress('glGetTrackMatrixivNV');
- if not Assigned(glGetTrackMatrixivNV) then Exit;
- @glGetVertexAttribdvNV := SDL_GL_GetProcAddress('glGetVertexAttribdvNV');
- if not Assigned(glGetVertexAttribdvNV) then Exit;
- @glGetVertexAttribfvNV := SDL_GL_GetProcAddress('glGetVertexAttribfvNV');
- if not Assigned(glGetVertexAttribfvNV) then Exit;
- @glGetVertexAttribivNV := SDL_GL_GetProcAddress('glGetVertexAttribivNV');
- if not Assigned(glGetVertexAttribivNV) then Exit;
- @glGetVertexAttribPointervNV := SDL_GL_GetProcAddress('glGetVertexAttribPointervNV');
- if not Assigned(glGetVertexAttribPointervNV) then Exit;
- @glIsProgramNV := SDL_GL_GetProcAddress('glIsProgramNV');
- if not Assigned(glIsProgramNV) then Exit;
- @glLoadProgramNV := SDL_GL_GetProcAddress('glLoadProgramNV');
- if not Assigned(glLoadProgramNV) then Exit;
- @glProgramParameter4fNV := SDL_GL_GetProcAddress('glProgramParameter4fNV');
- if not Assigned(glProgramParameter4fNV) then Exit;
- @glProgramParameter4fvNV := SDL_GL_GetProcAddress('glProgramParameter4fvNV');
- if not Assigned(glProgramParameter4fvNV) then Exit;
- @glProgramParameters4dvNV := SDL_GL_GetProcAddress('glProgramParameters4dvNV');
- if not Assigned(glProgramParameters4dvNV) then Exit;
- @glProgramParameters4fvNV := SDL_GL_GetProcAddress('glProgramParameters4fvNV');
- if not Assigned(glProgramParameters4fvNV) then Exit;
- @glTrackMatrixNV := SDL_GL_GetProcAddress('glTrackMatrixNV');
- if not Assigned(glTrackMatrixNV) then Exit;
- @glVertexAttribPointerNV := SDL_GL_GetProcAddress('glVertexAttribPointerNV');
- if not Assigned(glVertexAttribPointerNV) then Exit;
- @glVertexAttrib1sNV := SDL_GL_GetProcAddress('glVertexAttrib1sNV');
- if not Assigned(glVertexAttrib1sNV) then Exit;
- @glVertexAttrib1fNV := SDL_GL_GetProcAddress('glVertexAttrib1fNV');
- if not Assigned(glVertexAttrib1fNV) then Exit;
- @glVertexAttrib1dNV := SDL_GL_GetProcAddress('glVertexAttrib1dNV');
- if not Assigned(glVertexAttrib1dNV) then Exit;
- @glVertexAttrib2sNV := SDL_GL_GetProcAddress('glVertexAttrib2sNV');
- if not Assigned(glVertexAttrib2sNV) then Exit;
- @glVertexAttrib2fNV := SDL_GL_GetProcAddress('glVertexAttrib2fNV');
- if not Assigned(glVertexAttrib2fNV) then Exit;
- @glVertexAttrib2dNV := SDL_GL_GetProcAddress('glVertexAttrib2dNV');
- if not Assigned(glVertexAttrib2dNV) then Exit;
- @glVertexAttrib3sNV := SDL_GL_GetProcAddress('glVertexAttrib3sNV');
- if not Assigned(glVertexAttrib3sNV) then Exit;
- @glVertexAttrib3fNV := SDL_GL_GetProcAddress('glVertexAttrib3fNV');
- if not Assigned(glVertexAttrib3fNV) then Exit;
- @glVertexAttrib3dNV := SDL_GL_GetProcAddress('glVertexAttrib3dNV');
- if not Assigned(glVertexAttrib3dNV) then Exit;
- @glVertexAttrib4sNV := SDL_GL_GetProcAddress('glVertexAttrib4sNV');
- if not Assigned(glVertexAttrib4sNV) then Exit;
- @glVertexAttrib4fNV := SDL_GL_GetProcAddress('glVertexAttrib4fNV');
- if not Assigned(glVertexAttrib4fNV) then Exit;
- @glVertexAttrib4dNV := SDL_GL_GetProcAddress('glVertexAttrib4dNV');
- if not Assigned(glVertexAttrib4dNV) then Exit;
- @glVertexAttrib4ubNV := SDL_GL_GetProcAddress('glVertexAttrib4ubNV');
- if not Assigned(glVertexAttrib4ubNV) then Exit;
- @glVertexAttrib1svNV := SDL_GL_GetProcAddress('glVertexAttrib1svNV');
- if not Assigned(glVertexAttrib1svNV) then Exit;
- @glVertexAttrib1fvNV := SDL_GL_GetProcAddress('glVertexAttrib1fvNV');
- if not Assigned(glVertexAttrib1fvNV) then Exit;
- @glVertexAttrib1dvNV := SDL_GL_GetProcAddress('glVertexAttrib1dvNV');
- if not Assigned(glVertexAttrib1dvNV) then Exit;
- @glVertexAttrib2svNV := SDL_GL_GetProcAddress('glVertexAttrib2svNV');
- if not Assigned(glVertexAttrib2svNV) then Exit;
- @glVertexAttrib2fvNV := SDL_GL_GetProcAddress('glVertexAttrib2fvNV');
- if not Assigned(glVertexAttrib2fvNV) then Exit;
- @glVertexAttrib2dvNV := SDL_GL_GetProcAddress('glVertexAttrib2dvNV');
- if not Assigned(glVertexAttrib2dvNV) then Exit;
- @glVertexAttrib3svNV := SDL_GL_GetProcAddress('glVertexAttrib3svNV');
- if not Assigned(glVertexAttrib3svNV) then Exit;
- @glVertexAttrib3fvNV := SDL_GL_GetProcAddress('glVertexAttrib3fvNV');
- if not Assigned(glVertexAttrib3fvNV) then Exit;
- @glVertexAttrib3dvNV := SDL_GL_GetProcAddress('glVertexAttrib3dvNV');
- if not Assigned(glVertexAttrib3dvNV) then Exit;
- @glVertexAttrib4svNV := SDL_GL_GetProcAddress('glVertexAttrib4svNV');
- if not Assigned(glVertexAttrib4svNV) then Exit;
- @glVertexAttrib4fvNV := SDL_GL_GetProcAddress('glVertexAttrib4fvNV');
- if not Assigned(glVertexAttrib4fvNV) then Exit;
- @glVertexAttrib4dvNV := SDL_GL_GetProcAddress('glVertexAttrib4dvNV');
- if not Assigned(glVertexAttrib4dvNV) then Exit;
- @glVertexAttrib4ubvNV := SDL_GL_GetProcAddress('glVertexAttrib4ubvNV');
- if not Assigned(glVertexAttrib4ubvNV) then Exit;
- @glVertexAttribs1svNV := SDL_GL_GetProcAddress('glVertexAttribs1svNV');
- if not Assigned(glVertexAttribs1svNV) then Exit;
- @glVertexAttribs1fvNV := SDL_GL_GetProcAddress('glVertexAttribs1fvNV');
- if not Assigned(glVertexAttribs1fvNV) then Exit;
- @glVertexAttribs1dvNV := SDL_GL_GetProcAddress('glVertexAttribs1dvNV');
- if not Assigned(glVertexAttribs1dvNV) then Exit;
- @glVertexAttribs2svNV := SDL_GL_GetProcAddress('glVertexAttribs2svNV');
- if not Assigned(glVertexAttribs2svNV) then Exit;
- @glVertexAttribs2fvNV := SDL_GL_GetProcAddress('glVertexAttribs2fvNV');
- if not Assigned(glVertexAttribs2fvNV) then Exit;
- @glVertexAttribs2dvNV := SDL_GL_GetProcAddress('glVertexAttribs2dvNV');
- if not Assigned(glVertexAttribs2dvNV) then Exit;
- @glVertexAttribs3svNV := SDL_GL_GetProcAddress('glVertexAttribs3svNV');
- if not Assigned(glVertexAttribs3svNV) then Exit;
- @glVertexAttribs3fvNV := SDL_GL_GetProcAddress('glVertexAttribs3fvNV');
- if not Assigned(glVertexAttribs3fvNV) then Exit;
- @glVertexAttribs3dvNV := SDL_GL_GetProcAddress('glVertexAttribs3dvNV');
- if not Assigned(glVertexAttribs3dvNV) then Exit;
- @glVertexAttribs4svNV := SDL_GL_GetProcAddress('glVertexAttribs4svNV');
- if not Assigned(glVertexAttribs4svNV) then Exit;
- @glVertexAttribs4fvNV := SDL_GL_GetProcAddress('glVertexAttribs4fvNV');
- if not Assigned(glVertexAttribs4fvNV) then Exit;
- @glVertexAttribs4dvNV := SDL_GL_GetProcAddress('glVertexAttribs4dvNV');
- if not Assigned(glVertexAttribs4dvNV) then Exit;
- @glVertexAttribs4ubvNV := SDL_GL_GetProcAddress('glVertexAttribs4ubvNV');
- if not Assigned(glVertexAttribs4ubvNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_program1_1: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_program1_1', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_element_array: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_element_array', extstring) then
- begin
- @glElementPointerATI := SDL_GL_GetProcAddress('glElementPointerATI');
- if not Assigned(glElementPointerATI) then Exit;
- @glDrawElementArrayATI := SDL_GL_GetProcAddress('glDrawElementArrayATI');
- if not Assigned(glDrawElementArrayATI) then Exit;
- @glDrawRangeElementArrayATI := SDL_GL_GetProcAddress('glDrawRangeElementArrayATI');
- if not Assigned(glDrawRangeElementArrayATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_envmap_bumpmap: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_envmap_bumpmap', extstring) then
- begin
- @glTexBumpParameterivATI := SDL_GL_GetProcAddress('glTexBumpParameterivATI');
- if not Assigned(glTexBumpParameterivATI) then Exit;
- @glTexBumpParameterfvATI := SDL_GL_GetProcAddress('glTexBumpParameterfvATI');
- if not Assigned(glTexBumpParameterfvATI) then Exit;
- @glGetTexBumpParameterivATI := SDL_GL_GetProcAddress('glGetTexBumpParameterivATI');
- if not Assigned(glGetTexBumpParameterivATI) then Exit;
- @glGetTexBumpParameterfvATI := SDL_GL_GetProcAddress('glGetTexBumpParameterfvATI');
- if not Assigned(glGetTexBumpParameterfvATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_fragment_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_fragment_shader', extstring) then
- begin
- @glGenFragmentShadersATI := SDL_GL_GetProcAddress('glGenFragmentShadersATI');
- if not Assigned(glGenFragmentShadersATI) then Exit;
- @glBindFragmentShaderATI := SDL_GL_GetProcAddress('glBindFragmentShaderATI');
- if not Assigned(glBindFragmentShaderATI) then Exit;
- @glDeleteFragmentShaderATI := SDL_GL_GetProcAddress('glDeleteFragmentShaderATI');
- if not Assigned(glDeleteFragmentShaderATI) then Exit;
- @glBeginFragmentShaderATI := SDL_GL_GetProcAddress('glBeginFragmentShaderATI');
- if not Assigned(glBeginFragmentShaderATI) then Exit;
- @glEndFragmentShaderATI := SDL_GL_GetProcAddress('glEndFragmentShaderATI');
- if not Assigned(glEndFragmentShaderATI) then Exit;
- @glPassTexCoordATI := SDL_GL_GetProcAddress('glPassTexCoordATI');
- if not Assigned(glPassTexCoordATI) then Exit;
- @glSampleMapATI := SDL_GL_GetProcAddress('glSampleMapATI');
- if not Assigned(glSampleMapATI) then Exit;
- @glColorFragmentOp1ATI := SDL_GL_GetProcAddress('glColorFragmentOp1ATI');
- if not Assigned(glColorFragmentOp1ATI) then Exit;
- @glColorFragmentOp2ATI := SDL_GL_GetProcAddress('glColorFragmentOp2ATI');
- if not Assigned(glColorFragmentOp2ATI) then Exit;
- @glColorFragmentOp3ATI := SDL_GL_GetProcAddress('glColorFragmentOp3ATI');
- if not Assigned(glColorFragmentOp3ATI) then Exit;
- @glAlphaFragmentOp1ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp1ATI');
- if not Assigned(glAlphaFragmentOp1ATI) then Exit;
- @glAlphaFragmentOp2ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp2ATI');
- if not Assigned(glAlphaFragmentOp2ATI) then Exit;
- @glAlphaFragmentOp3ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp3ATI');
- if not Assigned(glAlphaFragmentOp3ATI) then Exit;
- @glSetFragmentShaderConstantATI := SDL_GL_GetProcAddress('glSetFragmentShaderConstantATI');
- if not Assigned(glSetFragmentShaderConstantATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_pn_triangles: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_pn_triangles', extstring) then
- begin
- @glPNTrianglesiATI := SDL_GL_GetProcAddress('glPNTrianglesiATI');
- if not Assigned(glPNTrianglesiATI) then Exit;
- @glPNTrianglesfATI := SDL_GL_GetProcAddress('glPNTrianglesfATI');
- if not Assigned(glPNTrianglesfATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_texture_mirror_once: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_texture_mirror_once', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_vertex_array_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_vertex_array_object', extstring) then
- begin
- @glNewObjectBufferATI := SDL_GL_GetProcAddress('glNewObjectBufferATI');
- if not Assigned(glNewObjectBufferATI) then Exit;
- @glIsObjectBufferATI := SDL_GL_GetProcAddress('glIsObjectBufferATI');
- if not Assigned(glIsObjectBufferATI) then Exit;
- @glUpdateObjectBufferATI := SDL_GL_GetProcAddress('glUpdateObjectBufferATI');
- if not Assigned(glUpdateObjectBufferATI) then Exit;
- @glGetObjectBufferfvATI := SDL_GL_GetProcAddress('glGetObjectBufferfvATI');
- if not Assigned(glGetObjectBufferfvATI) then Exit;
- @glGetObjectBufferivATI := SDL_GL_GetProcAddress('glGetObjectBufferivATI');
- if not Assigned(glGetObjectBufferivATI) then Exit;
- @glDeleteObjectBufferATI := SDL_GL_GetProcAddress('glDeleteObjectBufferATI');
- if not Assigned(glDeleteObjectBufferATI) then Exit;
- @glArrayObjectATI := SDL_GL_GetProcAddress('glArrayObjectATI');
- if not Assigned(glArrayObjectATI) then Exit;
- @glGetArrayObjectfvATI := SDL_GL_GetProcAddress('glGetArrayObjectfvATI');
- if not Assigned(glGetArrayObjectfvATI) then Exit;
- @glGetArrayObjectivATI := SDL_GL_GetProcAddress('glGetArrayObjectivATI');
- if not Assigned(glGetArrayObjectivATI) then Exit;
- @glVariantArrayObjectATI := SDL_GL_GetProcAddress('glVariantArrayObjectATI');
- if not Assigned(glVariantArrayObjectATI) then Exit;
- @glGetVariantArrayObjectfvATI := SDL_GL_GetProcAddress('glGetVariantArrayObjectfvATI');
- if not Assigned(glGetVariantArrayObjectfvATI) then Exit;
- @glGetVariantArrayObjectivATI := SDL_GL_GetProcAddress('glGetVariantArrayObjectivATI');
- if not Assigned(glGetVariantArrayObjectivATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_vertex_streams: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_vertex_streams', extstring) then
- begin
- @glVertexStream1s := SDL_GL_GetProcAddress('glVertexStream1s');
- if not Assigned(glVertexStream1s) then Exit;
- @glVertexStream1i := SDL_GL_GetProcAddress('glVertexStream1i');
- if not Assigned(glVertexStream1i) then Exit;
- @glVertexStream1f := SDL_GL_GetProcAddress('glVertexStream1f');
- if not Assigned(glVertexStream1f) then Exit;
- @glVertexStream1d := SDL_GL_GetProcAddress('glVertexStream1d');
- if not Assigned(glVertexStream1d) then Exit;
- @glVertexStream1sv := SDL_GL_GetProcAddress('glVertexStream1sv');
- if not Assigned(glVertexStream1sv) then Exit;
- @glVertexStream1iv := SDL_GL_GetProcAddress('glVertexStream1iv');
- if not Assigned(glVertexStream1iv) then Exit;
- @glVertexStream1fv := SDL_GL_GetProcAddress('glVertexStream1fv');
- if not Assigned(glVertexStream1fv) then Exit;
- @glVertexStream1dv := SDL_GL_GetProcAddress('glVertexStream1dv');
- if not Assigned(glVertexStream1dv) then Exit;
- @glVertexStream2s := SDL_GL_GetProcAddress('glVertexStream2s');
- if not Assigned(glVertexStream2s) then Exit;
- @glVertexStream2i := SDL_GL_GetProcAddress('glVertexStream2i');
- if not Assigned(glVertexStream2i) then Exit;
- @glVertexStream2f := SDL_GL_GetProcAddress('glVertexStream2f');
- if not Assigned(glVertexStream2f) then Exit;
- @glVertexStream2d := SDL_GL_GetProcAddress('glVertexStream2d');
- if not Assigned(glVertexStream2d) then Exit;
- @glVertexStream2sv := SDL_GL_GetProcAddress('glVertexStream2sv');
- if not Assigned(glVertexStream2sv) then Exit;
- @glVertexStream2iv := SDL_GL_GetProcAddress('glVertexStream2iv');
- if not Assigned(glVertexStream2iv) then Exit;
- @glVertexStream2fv := SDL_GL_GetProcAddress('glVertexStream2fv');
- if not Assigned(glVertexStream2fv) then Exit;
- @glVertexStream2dv := SDL_GL_GetProcAddress('glVertexStream2dv');
- if not Assigned(glVertexStream2dv) then Exit;
- @glVertexStream3s := SDL_GL_GetProcAddress('glVertexStream3s');
- if not Assigned(glVertexStream3s) then Exit;
- @glVertexStream3i := SDL_GL_GetProcAddress('glVertexStream3i');
- if not Assigned(glVertexStream3i) then Exit;
- @glVertexStream3f := SDL_GL_GetProcAddress('glVertexStream3f');
- if not Assigned(glVertexStream3f) then Exit;
- @glVertexStream3d := SDL_GL_GetProcAddress('glVertexStream3d');
- if not Assigned(glVertexStream3d) then Exit;
- @glVertexStream3sv := SDL_GL_GetProcAddress('glVertexStream3sv');
- if not Assigned(glVertexStream3sv) then Exit;
- @glVertexStream3iv := SDL_GL_GetProcAddress('glVertexStream3iv');
- if not Assigned(glVertexStream3iv) then Exit;
- @glVertexStream3fv := SDL_GL_GetProcAddress('glVertexStream3fv');
- if not Assigned(glVertexStream3fv) then Exit;
- @glVertexStream3dv := SDL_GL_GetProcAddress('glVertexStream3dv');
- if not Assigned(glVertexStream3dv) then Exit;
- @glVertexStream4s := SDL_GL_GetProcAddress('glVertexStream4s');
- if not Assigned(glVertexStream4s) then Exit;
- @glVertexStream4i := SDL_GL_GetProcAddress('glVertexStream4i');
- if not Assigned(glVertexStream4i) then Exit;
- @glVertexStream4f := SDL_GL_GetProcAddress('glVertexStream4f');
- if not Assigned(glVertexStream4f) then Exit;
- @glVertexStream4d := SDL_GL_GetProcAddress('glVertexStream4d');
- if not Assigned(glVertexStream4d) then Exit;
- @glVertexStream4sv := SDL_GL_GetProcAddress('glVertexStream4sv');
- if not Assigned(glVertexStream4sv) then Exit;
- @glVertexStream4iv := SDL_GL_GetProcAddress('glVertexStream4iv');
- if not Assigned(glVertexStream4iv) then Exit;
- @glVertexStream4fv := SDL_GL_GetProcAddress('glVertexStream4fv');
- if not Assigned(glVertexStream4fv) then Exit;
- @glVertexStream4dv := SDL_GL_GetProcAddress('glVertexStream4dv');
- if not Assigned(glVertexStream4dv) then Exit;
- @glNormalStream3b := SDL_GL_GetProcAddress('glNormalStream3b');
- if not Assigned(glNormalStream3b) then Exit;
- @glNormalStream3s := SDL_GL_GetProcAddress('glNormalStream3s');
- if not Assigned(glNormalStream3s) then Exit;
- @glNormalStream3i := SDL_GL_GetProcAddress('glNormalStream3i');
- if not Assigned(glNormalStream3i) then Exit;
- @glNormalStream3f := SDL_GL_GetProcAddress('glNormalStream3f');
- if not Assigned(glNormalStream3f) then Exit;
- @glNormalStream3d := SDL_GL_GetProcAddress('glNormalStream3d');
- if not Assigned(glNormalStream3d) then Exit;
- @glNormalStream3bv := SDL_GL_GetProcAddress('glNormalStream3bv');
- if not Assigned(glNormalStream3bv) then Exit;
- @glNormalStream3sv := SDL_GL_GetProcAddress('glNormalStream3sv');
- if not Assigned(glNormalStream3sv) then Exit;
- @glNormalStream3iv := SDL_GL_GetProcAddress('glNormalStream3iv');
- if not Assigned(glNormalStream3iv) then Exit;
- @glNormalStream3fv := SDL_GL_GetProcAddress('glNormalStream3fv');
- if not Assigned(glNormalStream3fv) then Exit;
- @glNormalStream3dv := SDL_GL_GetProcAddress('glNormalStream3dv');
- if not Assigned(glNormalStream3dv) then Exit;
- @glClientActiveVertexStream := SDL_GL_GetProcAddress('glClientActiveVertexStream');
- if not Assigned(glClientActiveVertexStream) then Exit;
- @glVertexBlendEnvi := SDL_GL_GetProcAddress('glVertexBlendEnvi');
- if not Assigned(glVertexBlendEnvi) then Exit;
- @glVertexBlendEnvf := SDL_GL_GetProcAddress('glVertexBlendEnvf');
- if not Assigned(glVertexBlendEnvf) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-{$IFDEF WINDOWS}
-function Load_WGL_I3D_image_buffer: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_image_buffer', extstring) then
- begin
- @wglCreateImageBufferI3D := SDL_GL_GetProcAddress('wglCreateImageBufferI3D');
- if not Assigned(wglCreateImageBufferI3D) then Exit;
- @wglDestroyImageBufferI3D := SDL_GL_GetProcAddress('wglDestroyImageBufferI3D');
- if not Assigned(wglDestroyImageBufferI3D) then Exit;
- @wglAssociateImageBufferEventsI3D := SDL_GL_GetProcAddress('wglAssociateImageBufferEventsI3D');
- if not Assigned(wglAssociateImageBufferEventsI3D) then Exit;
- @wglReleaseImageBufferEventsI3D := SDL_GL_GetProcAddress('wglReleaseImageBufferEventsI3D');
- if not Assigned(wglReleaseImageBufferEventsI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_I3D_swap_frame_lock: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_swap_frame_lock', extstring) then
- begin
- @wglEnableFrameLockI3D := SDL_GL_GetProcAddress('wglEnableFrameLockI3D');
- if not Assigned(wglEnableFrameLockI3D) then Exit;
- @wglDisableFrameLockI3D := SDL_GL_GetProcAddress('wglDisableFrameLockI3D');
- if not Assigned(wglDisableFrameLockI3D) then Exit;
- @wglIsEnabledFrameLockI3D := SDL_GL_GetProcAddress('wglIsEnabledFrameLockI3D');
- if not Assigned(wglIsEnabledFrameLockI3D) then Exit;
- @wglQueryFrameLockMasterI3D := SDL_GL_GetProcAddress('wglQueryFrameLockMasterI3D');
- if not Assigned(wglQueryFrameLockMasterI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_I3D_swap_frame_usage: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_swap_frame_usage', extstring) then
- begin
- @wglGetFrameUsageI3D := SDL_GL_GetProcAddress('wglGetFrameUsageI3D');
- if not Assigned(wglGetFrameUsageI3D) then Exit;
- @wglBeginFrameTrackingI3D := SDL_GL_GetProcAddress('wglBeginFrameTrackingI3D');
- if not Assigned(wglBeginFrameTrackingI3D) then Exit;
- @wglEndFrameTrackingI3D := SDL_GL_GetProcAddress('wglEndFrameTrackingI3D');
- if not Assigned(wglEndFrameTrackingI3D) then Exit;
- @wglQueryFrameTrackingI3D := SDL_GL_GetProcAddress('wglQueryFrameTrackingI3D');
- if not Assigned(wglQueryFrameTrackingI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-{$ENDIF}
-
-function Load_GL_3DFX_texture_compression_FXT1: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_3DFX_texture_compression_FXT1', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_IBM_cull_vertex: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_IBM_cull_vertex', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_IBM_multimode_draw_arrays: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_IBM_multimode_draw_arrays', extstring) then
- begin
- @glMultiModeDrawArraysIBM := SDL_GL_GetProcAddress('glMultiModeDrawArraysIBM');
- if not Assigned(glMultiModeDrawArraysIBM) then Exit;
- @glMultiModeDrawElementsIBM := SDL_GL_GetProcAddress('glMultiModeDrawElementsIBM');
- if not Assigned(glMultiModeDrawElementsIBM) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_IBM_raster_pos_clip: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_IBM_raster_pos_clip', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_IBM_texture_mirrored_repeat: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_IBM_texture_mirrored_repeat', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_IBM_vertex_array_lists: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_IBM_vertex_array_lists', extstring) then
- begin
- @glColorPointerListIBM := SDL_GL_GetProcAddress('glColorPointerListIBM');
- if not Assigned(glColorPointerListIBM) then Exit;
- @glSecondaryColorPointerListIBM := SDL_GL_GetProcAddress('glSecondaryColorPointerListIBM');
- if not Assigned(glSecondaryColorPointerListIBM) then Exit;
- @glEdgeFlagPointerListIBM := SDL_GL_GetProcAddress('glEdgeFlagPointerListIBM');
- if not Assigned(glEdgeFlagPointerListIBM) then Exit;
- @glFogCoordPointerListIBM := SDL_GL_GetProcAddress('glFogCoordPointerListIBM');
- if not Assigned(glFogCoordPointerListIBM) then Exit;
- @glNormalPointerListIBM := SDL_GL_GetProcAddress('glNormalPointerListIBM');
- if not Assigned(glNormalPointerListIBM) then Exit;
- @glTexCoordPointerListIBM := SDL_GL_GetProcAddress('glTexCoordPointerListIBM');
- if not Assigned(glTexCoordPointerListIBM) then Exit;
- @glVertexPointerListIBM := SDL_GL_GetProcAddress('glVertexPointerListIBM');
- if not Assigned(glVertexPointerListIBM) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_MESA_resize_buffers: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_MESA_resize_buffers', extstring) then
- begin
- @glResizeBuffersMESA := SDL_GL_GetProcAddress('glResizeBuffersMESA');
- if not Assigned(glResizeBuffersMESA) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_MESA_window_pos: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_MESA_window_pos', extstring) then
- begin
- @glWindowPos2dMESA := SDL_GL_GetProcAddress('glWindowPos2dMESA');
- if not Assigned(glWindowPos2dMESA) then Exit;
- @glWindowPos2fMESA := SDL_GL_GetProcAddress('glWindowPos2fMESA');
- if not Assigned(glWindowPos2fMESA) then Exit;
- @glWindowPos2iMESA := SDL_GL_GetProcAddress('glWindowPos2iMESA');
- if not Assigned(glWindowPos2iMESA) then Exit;
- @glWindowPos2sMESA := SDL_GL_GetProcAddress('glWindowPos2sMESA');
- if not Assigned(glWindowPos2sMESA) then Exit;
- @glWindowPos2ivMESA := SDL_GL_GetProcAddress('glWindowPos2ivMESA');
- if not Assigned(glWindowPos2ivMESA) then Exit;
- @glWindowPos2svMESA := SDL_GL_GetProcAddress('glWindowPos2svMESA');
- if not Assigned(glWindowPos2svMESA) then Exit;
- @glWindowPos2fvMESA := SDL_GL_GetProcAddress('glWindowPos2fvMESA');
- if not Assigned(glWindowPos2fvMESA) then Exit;
- @glWindowPos2dvMESA := SDL_GL_GetProcAddress('glWindowPos2dvMESA');
- if not Assigned(glWindowPos2dvMESA) then Exit;
- @glWindowPos3iMESA := SDL_GL_GetProcAddress('glWindowPos3iMESA');
- if not Assigned(glWindowPos3iMESA) then Exit;
- @glWindowPos3sMESA := SDL_GL_GetProcAddress('glWindowPos3sMESA');
- if not Assigned(glWindowPos3sMESA) then Exit;
- @glWindowPos3fMESA := SDL_GL_GetProcAddress('glWindowPos3fMESA');
- if not Assigned(glWindowPos3fMESA) then Exit;
- @glWindowPos3dMESA := SDL_GL_GetProcAddress('glWindowPos3dMESA');
- if not Assigned(glWindowPos3dMESA) then Exit;
- @glWindowPos3ivMESA := SDL_GL_GetProcAddress('glWindowPos3ivMESA');
- if not Assigned(glWindowPos3ivMESA) then Exit;
- @glWindowPos3svMESA := SDL_GL_GetProcAddress('glWindowPos3svMESA');
- if not Assigned(glWindowPos3svMESA) then Exit;
- @glWindowPos3fvMESA := SDL_GL_GetProcAddress('glWindowPos3fvMESA');
- if not Assigned(glWindowPos3fvMESA) then Exit;
- @glWindowPos3dvMESA := SDL_GL_GetProcAddress('glWindowPos3dvMESA');
- if not Assigned(glWindowPos3dvMESA) then Exit;
- @glWindowPos4iMESA := SDL_GL_GetProcAddress('glWindowPos4iMESA');
- if not Assigned(glWindowPos4iMESA) then Exit;
- @glWindowPos4sMESA := SDL_GL_GetProcAddress('glWindowPos4sMESA');
- if not Assigned(glWindowPos4sMESA) then Exit;
- @glWindowPos4fMESA := SDL_GL_GetProcAddress('glWindowPos4fMESA');
- if not Assigned(glWindowPos4fMESA) then Exit;
- @glWindowPos4dMESA := SDL_GL_GetProcAddress('glWindowPos4dMESA');
- if not Assigned(glWindowPos4dMESA) then Exit;
- @glWindowPos4ivMESA := SDL_GL_GetProcAddress('glWindowPos4ivMESA');
- if not Assigned(glWindowPos4ivMESA) then Exit;
- @glWindowPos4svMESA := SDL_GL_GetProcAddress('glWindowPos4svMESA');
- if not Assigned(glWindowPos4svMESA) then Exit;
- @glWindowPos4fvMESA := SDL_GL_GetProcAddress('glWindowPos4fvMESA');
- if not Assigned(glWindowPos4fvMESA) then Exit;
- @glWindowPos4dvMESA := SDL_GL_GetProcAddress('glWindowPos4dvMESA');
- if not Assigned(glWindowPos4dvMESA) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_OML_interlace: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_OML_interlace', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_OML_resample: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_OML_resample', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_OML_subsample: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_OML_subsample', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_generate_mipmap: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_generate_mipmap', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_multisample: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_multisample', extstring) then
- begin
- @glSampleMaskSGIS := SDL_GL_GetProcAddress('glSampleMaskSGIS');
- if not Assigned(glSampleMaskSGIS) then Exit;
- @glSamplePatternSGIS := SDL_GL_GetProcAddress('glSamplePatternSGIS');
- if not Assigned(glSamplePatternSGIS) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_pixel_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_pixel_texture', extstring) then
- begin
- @glPixelTexGenParameteriSGIS := SDL_GL_GetProcAddress('glPixelTexGenParameteriSGIS');
- if not Assigned(glPixelTexGenParameteriSGIS) then Exit;
- @glPixelTexGenParameterfSGIS := SDL_GL_GetProcAddress('glPixelTexGenParameterfSGIS');
- if not Assigned(glPixelTexGenParameterfSGIS) then Exit;
- @glGetPixelTexGenParameterivSGIS := SDL_GL_GetProcAddress('glGetPixelTexGenParameterivSGIS');
- if not Assigned(glGetPixelTexGenParameterivSGIS) then Exit;
- @glGetPixelTexGenParameterfvSGIS := SDL_GL_GetProcAddress('glGetPixelTexGenParameterfvSGIS');
- if not Assigned(glGetPixelTexGenParameterfvSGIS) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_texture_border_clamp: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_texture_border_clamp', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_texture_color_mask: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_texture_color_mask', extstring) then
- begin
- @glTextureColorMaskSGIS := SDL_GL_GetProcAddress('glTextureColorMaskSGIS');
- if not Assigned(glTextureColorMaskSGIS) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_texture_edge_clamp: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_texture_edge_clamp', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_texture_lod: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_texture_lod', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIS_depth_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIS_depth_texture', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIX_fog_offset: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIX_fog_offset', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIX_interlace: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIX_interlace', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGIX_shadow_ambient: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGIX_shadow_ambient', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGI_color_matrix: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGI_color_matrix', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGI_color_table: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGI_color_table', extstring) then
- begin
- @glColorTableSGI := SDL_GL_GetProcAddress('glColorTableSGI');
- if not Assigned(glColorTableSGI) then Exit;
- @glCopyColorTableSGI := SDL_GL_GetProcAddress('glCopyColorTableSGI');
- if not Assigned(glCopyColorTableSGI) then Exit;
- @glColorTableParameterivSGI := SDL_GL_GetProcAddress('glColorTableParameterivSGI');
- if not Assigned(glColorTableParameterivSGI) then Exit;
- @glColorTableParameterfvSGI := SDL_GL_GetProcAddress('glColorTableParameterfvSGI');
- if not Assigned(glColorTableParameterfvSGI) then Exit;
- @glGetColorTableSGI := SDL_GL_GetProcAddress('glGetColorTableSGI');
- if not Assigned(glGetColorTableSGI) then Exit;
- @glGetColorTableParameterivSGI := SDL_GL_GetProcAddress('glGetColorTableParameterivSGI');
- if not Assigned(glGetColorTableParameterivSGI) then Exit;
- @glGetColorTableParameterfvSGI := SDL_GL_GetProcAddress('glGetColorTableParameterfvSGI');
- if not Assigned(glGetColorTableParameterfvSGI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SGI_texture_color_table: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SGI_texture_color_table', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_SUN_vertex: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_SUN_vertex', extstring) then
- begin
- @glColor4ubVertex2fSUN := SDL_GL_GetProcAddress('glColor4ubVertex2fSUN');
- if not Assigned(glColor4ubVertex2fSUN) then Exit;
- @glColor4ubVertex2fvSUN := SDL_GL_GetProcAddress('glColor4ubVertex2fvSUN');
- if not Assigned(glColor4ubVertex2fvSUN) then Exit;
- @glColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glColor4ubVertex3fSUN');
- if not Assigned(glColor4ubVertex3fSUN) then Exit;
- @glColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glColor4ubVertex3fvSUN');
- if not Assigned(glColor4ubVertex3fvSUN) then Exit;
- @glColor3fVertex3fSUN := SDL_GL_GetProcAddress('glColor3fVertex3fSUN');
- if not Assigned(glColor3fVertex3fSUN) then Exit;
- @glColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glColor3fVertex3fvSUN');
- if not Assigned(glColor3fVertex3fvSUN) then Exit;
- @glNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glNormal3fVertex3fSUN');
- if not Assigned(glNormal3fVertex3fSUN) then Exit;
- @glNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glNormal3fVertex3fvSUN');
- if not Assigned(glNormal3fVertex3fvSUN) then Exit;
- @glColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glColor4fNormal3fVertex3fSUN');
- if not Assigned(glColor4fNormal3fVertex3fSUN) then Exit;
- @glColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glColor4fNormal3fVertex3fvSUN');
- if not Assigned(glColor4fNormal3fVertex3fvSUN) then Exit;
- @glTexCoord2fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fVertex3fSUN');
- if not Assigned(glTexCoord2fVertex3fSUN) then Exit;
- @glTexCoord2fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fVertex3fvSUN');
- if not Assigned(glTexCoord2fVertex3fvSUN) then Exit;
- @glTexCoord4fVertex4fSUN := SDL_GL_GetProcAddress('glTexCoord4fVertex4fSUN');
- if not Assigned(glTexCoord4fVertex4fSUN) then Exit;
- @glTexCoord4fVertex4fvSUN := SDL_GL_GetProcAddress('glTexCoord4fVertex4fvSUN');
- if not Assigned(glTexCoord4fVertex4fvSUN) then Exit;
- @glTexCoord2fColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4ubVertex3fSUN');
- if not Assigned(glTexCoord2fColor4ubVertex3fSUN) then Exit;
- @glTexCoord2fColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4ubVertex3fvSUN');
- if not Assigned(glTexCoord2fColor4ubVertex3fvSUN) then Exit;
- @glTexCoord2fColor3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor3fVertex3fSUN');
- if not Assigned(glTexCoord2fColor3fVertex3fSUN) then Exit;
- @glTexCoord2fColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor3fVertex3fvSUN');
- if not Assigned(glTexCoord2fColor3fVertex3fvSUN) then Exit;
- @glTexCoord2fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fNormal3fVertex3fSUN');
- if not Assigned(glTexCoord2fNormal3fVertex3fSUN) then Exit;
- @glTexCoord2fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fNormal3fVertex3fvSUN');
- if not Assigned(glTexCoord2fNormal3fVertex3fvSUN) then Exit;
- @glTexCoord2fColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4fNormal3fVertex3fSUN');
- if not Assigned(glTexCoord2fColor4fNormal3fVertex3fSUN) then Exit;
- @glTexCoord2fColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4fNormal3fVertex3fvSUN');
- if not Assigned(glTexCoord2fColor4fNormal3fVertex3fvSUN) then Exit;
- @glTexCoord4fColor4fNormal3fVertex4fSUN := SDL_GL_GetProcAddress('glTexCoord4fColor4fNormal3fVertex4fSUN');
- if not Assigned(glTexCoord4fColor4fNormal3fVertex4fSUN) then Exit;
- @glTexCoord4fColor4fNormal3fVertex4fvSUN := SDL_GL_GetProcAddress('glTexCoord4fColor4fNormal3fVertex4fvSUN');
- if not Assigned(glTexCoord4fColor4fNormal3fVertex4fvSUN) then Exit;
- @glReplacementCodeuiVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiVertex3fSUN');
- if not Assigned(glReplacementCodeuiVertex3fSUN) then Exit;
- @glReplacementCodeuiVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiVertex3fvSUN');
- if not Assigned(glReplacementCodeuiVertex3fvSUN) then Exit;
- @glReplacementCodeuiColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4ubVertex3fSUN');
- if not Assigned(glReplacementCodeuiColor4ubVertex3fSUN) then Exit;
- @glReplacementCodeuiColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4ubVertex3fvSUN');
- if not Assigned(glReplacementCodeuiColor4ubVertex3fvSUN) then Exit;
- @glReplacementCodeuiColor3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor3fVertex3fSUN');
- if not Assigned(glReplacementCodeuiColor3fVertex3fSUN) then Exit;
- @glReplacementCodeuiColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor3fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiColor3fVertex3fvSUN) then Exit;
- @glReplacementCodeuiNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiNormal3fVertex3fSUN');
- if not Assigned(glReplacementCodeuiNormal3fVertex3fSUN) then Exit;
- @glReplacementCodeuiNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiNormal3fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiNormal3fVertex3fvSUN) then Exit;
- @glReplacementCodeuiColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fSUN');
- if not Assigned(glReplacementCodeuiColor4fNormal3fVertex3fSUN) then Exit;
- @glReplacementCodeuiColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiColor4fNormal3fVertex3fvSUN) then Exit;
- @glReplacementCodeuiTexCoord2fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fVertex3fSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fVertex3fSUN) then Exit;
- @glReplacementCodeuiTexCoord2fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fVertex3fvSUN) then Exit;
- @glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) then Exit;
- @glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) then Exit;
- @glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) then Exit;
- @glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN');
- if not Assigned(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_fragment_program: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_fragment_program', extstring) then
- begin
- @glProgramStringARB := SDL_GL_GetProcAddress('glProgramStringARB');
- if not Assigned(glProgramStringARB) then Exit;
- @glBindProgramARB := SDL_GL_GetProcAddress('glBindProgramARB');
- if not Assigned(glBindProgramARB) then Exit;
- @glDeleteProgramsARB := SDL_GL_GetProcAddress('glDeleteProgramsARB');
- if not Assigned(glDeleteProgramsARB) then Exit;
- @glGenProgramsARB := SDL_GL_GetProcAddress('glGenProgramsARB');
- if not Assigned(glGenProgramsARB) then Exit;
- @glProgramEnvParameter4dARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dARB');
- if not Assigned(glProgramEnvParameter4dARB) then Exit;
- @glProgramEnvParameter4dvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dvARB');
- if not Assigned(glProgramEnvParameter4dvARB) then Exit;
- @glProgramEnvParameter4fARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fARB');
- if not Assigned(glProgramEnvParameter4fARB) then Exit;
- @glProgramEnvParameter4fvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fvARB');
- if not Assigned(glProgramEnvParameter4fvARB) then Exit;
- @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
- if not Assigned(glProgramLocalParameter4dARB) then Exit;
- @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
- if not Assigned(glProgramLocalParameter4dvARB) then Exit;
- @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
- if not Assigned(glProgramLocalParameter4fARB) then Exit;
- @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
- if not Assigned(glProgramLocalParameter4fvARB) then Exit;
- @glGetProgramEnvParameterdvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterdvARB');
- if not Assigned(glGetProgramEnvParameterdvARB) then Exit;
- @glGetProgramEnvParameterfvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterfvARB');
- if not Assigned(glGetProgramEnvParameterfvARB) then Exit;
- @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
- if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
- @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
- if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
- @glGetProgramivARB := SDL_GL_GetProcAddress('glGetProgramivARB');
- if not Assigned(glGetProgramivARB) then Exit;
- @glGetProgramStringARB := SDL_GL_GetProcAddress('glGetProgramStringARB');
- if not Assigned(glGetProgramStringARB) then Exit;
- @glIsProgramARB := SDL_GL_GetProcAddress('glIsProgramARB');
- if not Assigned(glIsProgramARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_text_fragment_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_text_fragment_shader', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_APPLE_client_storage: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_APPLE_client_storage', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_APPLE_element_array: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_APPLE_element_array', extstring) then
- begin
- @glElementPointerAPPLE := SDL_GL_GetProcAddress('glElementPointerAPPLE');
- if not Assigned(glElementPointerAPPLE) then Exit;
- @glDrawElementArrayAPPLE := SDL_GL_GetProcAddress('glDrawElementArrayAPPLE');
- if not Assigned(glDrawElementArrayAPPLE) then Exit;
- @glDrawRangeElementArrayAPPLE := SDL_GL_GetProcAddress('glDrawRangeElementArrayAPPLE');
- if not Assigned(glDrawRangeElementArrayAPPLE) then Exit;
- @glMultiDrawElementArrayAPPLE := SDL_GL_GetProcAddress('glMultiDrawElementArrayAPPLE');
- if not Assigned(glMultiDrawElementArrayAPPLE) then Exit;
- @glMultiDrawRangeElementArrayAPPLE := SDL_GL_GetProcAddress('glMultiDrawRangeElementArrayAPPLE');
- if not Assigned(glMultiDrawRangeElementArrayAPPLE) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_APPLE_fence: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_APPLE_fence', extstring) then
- begin
- @glGenFencesAPPLE := SDL_GL_GetProcAddress('glGenFencesAPPLE');
- if not Assigned(glGenFencesAPPLE) then Exit;
- @glDeleteFencesAPPLE := SDL_GL_GetProcAddress('glDeleteFencesAPPLE');
- if not Assigned(glDeleteFencesAPPLE) then Exit;
- @glSetFenceAPPLE := SDL_GL_GetProcAddress('glSetFenceAPPLE');
- if not Assigned(glSetFenceAPPLE) then Exit;
- @glIsFenceAPPLE := SDL_GL_GetProcAddress('glIsFenceAPPLE');
- if not Assigned(glIsFenceAPPLE) then Exit;
- @glTestFenceAPPLE := SDL_GL_GetProcAddress('glTestFenceAPPLE');
- if not Assigned(glTestFenceAPPLE) then Exit;
- @glFinishFenceAPPLE := SDL_GL_GetProcAddress('glFinishFenceAPPLE');
- if not Assigned(glFinishFenceAPPLE) then Exit;
- @glTestObjectAPPLE := SDL_GL_GetProcAddress('glTestObjectAPPLE');
- if not Assigned(glTestObjectAPPLE) then Exit;
- @glFinishObjectAPPLE := SDL_GL_GetProcAddress('glFinishObjectAPPLE');
- if not Assigned(glFinishObjectAPPLE) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_APPLE_vertex_array_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_APPLE_vertex_array_object', extstring) then
- begin
- @glBindVertexArrayAPPLE := SDL_GL_GetProcAddress('glBindVertexArrayAPPLE');
- if not Assigned(glBindVertexArrayAPPLE) then Exit;
- @glDeleteVertexArraysAPPLE := SDL_GL_GetProcAddress('glDeleteVertexArraysAPPLE');
- if not Assigned(glDeleteVertexArraysAPPLE) then Exit;
- @glGenVertexArraysAPPLE := SDL_GL_GetProcAddress('glGenVertexArraysAPPLE');
- if not Assigned(glGenVertexArraysAPPLE) then Exit;
- @glIsVertexArrayAPPLE := SDL_GL_GetProcAddress('glIsVertexArrayAPPLE');
- if not Assigned(glIsVertexArrayAPPLE) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_APPLE_vertex_array_range: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_APPLE_vertex_array_range', extstring) then
- begin
- @glVertexArrayRangeAPPLE := SDL_GL_GetProcAddress('glVertexArrayRangeAPPLE');
- if not Assigned(glVertexArrayRangeAPPLE) then Exit;
- @glFlushVertexArrayRangeAPPLE := SDL_GL_GetProcAddress('glFlushVertexArrayRangeAPPLE');
- if not Assigned(glFlushVertexArrayRangeAPPLE) then Exit;
- @glVertexArrayParameteriAPPLE := SDL_GL_GetProcAddress('glVertexArrayParameteriAPPLE');
- if not Assigned(glVertexArrayParameteriAPPLE) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-{$IFDEF WINDOWS}
-function Load_WGL_ARB_pixel_format: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_pixel_format', extstring) then
- begin
- @wglGetPixelFormatAttribivARB := SDL_GL_GetProcAddress('wglGetPixelFormatAttribivARB');
- if not Assigned(wglGetPixelFormatAttribivARB) then Exit;
- @wglGetPixelFormatAttribfvARB := SDL_GL_GetProcAddress('wglGetPixelFormatAttribfvARB');
- if not Assigned(wglGetPixelFormatAttribfvARB) then Exit;
- @wglChoosePixelFormatARB := SDL_GL_GetProcAddress('wglChoosePixelFormatARB');
- if not Assigned(wglChoosePixelFormatARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_ARB_make_current_read: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_make_current_read', extstring) then
- begin
- @wglMakeContextCurrentARB := SDL_GL_GetProcAddress('wglMakeContextCurrentARB');
- if not Assigned(wglMakeContextCurrentARB) then Exit;
- @wglGetCurrentReadDCARB := SDL_GL_GetProcAddress('wglGetCurrentReadDCARB');
- if not Assigned(wglGetCurrentReadDCARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_ARB_pbuffer: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_pbuffer', extstring) then
- begin
- @wglCreatePbufferARB := SDL_GL_GetProcAddress('wglCreatePbufferARB');
- if not Assigned(wglCreatePbufferARB) then Exit;
- @wglGetPbufferDCARB := SDL_GL_GetProcAddress('wglGetPbufferDCARB');
- if not Assigned(wglGetPbufferDCARB) then Exit;
- @wglReleasePbufferDCARB := SDL_GL_GetProcAddress('wglReleasePbufferDCARB');
- if not Assigned(wglReleasePbufferDCARB) then Exit;
- @wglDestroyPbufferARB := SDL_GL_GetProcAddress('wglDestroyPbufferARB');
- if not Assigned(wglDestroyPbufferARB) then Exit;
- @wglQueryPbufferARB := SDL_GL_GetProcAddress('wglQueryPbufferARB');
- if not Assigned(wglQueryPbufferARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_EXT_swap_control: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_EXT_swap_control', extstring) then
- begin
- @wglSwapIntervalEXT := SDL_GL_GetProcAddress('wglSwapIntervalEXT');
- if not Assigned(wglSwapIntervalEXT) then Exit;
- @wglGetSwapIntervalEXT := SDL_GL_GetProcAddress('wglGetSwapIntervalEXT');
- if not Assigned(wglGetSwapIntervalEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_ARB_render_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ARB_render_texture', extstring) then
- begin
- @wglBindTexImageARB := SDL_GL_GetProcAddress('wglBindTexImageARB');
- if not Assigned(wglBindTexImageARB) then Exit;
- @wglReleaseTexImageARB := SDL_GL_GetProcAddress('wglReleaseTexImageARB');
- if not Assigned(wglReleaseTexImageARB) then Exit;
- @wglSetPbufferAttribARB := SDL_GL_GetProcAddress('wglSetPbufferAttribARB');
- if not Assigned(wglSetPbufferAttribARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_EXT_extensions_string: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_EXT_extensions_string', extstring) then
- begin
- @wglGetExtensionsStringEXT := SDL_GL_GetProcAddress('wglGetExtensionsStringEXT');
- if not Assigned(wglGetExtensionsStringEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_EXT_make_current_read: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_EXT_make_current_read', extstring) then
- begin
- @wglMakeContextCurrentEXT := SDL_GL_GetProcAddress('wglMakeContextCurrentEXT');
- if not Assigned(wglMakeContextCurrentEXT) then Exit;
- @wglGetCurrentReadDCEXT := SDL_GL_GetProcAddress('wglGetCurrentReadDCEXT');
- if not Assigned(wglGetCurrentReadDCEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_EXT_pbuffer: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_EXT_pbuffer', extstring) then
- begin
- @wglCreatePbufferEXT := SDL_GL_GetProcAddress('wglCreatePbufferEXT');
- if not Assigned(wglCreatePbufferEXT) then Exit;
- @wglGetPbufferDCEXT := SDL_GL_GetProcAddress('wglGetPbufferDCEXT');
- if not Assigned(wglGetPbufferDCEXT) then Exit;
- @wglReleasePbufferDCEXT := SDL_GL_GetProcAddress('wglReleasePbufferDCEXT');
- if not Assigned(wglReleasePbufferDCEXT) then Exit;
- @wglDestroyPbufferEXT := SDL_GL_GetProcAddress('wglDestroyPbufferEXT');
- if not Assigned(wglDestroyPbufferEXT) then Exit;
- @wglQueryPbufferEXT := SDL_GL_GetProcAddress('wglQueryPbufferEXT');
- if not Assigned(wglQueryPbufferEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_EXT_pixel_format: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_EXT_pixel_format', extstring) then
- begin
- @wglGetPixelFormatAttribivEXT := SDL_GL_GetProcAddress('wglGetPixelFormatAttribivEXT');
- if not Assigned(wglGetPixelFormatAttribivEXT) then Exit;
- @wglGetPixelFormatAttribfvEXT := SDL_GL_GetProcAddress('wglGetPixelFormatAttribfvEXT');
- if not Assigned(wglGetPixelFormatAttribfvEXT) then Exit;
- @wglChoosePixelFormatEXT := SDL_GL_GetProcAddress('wglChoosePixelFormatEXT');
- if not Assigned(wglChoosePixelFormatEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_I3D_digital_video_control: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_digital_video_control', extstring) then
- begin
- @wglGetDigitalVideoParametersI3D := SDL_GL_GetProcAddress('wglGetDigitalVideoParametersI3D');
- if not Assigned(wglGetDigitalVideoParametersI3D) then Exit;
- @wglSetDigitalVideoParametersI3D := SDL_GL_GetProcAddress('wglSetDigitalVideoParametersI3D');
- if not Assigned(wglSetDigitalVideoParametersI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_I3D_gamma: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_gamma', extstring) then
- begin
- @wglGetGammaTableParametersI3D := SDL_GL_GetProcAddress('wglGetGammaTableParametersI3D');
- if not Assigned(wglGetGammaTableParametersI3D) then Exit;
- @wglSetGammaTableParametersI3D := SDL_GL_GetProcAddress('wglSetGammaTableParametersI3D');
- if not Assigned(wglSetGammaTableParametersI3D) then Exit;
- @wglGetGammaTableI3D := SDL_GL_GetProcAddress('wglGetGammaTableI3D');
- if not Assigned(wglGetGammaTableI3D) then Exit;
- @wglSetGammaTableI3D := SDL_GL_GetProcAddress('wglSetGammaTableI3D');
- if not Assigned(wglSetGammaTableI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_WGL_I3D_genlock: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_I3D_genlock', extstring) then
- begin
- @wglEnableGenlockI3D := SDL_GL_GetProcAddress('wglEnableGenlockI3D');
- if not Assigned(wglEnableGenlockI3D) then Exit;
- @wglDisableGenlockI3D := SDL_GL_GetProcAddress('wglDisableGenlockI3D');
- if not Assigned(wglDisableGenlockI3D) then Exit;
- @wglIsEnabledGenlockI3D := SDL_GL_GetProcAddress('wglIsEnabledGenlockI3D');
- if not Assigned(wglIsEnabledGenlockI3D) then Exit;
- @wglGenlockSourceI3D := SDL_GL_GetProcAddress('wglGenlockSourceI3D');
- if not Assigned(wglGenlockSourceI3D) then Exit;
- @wglGetGenlockSourceI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceI3D');
- if not Assigned(wglGetGenlockSourceI3D) then Exit;
- @wglGenlockSourceEdgeI3D := SDL_GL_GetProcAddress('wglGenlockSourceEdgeI3D');
- if not Assigned(wglGenlockSourceEdgeI3D) then Exit;
- @wglGetGenlockSourceEdgeI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceEdgeI3D');
- if not Assigned(wglGetGenlockSourceEdgeI3D) then Exit;
- @wglGenlockSampleRateI3D := SDL_GL_GetProcAddress('wglGenlockSampleRateI3D');
- if not Assigned(wglGenlockSampleRateI3D) then Exit;
- @wglGetGenlockSampleRateI3D := SDL_GL_GetProcAddress('wglGetGenlockSampleRateI3D');
- if not Assigned(wglGetGenlockSampleRateI3D) then Exit;
- @wglGenlockSourceDelayI3D := SDL_GL_GetProcAddress('wglGenlockSourceDelayI3D');
- if not Assigned(wglGenlockSourceDelayI3D) then Exit;
- @wglGetGenlockSourceDelayI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceDelayI3D');
- if not Assigned(wglGetGenlockSourceDelayI3D) then Exit;
- @wglQueryGenlockMaxSourceDelayI3D := SDL_GL_GetProcAddress('wglQueryGenlockMaxSourceDelayI3D');
- if not Assigned(wglQueryGenlockMaxSourceDelayI3D) then Exit;
- Result := TRUE;
- end;
-
-end;
-{$ENDIF}
-
-function Load_GL_ARB_matrix_palette: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_matrix_palette', extstring) then
- begin
- @glCurrentPaletteMatrixARB := SDL_GL_GetProcAddress('glCurrentPaletteMatrixARB');
- if not Assigned(glCurrentPaletteMatrixARB) then Exit;
- @glMatrixIndexubvARB := SDL_GL_GetProcAddress('glMatrixIndexubvARB');
- if not Assigned(glMatrixIndexubvARB) then Exit;
- @glMatrixIndexusvARB := SDL_GL_GetProcAddress('glMatrixIndexusvARB');
- if not Assigned(glMatrixIndexusvARB) then Exit;
- @glMatrixIndexuivARB := SDL_GL_GetProcAddress('glMatrixIndexuivARB');
- if not Assigned(glMatrixIndexuivARB) then Exit;
- @glMatrixIndexPointerARB := SDL_GL_GetProcAddress('glMatrixIndexPointerARB');
- if not Assigned(glMatrixIndexPointerARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_element_array: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_element_array', extstring) then
- begin
- @glElementPointerNV := SDL_GL_GetProcAddress('glElementPointerNV');
- if not Assigned(glElementPointerNV) then Exit;
- @glDrawElementArrayNV := SDL_GL_GetProcAddress('glDrawElementArrayNV');
- if not Assigned(glDrawElementArrayNV) then Exit;
- @glDrawRangeElementArrayNV := SDL_GL_GetProcAddress('glDrawRangeElementArrayNV');
- if not Assigned(glDrawRangeElementArrayNV) then Exit;
- @glMultiDrawElementArrayNV := SDL_GL_GetProcAddress('glMultiDrawElementArrayNV');
- if not Assigned(glMultiDrawElementArrayNV) then Exit;
- @glMultiDrawRangeElementArrayNV := SDL_GL_GetProcAddress('glMultiDrawRangeElementArrayNV');
- if not Assigned(glMultiDrawRangeElementArrayNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_float_buffer: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_float_buffer', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_fragment_program: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_fragment_program', extstring) then
- begin
- @glProgramNamedParameter4fNV := SDL_GL_GetProcAddress('glProgramNamedParameter4fNV');
- if not Assigned(glProgramNamedParameter4fNV) then Exit;
- @glProgramNamedParameter4dNV := SDL_GL_GetProcAddress('glProgramNamedParameter4dNV');
- if not Assigned(glProgramNamedParameter4dNV) then Exit;
- @glGetProgramNamedParameterfvNV := SDL_GL_GetProcAddress('glGetProgramNamedParameterfvNV');
- if not Assigned(glGetProgramNamedParameterfvNV) then Exit;
- @glGetProgramNamedParameterdvNV := SDL_GL_GetProcAddress('glGetProgramNamedParameterdvNV');
- if not Assigned(glGetProgramNamedParameterdvNV) then Exit;
- @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
- if not Assigned(glProgramLocalParameter4dARB) then Exit;
- @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
- if not Assigned(glProgramLocalParameter4dvARB) then Exit;
- @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
- if not Assigned(glProgramLocalParameter4fARB) then Exit;
- @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
- if not Assigned(glProgramLocalParameter4fvARB) then Exit;
- @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
- if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
- @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
- if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_primitive_restart: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_primitive_restart', extstring) then
- begin
- @glPrimitiveRestartNV := SDL_GL_GetProcAddress('glPrimitiveRestartNV');
- if not Assigned(glPrimitiveRestartNV) then Exit;
- @glPrimitiveRestartIndexNV := SDL_GL_GetProcAddress('glPrimitiveRestartIndexNV');
- if not Assigned(glPrimitiveRestartIndexNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_program2: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_program2', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-{$IFDEF WINDOWS}
-function Load_WGL_NV_render_texture_rectangle: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_NV_render_texture_rectangle', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-{$ENDIF}
-
-function Load_GL_NV_pixel_data_range: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_pixel_data_range', extstring) then
- begin
- @glPixelDataRangeNV := SDL_GL_GetProcAddress('glPixelDataRangeNV');
- if not Assigned(glPixelDataRangeNV) then Exit;
- @glFlushPixelDataRangeNV := SDL_GL_GetProcAddress('glFlushPixelDataRangeNV');
- if not Assigned(glFlushPixelDataRangeNV) then Exit;
- {$IFDEF WINDOWS}
- @wglAllocateMemoryNV := SDL_GL_GetProcAddress('wglAllocateMemoryNV');
- if not Assigned(wglAllocateMemoryNV) then Exit;
- @wglFreeMemoryNV := SDL_GL_GetProcAddress('wglFreeMemoryNV');
- if not Assigned(wglFreeMemoryNV) then Exit;
- {$ENDIF}
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_rectangle: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_rectangle', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_S3_s3tc: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_S3_s3tc', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_draw_buffers: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_draw_buffers', extstring) then
- begin
- @glDrawBuffersATI := SDL_GL_GetProcAddress('glDrawBuffersATI');
- if not Assigned(glDrawBuffersATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-{$IFDEF WINDOWS}
-function Load_WGL_ATI_pixel_format_float: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
- if not Assigned(wglGetExtensionsStringARB) then Exit;
- extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
-
- if glext_ExtensionSupported('WGL_ATI_pixel_format_float', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-{$ENDIF}
-
-function Load_GL_ATI_texture_env_combine3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_texture_env_combine3', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_texture_float: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_texture_float', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_texture_expand_normal: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_texture_expand_normal', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_half_float: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_half_float', extstring) then
- begin
- @glVertex2hNV := SDL_GL_GetProcAddress('glVertex2hNV');
- if not Assigned(glVertex2hNV) then Exit;
- @glVertex2hvNV := SDL_GL_GetProcAddress('glVertex2hvNV');
- if not Assigned(glVertex2hvNV) then Exit;
- @glVertex3hNV := SDL_GL_GetProcAddress('glVertex3hNV');
- if not Assigned(glVertex3hNV) then Exit;
- @glVertex3hvNV := SDL_GL_GetProcAddress('glVertex3hvNV');
- if not Assigned(glVertex3hvNV) then Exit;
- @glVertex4hNV := SDL_GL_GetProcAddress('glVertex4hNV');
- if not Assigned(glVertex4hNV) then Exit;
- @glVertex4hvNV := SDL_GL_GetProcAddress('glVertex4hvNV');
- if not Assigned(glVertex4hvNV) then Exit;
- @glNormal3hNV := SDL_GL_GetProcAddress('glNormal3hNV');
- if not Assigned(glNormal3hNV) then Exit;
- @glNormal3hvNV := SDL_GL_GetProcAddress('glNormal3hvNV');
- if not Assigned(glNormal3hvNV) then Exit;
- @glColor3hNV := SDL_GL_GetProcAddress('glColor3hNV');
- if not Assigned(glColor3hNV) then Exit;
- @glColor3hvNV := SDL_GL_GetProcAddress('glColor3hvNV');
- if not Assigned(glColor3hvNV) then Exit;
- @glColor4hNV := SDL_GL_GetProcAddress('glColor4hNV');
- if not Assigned(glColor4hNV) then Exit;
- @glColor4hvNV := SDL_GL_GetProcAddress('glColor4hvNV');
- if not Assigned(glColor4hvNV) then Exit;
- @glTexCoord1hNV := SDL_GL_GetProcAddress('glTexCoord1hNV');
- if not Assigned(glTexCoord1hNV) then Exit;
- @glTexCoord1hvNV := SDL_GL_GetProcAddress('glTexCoord1hvNV');
- if not Assigned(glTexCoord1hvNV) then Exit;
- @glTexCoord2hNV := SDL_GL_GetProcAddress('glTexCoord2hNV');
- if not Assigned(glTexCoord2hNV) then Exit;
- @glTexCoord2hvNV := SDL_GL_GetProcAddress('glTexCoord2hvNV');
- if not Assigned(glTexCoord2hvNV) then Exit;
- @glTexCoord3hNV := SDL_GL_GetProcAddress('glTexCoord3hNV');
- if not Assigned(glTexCoord3hNV) then Exit;
- @glTexCoord3hvNV := SDL_GL_GetProcAddress('glTexCoord3hvNV');
- if not Assigned(glTexCoord3hvNV) then Exit;
- @glTexCoord4hNV := SDL_GL_GetProcAddress('glTexCoord4hNV');
- if not Assigned(glTexCoord4hNV) then Exit;
- @glTexCoord4hvNV := SDL_GL_GetProcAddress('glTexCoord4hvNV');
- if not Assigned(glTexCoord4hvNV) then Exit;
- @glMultiTexCoord1hNV := SDL_GL_GetProcAddress('glMultiTexCoord1hNV');
- if not Assigned(glMultiTexCoord1hNV) then Exit;
- @glMultiTexCoord1hvNV := SDL_GL_GetProcAddress('glMultiTexCoord1hvNV');
- if not Assigned(glMultiTexCoord1hvNV) then Exit;
- @glMultiTexCoord2hNV := SDL_GL_GetProcAddress('glMultiTexCoord2hNV');
- if not Assigned(glMultiTexCoord2hNV) then Exit;
- @glMultiTexCoord2hvNV := SDL_GL_GetProcAddress('glMultiTexCoord2hvNV');
- if not Assigned(glMultiTexCoord2hvNV) then Exit;
- @glMultiTexCoord3hNV := SDL_GL_GetProcAddress('glMultiTexCoord3hNV');
- if not Assigned(glMultiTexCoord3hNV) then Exit;
- @glMultiTexCoord3hvNV := SDL_GL_GetProcAddress('glMultiTexCoord3hvNV');
- if not Assigned(glMultiTexCoord3hvNV) then Exit;
- @glMultiTexCoord4hNV := SDL_GL_GetProcAddress('glMultiTexCoord4hNV');
- if not Assigned(glMultiTexCoord4hNV) then Exit;
- @glMultiTexCoord4hvNV := SDL_GL_GetProcAddress('glMultiTexCoord4hvNV');
- if not Assigned(glMultiTexCoord4hvNV) then Exit;
- @glFogCoordhNV := SDL_GL_GetProcAddress('glFogCoordhNV');
- if not Assigned(glFogCoordhNV) then Exit;
- @glFogCoordhvNV := SDL_GL_GetProcAddress('glFogCoordhvNV');
- if not Assigned(glFogCoordhvNV) then Exit;
- @glSecondaryColor3hNV := SDL_GL_GetProcAddress('glSecondaryColor3hNV');
- if not Assigned(glSecondaryColor3hNV) then Exit;
- @glSecondaryColor3hvNV := SDL_GL_GetProcAddress('glSecondaryColor3hvNV');
- if not Assigned(glSecondaryColor3hvNV) then Exit;
- @glVertexWeighthNV := SDL_GL_GetProcAddress('glVertexWeighthNV');
- if not Assigned(glVertexWeighthNV) then Exit;
- @glVertexWeighthvNV := SDL_GL_GetProcAddress('glVertexWeighthvNV');
- if not Assigned(glVertexWeighthvNV) then Exit;
- @glVertexAttrib1hNV := SDL_GL_GetProcAddress('glVertexAttrib1hNV');
- if not Assigned(glVertexAttrib1hNV) then Exit;
- @glVertexAttrib1hvNV := SDL_GL_GetProcAddress('glVertexAttrib1hvNV');
- if not Assigned(glVertexAttrib1hvNV) then Exit;
- @glVertexAttrib2hNV := SDL_GL_GetProcAddress('glVertexAttrib2hNV');
- if not Assigned(glVertexAttrib2hNV) then Exit;
- @glVertexAttrib2hvNV := SDL_GL_GetProcAddress('glVertexAttrib2hvNV');
- if not Assigned(glVertexAttrib2hvNV) then Exit;
- @glVertexAttrib3hNV := SDL_GL_GetProcAddress('glVertexAttrib3hNV');
- if not Assigned(glVertexAttrib3hNV) then Exit;
- @glVertexAttrib3hvNV := SDL_GL_GetProcAddress('glVertexAttrib3hvNV');
- if not Assigned(glVertexAttrib3hvNV) then Exit;
- @glVertexAttrib4hNV := SDL_GL_GetProcAddress('glVertexAttrib4hNV');
- if not Assigned(glVertexAttrib4hNV) then Exit;
- @glVertexAttrib4hvNV := SDL_GL_GetProcAddress('glVertexAttrib4hvNV');
- if not Assigned(glVertexAttrib4hvNV) then Exit;
- @glVertexAttribs1hvNV := SDL_GL_GetProcAddress('glVertexAttribs1hvNV');
- if not Assigned(glVertexAttribs1hvNV) then Exit;
- @glVertexAttribs2hvNV := SDL_GL_GetProcAddress('glVertexAttribs2hvNV');
- if not Assigned(glVertexAttribs2hvNV) then Exit;
- @glVertexAttribs3hvNV := SDL_GL_GetProcAddress('glVertexAttribs3hvNV');
- if not Assigned(glVertexAttribs3hvNV) then Exit;
- @glVertexAttribs4hvNV := SDL_GL_GetProcAddress('glVertexAttribs4hvNV');
- if not Assigned(glVertexAttribs4hvNV) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_map_object_buffer: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_map_object_buffer', extstring) then
- begin
- @glMapObjectBufferATI := SDL_GL_GetProcAddress('glMapObjectBufferATI');
- if not Assigned(glMapObjectBufferATI) then Exit;
- @glUnmapObjectBufferATI := SDL_GL_GetProcAddress('glUnmapObjectBufferATI');
- if not Assigned(glUnmapObjectBufferATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_separate_stencil: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_separate_stencil', extstring) then
- begin
- @glStencilOpSeparateATI := SDL_GL_GetProcAddress('glStencilOpSeparateATI');
- if not Assigned(glStencilOpSeparateATI) then Exit;
- @glStencilFuncSeparateATI := SDL_GL_GetProcAddress('glStencilFuncSeparateATI');
- if not Assigned(glStencilFuncSeparateATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ATI_vertex_attrib_array_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ATI_vertex_attrib_array_object', extstring) then
- begin
- @glVertexAttribArrayObjectATI := SDL_GL_GetProcAddress('glVertexAttribArrayObjectATI');
- if not Assigned(glVertexAttribArrayObjectATI) then Exit;
- @glGetVertexAttribArrayObjectfvATI := SDL_GL_GetProcAddress('glGetVertexAttribArrayObjectfvATI');
- if not Assigned(glGetVertexAttribArrayObjectfvATI) then Exit;
- @glGetVertexAttribArrayObjectivATI := SDL_GL_GetProcAddress('glGetVertexAttribArrayObjectivATI');
- if not Assigned(glGetVertexAttribArrayObjectivATI) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_vertex_buffer_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_vertex_buffer_object', extstring) then
- begin
- @glBindBufferARB := SDL_GL_GetProcAddress('glBindBufferARB');
- if not Assigned(glBindBufferARB) then Exit;
- @glDeleteBuffersARB := SDL_GL_GetProcAddress('glDeleteBuffersARB');
- if not Assigned(glDeleteBuffersARB) then Exit;
- @glGenBuffersARB := SDL_GL_GetProcAddress('glGenBuffersARB');
- if not Assigned(glGenBuffersARB) then Exit;
- @glIsBufferARB := SDL_GL_GetProcAddress('glIsBufferARB');
- if not Assigned(glIsBufferARB) then Exit;
- @glBufferDataARB := SDL_GL_GetProcAddress('glBufferDataARB');
- if not Assigned(glBufferDataARB) then Exit;
- @glBufferSubDataARB := SDL_GL_GetProcAddress('glBufferSubDataARB');
- if not Assigned(glBufferSubDataARB) then Exit;
- @glGetBufferSubDataARB := SDL_GL_GetProcAddress('glGetBufferSubDataARB');
- if not Assigned(glGetBufferSubDataARB) then Exit;
- @glMapBufferARB := SDL_GL_GetProcAddress('glMapBufferARB');
- if not Assigned(glMapBufferARB) then Exit;
- @glUnmapBufferARB := SDL_GL_GetProcAddress('glUnmapBufferARB');
- if not Assigned(glUnmapBufferARB) then Exit;
- @glGetBufferParameterivARB := SDL_GL_GetProcAddress('glGetBufferParameterivARB');
- if not Assigned(glGetBufferParameterivARB) then Exit;
- @glGetBufferPointervARB := SDL_GL_GetProcAddress('glGetBufferPointervARB');
- if not Assigned(glGetBufferPointervARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_occlusion_query: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_occlusion_query', extstring) then
- begin
- @glGenQueriesARB := SDL_GL_GetProcAddress('glGenQueriesARB');
- if not Assigned(glGenQueriesARB) then Exit;
- @glDeleteQueriesARB := SDL_GL_GetProcAddress('glDeleteQueriesARB');
- if not Assigned(glDeleteQueriesARB) then Exit;
- @glIsQueryARB := SDL_GL_GetProcAddress('glIsQueryARB');
- if not Assigned(glIsQueryARB) then Exit;
- @glBeginQueryARB := SDL_GL_GetProcAddress('glBeginQueryARB');
- if not Assigned(glBeginQueryARB) then Exit;
- @glEndQueryARB := SDL_GL_GetProcAddress('glEndQueryARB');
- if not Assigned(glEndQueryARB) then Exit;
- @glGetQueryivARB := SDL_GL_GetProcAddress('glGetQueryivARB');
- if not Assigned(glGetQueryivARB) then Exit;
- @glGetQueryObjectivARB := SDL_GL_GetProcAddress('glGetQueryObjectivARB');
- if not Assigned(glGetQueryObjectivARB) then Exit;
- @glGetQueryObjectuivARB := SDL_GL_GetProcAddress('glGetQueryObjectuivARB');
- if not Assigned(glGetQueryObjectuivARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_shader_objects: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_shader_objects', extstring) then
- begin
- @glDeleteObjectARB := SDL_GL_GetProcAddress('glDeleteObjectARB');
- if not Assigned(glDeleteObjectARB) then Exit;
- @glGetHandleARB := SDL_GL_GetProcAddress('glGetHandleARB');
- if not Assigned(glGetHandleARB) then Exit;
- @glDetachObjectARB := SDL_GL_GetProcAddress('glDetachObjectARB');
- if not Assigned(glDetachObjectARB) then Exit;
- @glCreateShaderObjectARB := SDL_GL_GetProcAddress('glCreateShaderObjectARB');
- if not Assigned(glCreateShaderObjectARB) then Exit;
- @glShaderSourceARB := SDL_GL_GetProcAddress('glShaderSourceARB');
- if not Assigned(glShaderSourceARB) then Exit;
- @glCompileShaderARB := SDL_GL_GetProcAddress('glCompileShaderARB');
- if not Assigned(glCompileShaderARB) then Exit;
- @glCreateProgramObjectARB := SDL_GL_GetProcAddress('glCreateProgramObjectARB');
- if not Assigned(glCreateProgramObjectARB) then Exit;
- @glAttachObjectARB := SDL_GL_GetProcAddress('glAttachObjectARB');
- if not Assigned(glAttachObjectARB) then Exit;
- @glLinkProgramARB := SDL_GL_GetProcAddress('glLinkProgramARB');
- if not Assigned(glLinkProgramARB) then Exit;
- @glUseProgramObjectARB := SDL_GL_GetProcAddress('glUseProgramObjectARB');
- if not Assigned(glUseProgramObjectARB) then Exit;
- @glValidateProgramARB := SDL_GL_GetProcAddress('glValidateProgramARB');
- if not Assigned(glValidateProgramARB) then Exit;
- @glUniform1fARB := SDL_GL_GetProcAddress('glUniform1fARB');
- if not Assigned(glUniform1fARB) then Exit;
- @glUniform2fARB := SDL_GL_GetProcAddress('glUniform2fARB');
- if not Assigned(glUniform2fARB) then Exit;
- @glUniform3fARB := SDL_GL_GetProcAddress('glUniform3fARB');
- if not Assigned(glUniform3fARB) then Exit;
- @glUniform4fARB := SDL_GL_GetProcAddress('glUniform4fARB');
- if not Assigned(glUniform4fARB) then Exit;
- @glUniform1iARB := SDL_GL_GetProcAddress('glUniform1iARB');
- if not Assigned(glUniform1iARB) then Exit;
- @glUniform2iARB := SDL_GL_GetProcAddress('glUniform2iARB');
- if not Assigned(glUniform2iARB) then Exit;
- @glUniform3iARB := SDL_GL_GetProcAddress('glUniform3iARB');
- if not Assigned(glUniform3iARB) then Exit;
- @glUniform4iARB := SDL_GL_GetProcAddress('glUniform4iARB');
- if not Assigned(glUniform4iARB) then Exit;
- @glUniform1fvARB := SDL_GL_GetProcAddress('glUniform1fvARB');
- if not Assigned(glUniform1fvARB) then Exit;
- @glUniform2fvARB := SDL_GL_GetProcAddress('glUniform2fvARB');
- if not Assigned(glUniform2fvARB) then Exit;
- @glUniform3fvARB := SDL_GL_GetProcAddress('glUniform3fvARB');
- if not Assigned(glUniform3fvARB) then Exit;
- @glUniform4fvARB := SDL_GL_GetProcAddress('glUniform4fvARB');
- if not Assigned(glUniform4fvARB) then Exit;
- @glUniform1ivARB := SDL_GL_GetProcAddress('glUniform1ivARB');
- if not Assigned(glUniform1ivARB) then Exit;
- @glUniform2ivARB := SDL_GL_GetProcAddress('glUniform2ivARB');
- if not Assigned(glUniform2ivARB) then Exit;
- @glUniform3ivARB := SDL_GL_GetProcAddress('glUniform3ivARB');
- if not Assigned(glUniform3ivARB) then Exit;
- @glUniform4ivARB := SDL_GL_GetProcAddress('glUniform4ivARB');
- if not Assigned(glUniform4ivARB) then Exit;
- @glUniformMatrix2fvARB := SDL_GL_GetProcAddress('glUniformMatrix2fvARB');
- if not Assigned(glUniformMatrix2fvARB) then Exit;
- @glUniformMatrix3fvARB := SDL_GL_GetProcAddress('glUniformMatrix3fvARB');
- if not Assigned(glUniformMatrix3fvARB) then Exit;
- @glUniformMatrix4fvARB := SDL_GL_GetProcAddress('glUniformMatrix4fvARB');
- if not Assigned(glUniformMatrix4fvARB) then Exit;
- @glGetObjectParameterfvARB := SDL_GL_GetProcAddress('glGetObjectParameterfvARB');
- if not Assigned(glGetObjectParameterfvARB) then Exit;
- @glGetObjectParameterivARB := SDL_GL_GetProcAddress('glGetObjectParameterivARB');
- if not Assigned(glGetObjectParameterivARB) then Exit;
- @glGetInfoLogARB := SDL_GL_GetProcAddress('glGetInfoLogARB');
- if not Assigned(glGetInfoLogARB) then Exit;
- @glGetAttachedObjectsARB := SDL_GL_GetProcAddress('glGetAttachedObjectsARB');
- if not Assigned(glGetAttachedObjectsARB) then Exit;
- @glGetUniformLocationARB := SDL_GL_GetProcAddress('glGetUniformLocationARB');
- if not Assigned(glGetUniformLocationARB) then Exit;
- @glGetActiveUniformARB := SDL_GL_GetProcAddress('glGetActiveUniformARB');
- if not Assigned(glGetActiveUniformARB) then Exit;
- @glGetUniformfvARB := SDL_GL_GetProcAddress('glGetUniformfvARB');
- if not Assigned(glGetUniformfvARB) then Exit;
- @glGetUniformivARB := SDL_GL_GetProcAddress('glGetUniformivARB');
- if not Assigned(glGetUniformivARB) then Exit;
- @glGetShaderSourceARB := SDL_GL_GetProcAddress('glGetShaderSourceARB');
- if not Assigned(glGetShaderSourceARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_vertex_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_vertex_shader', extstring) then
- begin
- @glVertexAttrib1fARB := SDL_GL_GetProcAddress('glVertexAttrib1fARB');
- if not Assigned(glVertexAttrib1fARB) then Exit;
- @glVertexAttrib1sARB := SDL_GL_GetProcAddress('glVertexAttrib1sARB');
- if not Assigned(glVertexAttrib1sARB) then Exit;
- @glVertexAttrib1dARB := SDL_GL_GetProcAddress('glVertexAttrib1dARB');
- if not Assigned(glVertexAttrib1dARB) then Exit;
- @glVertexAttrib2fARB := SDL_GL_GetProcAddress('glVertexAttrib2fARB');
- if not Assigned(glVertexAttrib2fARB) then Exit;
- @glVertexAttrib2sARB := SDL_GL_GetProcAddress('glVertexAttrib2sARB');
- if not Assigned(glVertexAttrib2sARB) then Exit;
- @glVertexAttrib2dARB := SDL_GL_GetProcAddress('glVertexAttrib2dARB');
- if not Assigned(glVertexAttrib2dARB) then Exit;
- @glVertexAttrib3fARB := SDL_GL_GetProcAddress('glVertexAttrib3fARB');
- if not Assigned(glVertexAttrib3fARB) then Exit;
- @glVertexAttrib3sARB := SDL_GL_GetProcAddress('glVertexAttrib3sARB');
- if not Assigned(glVertexAttrib3sARB) then Exit;
- @glVertexAttrib3dARB := SDL_GL_GetProcAddress('glVertexAttrib3dARB');
- if not Assigned(glVertexAttrib3dARB) then Exit;
- @glVertexAttrib4fARB := SDL_GL_GetProcAddress('glVertexAttrib4fARB');
- if not Assigned(glVertexAttrib4fARB) then Exit;
- @glVertexAttrib4sARB := SDL_GL_GetProcAddress('glVertexAttrib4sARB');
- if not Assigned(glVertexAttrib4sARB) then Exit;
- @glVertexAttrib4dARB := SDL_GL_GetProcAddress('glVertexAttrib4dARB');
- if not Assigned(glVertexAttrib4dARB) then Exit;
- @glVertexAttrib4NubARB := SDL_GL_GetProcAddress('glVertexAttrib4NubARB');
- if not Assigned(glVertexAttrib4NubARB) then Exit;
- @glVertexAttrib1fvARB := SDL_GL_GetProcAddress('glVertexAttrib1fvARB');
- if not Assigned(glVertexAttrib1fvARB) then Exit;
- @glVertexAttrib1svARB := SDL_GL_GetProcAddress('glVertexAttrib1svARB');
- if not Assigned(glVertexAttrib1svARB) then Exit;
- @glVertexAttrib1dvARB := SDL_GL_GetProcAddress('glVertexAttrib1dvARB');
- if not Assigned(glVertexAttrib1dvARB) then Exit;
- @glVertexAttrib2fvARB := SDL_GL_GetProcAddress('glVertexAttrib2fvARB');
- if not Assigned(glVertexAttrib2fvARB) then Exit;
- @glVertexAttrib2svARB := SDL_GL_GetProcAddress('glVertexAttrib2svARB');
- if not Assigned(glVertexAttrib2svARB) then Exit;
- @glVertexAttrib2dvARB := SDL_GL_GetProcAddress('glVertexAttrib2dvARB');
- if not Assigned(glVertexAttrib2dvARB) then Exit;
- @glVertexAttrib3fvARB := SDL_GL_GetProcAddress('glVertexAttrib3fvARB');
- if not Assigned(glVertexAttrib3fvARB) then Exit;
- @glVertexAttrib3svARB := SDL_GL_GetProcAddress('glVertexAttrib3svARB');
- if not Assigned(glVertexAttrib3svARB) then Exit;
- @glVertexAttrib3dvARB := SDL_GL_GetProcAddress('glVertexAttrib3dvARB');
- if not Assigned(glVertexAttrib3dvARB) then Exit;
- @glVertexAttrib4fvARB := SDL_GL_GetProcAddress('glVertexAttrib4fvARB');
- if not Assigned(glVertexAttrib4fvARB) then Exit;
- @glVertexAttrib4svARB := SDL_GL_GetProcAddress('glVertexAttrib4svARB');
- if not Assigned(glVertexAttrib4svARB) then Exit;
- @glVertexAttrib4dvARB := SDL_GL_GetProcAddress('glVertexAttrib4dvARB');
- if not Assigned(glVertexAttrib4dvARB) then Exit;
- @glVertexAttrib4ivARB := SDL_GL_GetProcAddress('glVertexAttrib4ivARB');
- if not Assigned(glVertexAttrib4ivARB) then Exit;
- @glVertexAttrib4bvARB := SDL_GL_GetProcAddress('glVertexAttrib4bvARB');
- if not Assigned(glVertexAttrib4bvARB) then Exit;
- @glVertexAttrib4ubvARB := SDL_GL_GetProcAddress('glVertexAttrib4ubvARB');
- if not Assigned(glVertexAttrib4ubvARB) then Exit;
- @glVertexAttrib4usvARB := SDL_GL_GetProcAddress('glVertexAttrib4usvARB');
- if not Assigned(glVertexAttrib4usvARB) then Exit;
- @glVertexAttrib4uivARB := SDL_GL_GetProcAddress('glVertexAttrib4uivARB');
- if not Assigned(glVertexAttrib4uivARB) then Exit;
- @glVertexAttrib4NbvARB := SDL_GL_GetProcAddress('glVertexAttrib4NbvARB');
- if not Assigned(glVertexAttrib4NbvARB) then Exit;
- @glVertexAttrib4NsvARB := SDL_GL_GetProcAddress('glVertexAttrib4NsvARB');
- if not Assigned(glVertexAttrib4NsvARB) then Exit;
- @glVertexAttrib4NivARB := SDL_GL_GetProcAddress('glVertexAttrib4NivARB');
- if not Assigned(glVertexAttrib4NivARB) then Exit;
- @glVertexAttrib4NubvARB := SDL_GL_GetProcAddress('glVertexAttrib4NubvARB');
- if not Assigned(glVertexAttrib4NubvARB) then Exit;
- @glVertexAttrib4NusvARB := SDL_GL_GetProcAddress('glVertexAttrib4NusvARB');
- if not Assigned(glVertexAttrib4NusvARB) then Exit;
- @glVertexAttrib4NuivARB := SDL_GL_GetProcAddress('glVertexAttrib4NuivARB');
- if not Assigned(glVertexAttrib4NuivARB) then Exit;
- @glVertexAttribPointerARB := SDL_GL_GetProcAddress('glVertexAttribPointerARB');
- if not Assigned(glVertexAttribPointerARB) then Exit;
- @glEnableVertexAttribArrayARB := SDL_GL_GetProcAddress('glEnableVertexAttribArrayARB');
- if not Assigned(glEnableVertexAttribArrayARB) then Exit;
- @glDisableVertexAttribArrayARB := SDL_GL_GetProcAddress('glDisableVertexAttribArrayARB');
- if not Assigned(glDisableVertexAttribArrayARB) then Exit;
- @glBindAttribLocationARB := SDL_GL_GetProcAddress('glBindAttribLocationARB');
- if not Assigned(glBindAttribLocationARB) then Exit;
- @glGetActiveAttribARB := SDL_GL_GetProcAddress('glGetActiveAttribARB');
- if not Assigned(glGetActiveAttribARB) then Exit;
- @glGetAttribLocationARB := SDL_GL_GetProcAddress('glGetAttribLocationARB');
- if not Assigned(glGetAttribLocationARB) then Exit;
- @glGetVertexAttribdvARB := SDL_GL_GetProcAddress('glGetVertexAttribdvARB');
- if not Assigned(glGetVertexAttribdvARB) then Exit;
- @glGetVertexAttribfvARB := SDL_GL_GetProcAddress('glGetVertexAttribfvARB');
- if not Assigned(glGetVertexAttribfvARB) then Exit;
- @glGetVertexAttribivARB := SDL_GL_GetProcAddress('glGetVertexAttribivARB');
- if not Assigned(glGetVertexAttribivARB) then Exit;
- @glGetVertexAttribPointervARB := SDL_GL_GetProcAddress('glGetVertexAttribPointervARB');
- if not Assigned(glGetVertexAttribPointervARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_fragment_shader: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_fragment_shader', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_shading_language_100: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_shading_language_100', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_non_power_of_two: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_texture_non_power_of_two', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_point_sprite: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_point_sprite', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_depth_bounds_test: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_depth_bounds_test', extstring) then
- begin
- @glDepthBoundsEXT := SDL_GL_GetProcAddress('glDepthBoundsEXT');
- if not Assigned(glDepthBoundsEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_secondary_color: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_secondary_color', extstring) then
- begin
- @glSecondaryColor3bEXT := SDL_GL_GetProcAddress('glSecondaryColor3bEXT');
- if not Assigned(glSecondaryColor3bEXT) then Exit;
- @glSecondaryColor3sEXT := SDL_GL_GetProcAddress('glSecondaryColor3sEXT');
- if not Assigned(glSecondaryColor3sEXT) then Exit;
- @glSecondaryColor3iEXT := SDL_GL_GetProcAddress('glSecondaryColor3iEXT');
- if not Assigned(glSecondaryColor3iEXT) then Exit;
- @glSecondaryColor3fEXT := SDL_GL_GetProcAddress('glSecondaryColor3fEXT');
- if not Assigned(glSecondaryColor3fEXT) then Exit;
- @glSecondaryColor3dEXT := SDL_GL_GetProcAddress('glSecondaryColor3dEXT');
- if not Assigned(glSecondaryColor3dEXT) then Exit;
- @glSecondaryColor3ubEXT := SDL_GL_GetProcAddress('glSecondaryColor3ubEXT');
- if not Assigned(glSecondaryColor3ubEXT) then Exit;
- @glSecondaryColor3usEXT := SDL_GL_GetProcAddress('glSecondaryColor3usEXT');
- if not Assigned(glSecondaryColor3usEXT) then Exit;
- @glSecondaryColor3uiEXT := SDL_GL_GetProcAddress('glSecondaryColor3uiEXT');
- if not Assigned(glSecondaryColor3uiEXT) then Exit;
- @glSecondaryColor3bvEXT := SDL_GL_GetProcAddress('glSecondaryColor3bvEXT');
- if not Assigned(glSecondaryColor3bvEXT) then Exit;
- @glSecondaryColor3svEXT := SDL_GL_GetProcAddress('glSecondaryColor3svEXT');
- if not Assigned(glSecondaryColor3svEXT) then Exit;
- @glSecondaryColor3ivEXT := SDL_GL_GetProcAddress('glSecondaryColor3ivEXT');
- if not Assigned(glSecondaryColor3ivEXT) then Exit;
- @glSecondaryColor3fvEXT := SDL_GL_GetProcAddress('glSecondaryColor3fvEXT');
- if not Assigned(glSecondaryColor3fvEXT) then Exit;
- @glSecondaryColor3dvEXT := SDL_GL_GetProcAddress('glSecondaryColor3dvEXT');
- if not Assigned(glSecondaryColor3dvEXT) then Exit;
- @glSecondaryColor3ubvEXT := SDL_GL_GetProcAddress('glSecondaryColor3ubvEXT');
- if not Assigned(glSecondaryColor3ubvEXT) then Exit;
- @glSecondaryColor3usvEXT := SDL_GL_GetProcAddress('glSecondaryColor3usvEXT');
- if not Assigned(glSecondaryColor3usvEXT) then Exit;
- @glSecondaryColor3uivEXT := SDL_GL_GetProcAddress('glSecondaryColor3uivEXT');
- if not Assigned(glSecondaryColor3uivEXT) then Exit;
- @glSecondaryColorPointerEXT := SDL_GL_GetProcAddress('glSecondaryColorPointerEXT');
- if not Assigned(glSecondaryColorPointerEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_mirror_clamp: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_texture_mirror_clamp', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_blend_equation_separate: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_blend_equation_separate', extstring) then
- begin
- @glBlendEquationSeparateEXT := SDL_GL_GetProcAddress('glBlendEquationSeparateEXT');
- if not Assigned(glBlendEquationSeparateEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_MESA_pack_invert: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_MESA_pack_invert', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_MESA_ycbcr_texture: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_MESA_ycbcr_texture', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_fragment_program_shadow: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_ARB_fragment_program_shadow', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_fog_coord: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_fog_coord', extstring) then
- begin
- @glFogCoordfEXT := SDL_GL_GetProcAddress('glFogCoordfEXT');
- if not Assigned(glFogCoordfEXT) then Exit;
- @glFogCoorddEXT := SDL_GL_GetProcAddress('glFogCoorddEXT');
- if not Assigned(glFogCoorddEXT) then Exit;
- @glFogCoordfvEXT := SDL_GL_GetProcAddress('glFogCoordfvEXT');
- if not Assigned(glFogCoordfvEXT) then Exit;
- @glFogCoorddvEXT := SDL_GL_GetProcAddress('glFogCoorddvEXT');
- if not Assigned(glFogCoorddvEXT) then Exit;
- @glFogCoordPointerEXT := SDL_GL_GetProcAddress('glFogCoordPointerEXT');
- if not Assigned(glFogCoordPointerEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_fragment_program_option: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_fragment_program_option', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_pixel_buffer_object: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_EXT_pixel_buffer_object', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_fragment_program2: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_fragment_program2', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_program2_option: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_program2_option', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_NV_vertex_program3: Boolean;
-var
- extstring : PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString( GL_EXTENSIONS );
-
- if glext_ExtensionSupported('GL_NV_vertex_program3', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_draw_buffers: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_draw_buffers', extstring) then
- begin
- glDrawBuffersARB := SDL_GL_GetProcAddress('glDrawBuffersARB');
- if not Assigned(glDrawBuffersARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_rectangle: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_texture_rectangle', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_color_buffer_float: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_color_buffer_float', extstring) then
- begin
- glClampColorARB := SDL_GL_GetProcAddress('glClampColorARB');
- if not Assigned(glClampColorARB) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_half_float_pixel: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_half_float_pixel', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_texture_float: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_texture_float', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_texture_compression_dxt1: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_EXT_texture_compression_dxt1', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_ARB_pixel_buffer_object: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_ARB_pixel_buffer_object', extstring) then
- begin
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_EXT_framebuffer_object: Boolean;
-var
- extstring: PChar;
-begin
-
- Result := FALSE;
- extstring := glGetString(GL_EXTENSIONS);
-
- if glext_ExtensionSupported('GL_EXT_framebuffer_object', extstring) then
- begin
- glIsRenderbufferEXT := SDL_GL_GetProcAddress('glIsRenderbufferEXT');
- if not Assigned(glIsRenderbufferEXT) then Exit;
- glBindRenderbufferEXT := SDL_GL_GetProcAddress('glBindRenderbufferEXT');
- if not Assigned(glBindRenderbufferEXT) then Exit;
- glDeleteRenderbuffersEXT := SDL_GL_GetProcAddress('glDeleteRenderbuffersEXT');
- if not Assigned(glDeleteRenderbuffersEXT) then Exit;
- glGenRenderbuffersEXT := SDL_GL_GetProcAddress('glGenRenderbuffersEXT');
- if not Assigned(glGenRenderbuffersEXT) then Exit;
- glRenderbufferStorageEXT := SDL_GL_GetProcAddress('glRenderbufferStorageEXT');
- if not Assigned(glRenderbufferStorageEXT) then Exit;
- glGetRenderbufferParameterivEXT := SDL_GL_GetProcAddress('glGetRenderbufferParameterivEXT');
- if not Assigned(glGetRenderbufferParameterivEXT) then Exit;
- glIsFramebufferEXT := SDL_GL_GetProcAddress('glIsFramebufferEXT');
- if not Assigned(glIsFramebufferEXT) then Exit;
- glBindFramebufferEXT := SDL_GL_GetProcAddress('glBindFramebufferEXT');
- if not Assigned(glBindFramebufferEXT) then Exit;
- glDeleteFramebuffersEXT := SDL_GL_GetProcAddress('glDeleteFramebuffersEXT');
- if not Assigned(glDeleteFramebuffersEXT) then Exit;
- glGenFramebuffersEXT := SDL_GL_GetProcAddress('glGenFramebuffersEXT');
- if not Assigned(glGenFramebuffersEXT) then Exit;
- glCheckFramebufferStatusEXT := SDL_GL_GetProcAddress('glCheckFramebufferStatusEXT');
- if not Assigned(glCheckFramebufferStatusEXT) then Exit;
- glFramebufferTexture1DEXT := SDL_GL_GetProcAddress('glFramebufferTexture1DEXT');
- if not Assigned(glFramebufferTexture1DEXT) then Exit;
- glFramebufferTexture2DEXT := SDL_GL_GetProcAddress('glFramebufferTexture2DEXT');
- if not Assigned(glFramebufferTexture2DEXT) then Exit;
- glFramebufferTexture3DEXT := SDL_GL_GetProcAddress('glFramebufferTexture3DEXT');
- if not Assigned(glFramebufferTexture3DEXT) then Exit;
- glFramebufferRenderbufferEXT := SDL_GL_GetProcAddress('glFramebufferRenderbufferEXT');
- if not Assigned(glFramebufferRenderbufferEXT) then Exit;
- glGetFramebufferAttachmentParameterivEXT := SDL_GL_GetProcAddress('glGetFramebufferAttachmentParameterivEXT');
- if not Assigned(glGetFramebufferAttachmentParameterivEXT) then Exit;
- glGenerateMipmapEXT := SDL_GL_GetProcAddress('glGenerateMipmapEXT');
- if not Assigned(glGenerateMipmapEXT) then Exit;
- Result := TRUE;
- end;
-
-end;
-
-function Load_GL_version_1_4: Boolean;
-var
- extstring: String;
-begin
-
- Result := FALSE;
- extstring := String(PChar(glGetString(GL_EXTENSIONS)));
-
- glBlendFuncSeparate := SDL_GL_GetProcAddress('glBlendFuncSeparate');
- if not Assigned(glBlendFuncSeparate) then Exit;
- glFogCoordf := SDL_GL_GetProcAddress('glFogCoordf');
- if not Assigned(glFogCoordf) then Exit;
- glFogCoordfv := SDL_GL_GetProcAddress('glFogCoordfv');
- if not Assigned(glFogCoordfv) then Exit;
- glFogCoordd := SDL_GL_GetProcAddress('glFogCoordd');
- if not Assigned(glFogCoordd) then Exit;
- glFogCoorddv := SDL_GL_GetProcAddress('glFogCoorddv');
- if not Assigned(glFogCoorddv) then Exit;
- glFogCoordPointer := SDL_GL_GetProcAddress('glFogCoordPointer');
- if not Assigned(glFogCoordPointer) then Exit;
- glMultiDrawArrays := SDL_GL_GetProcAddress('glMultiDrawArrays');
- if not Assigned(glMultiDrawArrays) then Exit;
- glMultiDrawElements := SDL_GL_GetProcAddress('glMultiDrawElements');
- if not Assigned(glMultiDrawElements) then Exit;
- glPointParameterf := SDL_GL_GetProcAddress('glPointParameterf');
- if not Assigned(glPointParameterf) then Exit;
- glPointParameterfv := SDL_GL_GetProcAddress('glPointParameterfv');
- if not Assigned(glPointParameterfv) then Exit;
- glPointParameteri := SDL_GL_GetProcAddress('glPointParameteri');
- if not Assigned(glPointParameteri) then Exit;
- glPointParameteriv := SDL_GL_GetProcAddress('glPointParameteriv');
- if not Assigned(glPointParameteriv) then Exit;
- glSecondaryColor3b := SDL_GL_GetProcAddress('glSecondaryColor3b');
- if not Assigned(glSecondaryColor3b) then Exit;
- glSecondaryColor3bv := SDL_GL_GetProcAddress('glSecondaryColor3bv');
- if not Assigned(glSecondaryColor3bv) then Exit;
- glSecondaryColor3d := SDL_GL_GetProcAddress('glSecondaryColor3d');
- if not Assigned(glSecondaryColor3d) then Exit;
- glSecondaryColor3dv := SDL_GL_GetProcAddress('glSecondaryColor3dv');
- if not Assigned(glSecondaryColor3dv) then Exit;
- glSecondaryColor3f := SDL_GL_GetProcAddress('glSecondaryColor3f');
- if not Assigned(glSecondaryColor3f) then Exit;
- glSecondaryColor3fv := SDL_GL_GetProcAddress('glSecondaryColor3fv');
- if not Assigned(glSecondaryColor3fv) then Exit;
- glSecondaryColor3i := SDL_GL_GetProcAddress('glSecondaryColor3i');
- if not Assigned(glSecondaryColor3i) then Exit;
- glSecondaryColor3iv := SDL_GL_GetProcAddress('glSecondaryColor3iv');
- if not Assigned(glSecondaryColor3iv) then Exit;
- glSecondaryColor3s := SDL_GL_GetProcAddress('glSecondaryColor3s');
- if not Assigned(glSecondaryColor3s) then Exit;
- glSecondaryColor3sv := SDL_GL_GetProcAddress('glSecondaryColor3sv');
- if not Assigned(glSecondaryColor3sv) then Exit;
- glSecondaryColor3ub := SDL_GL_GetProcAddress('glSecondaryColor3ub');
- if not Assigned(glSecondaryColor3ub) then Exit;
- glSecondaryColor3ubv := SDL_GL_GetProcAddress('glSecondaryColor3ubv');
- if not Assigned(glSecondaryColor3ubv) then Exit;
- glSecondaryColor3ui := SDL_GL_GetProcAddress('glSecondaryColor3ui');
- if not Assigned(glSecondaryColor3ui) then Exit;
- glSecondaryColor3uiv := SDL_GL_GetProcAddress('glSecondaryColor3uiv');
- if not Assigned(glSecondaryColor3uiv) then Exit;
- glSecondaryColor3us := SDL_GL_GetProcAddress('glSecondaryColor3us');
- if not Assigned(glSecondaryColor3us) then Exit;
- glSecondaryColor3usv := SDL_GL_GetProcAddress('glSecondaryColor3usv');
- if not Assigned(glSecondaryColor3usv) then Exit;
- glSecondaryColorPointer := SDL_GL_GetProcAddress('glSecondaryColorPointer');
- if not Assigned(glSecondaryColorPointer) then Exit;
- glWindowPos2d := SDL_GL_GetProcAddress('glWindowPos2d');
- if not Assigned(glWindowPos2d) then Exit;
- glWindowPos2dv := SDL_GL_GetProcAddress('glWindowPos2dv');
- if not Assigned(glWindowPos2dv) then Exit;
- glWindowPos2f := SDL_GL_GetProcAddress('glWindowPos2f');
- if not Assigned(glWindowPos2f) then Exit;
- glWindowPos2fv := SDL_GL_GetProcAddress('glWindowPos2fv');
- if not Assigned(glWindowPos2fv) then Exit;
- glWindowPos2i := SDL_GL_GetProcAddress('glWindowPos2i');
- if not Assigned(glWindowPos2i) then Exit;
- glWindowPos2iv := SDL_GL_GetProcAddress('glWindowPos2iv');
- if not Assigned(glWindowPos2iv) then Exit;
- glWindowPos2s := SDL_GL_GetProcAddress('glWindowPos2s');
- if not Assigned(glWindowPos2s) then Exit;
- glWindowPos2sv := SDL_GL_GetProcAddress('glWindowPos2sv');
- if not Assigned(glWindowPos2sv) then Exit;
- glWindowPos3d := SDL_GL_GetProcAddress('glWindowPos3d');
- if not Assigned(glWindowPos3d) then Exit;
- glWindowPos3dv := SDL_GL_GetProcAddress('glWindowPos3dv');
- if not Assigned(glWindowPos3dv) then Exit;
- glWindowPos3f := SDL_GL_GetProcAddress('glWindowPos3f');
- if not Assigned(glWindowPos3f) then Exit;
- glWindowPos3fv := SDL_GL_GetProcAddress('glWindowPos3fv');
- if not Assigned(glWindowPos3fv) then Exit;
- glWindowPos3i := SDL_GL_GetProcAddress('glWindowPos3i');
- if not Assigned(glWindowPos3i) then Exit;
- glWindowPos3iv := SDL_GL_GetProcAddress('glWindowPos3iv');
- if not Assigned(glWindowPos3iv) then Exit;
- glWindowPos3s := SDL_GL_GetProcAddress('glWindowPos3s');
- if not Assigned(glWindowPos3s) then Exit;
- glWindowPos3sv := SDL_GL_GetProcAddress('glWindowPos3sv');
- if not Assigned(glWindowPos3sv) then Exit;
- Result := TRUE;
-
-end;
-
-function Load_GL_version_1_5: Boolean;
-var
- extstring: String;
-begin
-
- Result := FALSE;
- extstring := String(PChar(glGetString(GL_EXTENSIONS)));
-
- glGenQueries := SDL_GL_GetProcAddress('glGenQueries');
- if not Assigned(glGenQueries) then Exit;
- glDeleteQueries := SDL_GL_GetProcAddress('glDeleteQueries');
- if not Assigned(glDeleteQueries) then Exit;
- glIsQuery := SDL_GL_GetProcAddress('glIsQuery');
- if not Assigned(glIsQuery) then Exit;
- glBeginQuery := SDL_GL_GetProcAddress('glBeginQuery');
- if not Assigned(glBeginQuery) then Exit;
- glEndQuery := SDL_GL_GetProcAddress('glEndQuery');
- if not Assigned(glEndQuery) then Exit;
- glGetQueryiv := SDL_GL_GetProcAddress('glGetQueryiv');
- if not Assigned(glGetQueryiv) then Exit;
- glGetQueryObjectiv := SDL_GL_GetProcAddress('glGetQueryObjectiv');
- if not Assigned(glGetQueryObjectiv) then Exit;
- glGetQueryObjectuiv := SDL_GL_GetProcAddress('glGetQueryObjectuiv');
- if not Assigned(glGetQueryObjectuiv) then Exit;
- glBindBuffer := SDL_GL_GetProcAddress('glBindBuffer');
- if not Assigned(glBindBuffer) then Exit;
- glDeleteBuffers := SDL_GL_GetProcAddress('glDeleteBuffers');
- if not Assigned(glDeleteBuffers) then Exit;
- glGenBuffers := SDL_GL_GetProcAddress('glGenBuffers');
- if not Assigned(glGenBuffers) then Exit;
- glIsBuffer := SDL_GL_GetProcAddress('glIsBuffer');
- if not Assigned(glIsBuffer) then Exit;
- glBufferData := SDL_GL_GetProcAddress('glBufferData');
- if not Assigned(glBufferData) then Exit;
- glBufferSubData := SDL_GL_GetProcAddress('glBufferSubData');
- if not Assigned(glBufferSubData) then Exit;
- glGetBufferSubData := SDL_GL_GetProcAddress('glGetBufferSubData');
- if not Assigned(glGetBufferSubData) then Exit;
- glMapBuffer := SDL_GL_GetProcAddress('glMapBuffer');
- if not Assigned(glMapBuffer) then Exit;
- glUnmapBuffer := SDL_GL_GetProcAddress('glUnmapBuffer');
- if not Assigned(glUnmapBuffer) then Exit;
- glGetBufferParameteriv := SDL_GL_GetProcAddress('glGetBufferParameteriv');
- if not Assigned(glGetBufferParameteriv) then Exit;
- glGetBufferPointerv := SDL_GL_GetProcAddress('glGetBufferPointerv');
- if not Assigned(glGetBufferPointerv) then Exit;
- Result := TRUE;
-
-end;
-
-function Load_GL_version_2_0: Boolean;
-var
- extstring: String;
-begin
-
- Result := FALSE;
- extstring := String(PChar(glGetString(GL_EXTENSIONS)));
-
- glBlendEquationSeparate := SDL_GL_GetProcAddress('glBlendEquationSeparate');
- if not Assigned(glBlendEquationSeparate) then Exit;
- glDrawBuffers := SDL_GL_GetProcAddress('glDrawBuffers');
- if not Assigned(glDrawBuffers) then Exit;
- glStencilOpSeparate := SDL_GL_GetProcAddress('glStencilOpSeparate');
- if not Assigned(glStencilOpSeparate) then Exit;
- glStencilFuncSeparate := SDL_GL_GetProcAddress('glStencilFuncSeparate');
- if not Assigned(glStencilFuncSeparate) then Exit;
- glStencilMaskSeparate := SDL_GL_GetProcAddress('glStencilMaskSeparate');
- if not Assigned(glStencilMaskSeparate) then Exit;
- glAttachShader := SDL_GL_GetProcAddress('glAttachShader');
- if not Assigned(glAttachShader) then Exit;
- glBindAttribLocation := SDL_GL_GetProcAddress('glBindAttribLocation');
- if not Assigned(glBindAttribLocation) then Exit;
- glCompileShader := SDL_GL_GetProcAddress('glCompileShader');
- if not Assigned(glCompileShader) then Exit;
- glCreateProgram := SDL_GL_GetProcAddress('glCreateProgram');
- if not Assigned(glCreateProgram) then Exit;
- glCreateShader := SDL_GL_GetProcAddress('glCreateShader');
- if not Assigned(glCreateShader) then Exit;
- glDeleteProgram := SDL_GL_GetProcAddress('glDeleteProgram');
- if not Assigned(glDeleteProgram) then Exit;
- glDeleteShader := SDL_GL_GetProcAddress('glDeleteShader');
- if not Assigned(glDeleteShader) then Exit;
- glDetachShader := SDL_GL_GetProcAddress('glDetachShader');
- if not Assigned(glDetachShader) then Exit;
- glDisableVertexAttribArray := SDL_GL_GetProcAddress('glDisableVertexAttribArray');
- if not Assigned(glDisableVertexAttribArray) then Exit;
- glEnableVertexAttribArray := SDL_GL_GetProcAddress('glEnableVertexAttribArray');
- if not Assigned(glEnableVertexAttribArray) then Exit;
- glGetActiveAttrib := SDL_GL_GetProcAddress('glGetActiveAttrib');
- if not Assigned(glGetActiveAttrib) then Exit;
- glGetActiveUniform := SDL_GL_GetProcAddress('glGetActiveUniform');
- if not Assigned(glGetActiveUniform) then Exit;
- glGetAttachedShaders := SDL_GL_GetProcAddress('glGetAttachedShaders');
- if not Assigned(glGetAttachedShaders) then Exit;
- glGetAttribLocation := SDL_GL_GetProcAddress('glGetAttribLocation');
- if not Assigned(glGetAttribLocation) then Exit;
- glGetProgramiv := SDL_GL_GetProcAddress('glGetProgramiv');
- if not Assigned(glGetProgramiv) then Exit;
- glGetProgramInfoLog := SDL_GL_GetProcAddress('glGetProgramInfoLog');
- if not Assigned(glGetProgramInfoLog) then Exit;
- glGetShaderiv := SDL_GL_GetProcAddress('glGetShaderiv');
- if not Assigned(glGetShaderiv) then Exit;
- glGetShaderInfoLog := SDL_GL_GetProcAddress('glGetShaderInfoLog');
- if not Assigned(glGetShaderInfoLog) then Exit;
- glGetShaderSource := SDL_GL_GetProcAddress('glGetShaderSource');
- if not Assigned(glGetShaderSource) then Exit;
- glGetUniformLocation := SDL_GL_GetProcAddress('glGetUniformLocation');
- if not Assigned(glGetUniformLocation) then Exit;
- glGetUniformfv := SDL_GL_GetProcAddress('glGetUniformfv');
- if not Assigned(glGetUniformfv) then Exit;
- glGetUniformiv := SDL_GL_GetProcAddress('glGetUniformiv');
- if not Assigned(glGetUniformiv) then Exit;
- glGetVertexAttribdv := SDL_GL_GetProcAddress('glGetVertexAttribdv');
- if not Assigned(glGetVertexAttribdv) then Exit;
- glGetVertexAttribfv := SDL_GL_GetProcAddress('glGetVertexAttribfv');
- if not Assigned(glGetVertexAttribfv) then Exit;
- glGetVertexAttribiv := SDL_GL_GetProcAddress('glGetVertexAttribiv');
- if not Assigned(glGetVertexAttribiv) then Exit;
- glGetVertexAttribPointerv := SDL_GL_GetProcAddress('glGetVertexAttribPointerv');
- if not Assigned(glGetVertexAttribPointerv) then Exit;
- glIsProgram := SDL_GL_GetProcAddress('glIsProgram');
- if not Assigned(glIsProgram) then Exit;
- glIsShader := SDL_GL_GetProcAddress('glIsShader');
- if not Assigned(glIsShader) then Exit;
- glLinkProgram := SDL_GL_GetProcAddress('glLinkProgram');
- if not Assigned(glLinkProgram) then Exit;
- glShaderSource := SDL_GL_GetProcAddress('glShaderSource');
- if not Assigned(glShaderSource) then Exit;
- glUseProgram := SDL_GL_GetProcAddress('glUseProgram');
- if not Assigned(glUseProgram) then Exit;
- glUniform1f := SDL_GL_GetProcAddress('glUniform1f');
- if not Assigned(glUniform1f) then Exit;
- glUniform2f := SDL_GL_GetProcAddress('glUniform2f');
- if not Assigned(glUniform2f) then Exit;
- glUniform3f := SDL_GL_GetProcAddress('glUniform3f');
- if not Assigned(glUniform3f) then Exit;
- glUniform4f := SDL_GL_GetProcAddress('glUniform4f');
- if not Assigned(glUniform4f) then Exit;
- glUniform1i := SDL_GL_GetProcAddress('glUniform1i');
- if not Assigned(glUniform1i) then Exit;
- glUniform2i := SDL_GL_GetProcAddress('glUniform2i');
- if not Assigned(glUniform2i) then Exit;
- glUniform3i := SDL_GL_GetProcAddress('glUniform3i');
- if not Assigned(glUniform3i) then Exit;
- glUniform4i := SDL_GL_GetProcAddress('glUniform4i');
- if not Assigned(glUniform4i) then Exit;
- glUniform1fv := SDL_GL_GetProcAddress('glUniform1fv');
- if not Assigned(glUniform1fv) then Exit;
- glUniform2fv := SDL_GL_GetProcAddress('glUniform2fv');
- if not Assigned(glUniform2fv) then Exit;
- glUniform3fv := SDL_GL_GetProcAddress('glUniform3fv');
- if not Assigned(glUniform3fv) then Exit;
- glUniform4fv := SDL_GL_GetProcAddress('glUniform4fv');
- if not Assigned(glUniform4fv) then Exit;
- glUniform1iv := SDL_GL_GetProcAddress('glUniform1iv');
- if not Assigned(glUniform1iv) then Exit;
- glUniform2iv := SDL_GL_GetProcAddress('glUniform2iv');
- if not Assigned(glUniform2iv) then Exit;
- glUniform3iv := SDL_GL_GetProcAddress('glUniform3iv');
- if not Assigned(glUniform3iv) then Exit;
- glUniform4iv := SDL_GL_GetProcAddress('glUniform4iv');
- if not Assigned(glUniform4iv) then Exit;
- glUniformMatrix2fv := SDL_GL_GetProcAddress('glUniformMatrix2fv');
- if not Assigned(glUniformMatrix2fv) then Exit;
- glUniformMatrix3fv := SDL_GL_GetProcAddress('glUniformMatrix3fv');
- if not Assigned(glUniformMatrix3fv) then Exit;
- glUniformMatrix4fv := SDL_GL_GetProcAddress('glUniformMatrix4fv');
- if not Assigned(glUniformMatrix4fv) then Exit;
- glValidateProgram := SDL_GL_GetProcAddress('glValidateProgram');
- if not Assigned(glValidateProgram) then Exit;
- glVertexAttrib1d := SDL_GL_GetProcAddress('glVertexAttrib1d');
- if not Assigned(glVertexAttrib1d) then Exit;
- glVertexAttrib1dv := SDL_GL_GetProcAddress('glVertexAttrib1dv');
- if not Assigned(glVertexAttrib1dv) then Exit;
- glVertexAttrib1f := SDL_GL_GetProcAddress('glVertexAttrib1f');
- if not Assigned(glVertexAttrib1f) then Exit;
- glVertexAttrib1fv := SDL_GL_GetProcAddress('glVertexAttrib1fv');
- if not Assigned(glVertexAttrib1fv) then Exit;
- glVertexAttrib1s := SDL_GL_GetProcAddress('glVertexAttrib1s');
- if not Assigned(glVertexAttrib1s) then Exit;
- glVertexAttrib1sv := SDL_GL_GetProcAddress('glVertexAttrib1sv');
- if not Assigned(glVertexAttrib1sv) then Exit;
- glVertexAttrib2d := SDL_GL_GetProcAddress('glVertexAttrib2d');
- if not Assigned(glVertexAttrib2d) then Exit;
- glVertexAttrib2dv := SDL_GL_GetProcAddress('glVertexAttrib2dv');
- if not Assigned(glVertexAttrib2dv) then Exit;
- glVertexAttrib2f := SDL_GL_GetProcAddress('glVertexAttrib2f');
- if not Assigned(glVertexAttrib2f) then Exit;
- glVertexAttrib2fv := SDL_GL_GetProcAddress('glVertexAttrib2fv');
- if not Assigned(glVertexAttrib2fv) then Exit;
- glVertexAttrib2s := SDL_GL_GetProcAddress('glVertexAttrib2s');
- if not Assigned(glVertexAttrib2s) then Exit;
- glVertexAttrib2sv := SDL_GL_GetProcAddress('glVertexAttrib2sv');
- if not Assigned(glVertexAttrib2sv) then Exit;
- glVertexAttrib3d := SDL_GL_GetProcAddress('glVertexAttrib3d');
- if not Assigned(glVertexAttrib3d) then Exit;
- glVertexAttrib3dv := SDL_GL_GetProcAddress('glVertexAttrib3dv');
- if not Assigned(glVertexAttrib3dv) then Exit;
- glVertexAttrib3f := SDL_GL_GetProcAddress('glVertexAttrib3f');
- if not Assigned(glVertexAttrib3f) then Exit;
- glVertexAttrib3fv := SDL_GL_GetProcAddress('glVertexAttrib3fv');
- if not Assigned(glVertexAttrib3fv) then Exit;
- glVertexAttrib3s := SDL_GL_GetProcAddress('glVertexAttrib3s');
- if not Assigned(glVertexAttrib3s) then Exit;
- glVertexAttrib3sv := SDL_GL_GetProcAddress('glVertexAttrib3sv');
- if not Assigned(glVertexAttrib3sv) then Exit;
- glVertexAttrib4Nbv := SDL_GL_GetProcAddress('glVertexAttrib4Nbv');
- if not Assigned(glVertexAttrib4Nbv) then Exit;
- glVertexAttrib4Niv := SDL_GL_GetProcAddress('glVertexAttrib4Niv');
- if not Assigned(glVertexAttrib4Niv) then Exit;
- glVertexAttrib4Nsv := SDL_GL_GetProcAddress('glVertexAttrib4Nsv');
- if not Assigned(glVertexAttrib4Nsv) then Exit;
- glVertexAttrib4Nub := SDL_GL_GetProcAddress('glVertexAttrib4Nub');
- if not Assigned(glVertexAttrib4Nub) then Exit;
- glVertexAttrib4Nubv := SDL_GL_GetProcAddress('glVertexAttrib4Nubv');
- if not Assigned(glVertexAttrib4Nubv) then Exit;
- glVertexAttrib4Nuiv := SDL_GL_GetProcAddress('glVertexAttrib4Nuiv');
- if not Assigned(glVertexAttrib4Nuiv) then Exit;
- glVertexAttrib4Nusv := SDL_GL_GetProcAddress('glVertexAttrib4Nusv');
- if not Assigned(glVertexAttrib4Nusv) then Exit;
- glVertexAttrib4bv := SDL_GL_GetProcAddress('glVertexAttrib4bv');
- if not Assigned(glVertexAttrib4bv) then Exit;
- glVertexAttrib4d := SDL_GL_GetProcAddress('glVertexAttrib4d');
- if not Assigned(glVertexAttrib4d) then Exit;
- glVertexAttrib4dv := SDL_GL_GetProcAddress('glVertexAttrib4dv');
- if not Assigned(glVertexAttrib4dv) then Exit;
- glVertexAttrib4f := SDL_GL_GetProcAddress('glVertexAttrib4f');
- if not Assigned(glVertexAttrib4f) then Exit;
- glVertexAttrib4fv := SDL_GL_GetProcAddress('glVertexAttrib4fv');
- if not Assigned(glVertexAttrib4fv) then Exit;
- glVertexAttrib4iv := SDL_GL_GetProcAddress('glVertexAttrib4iv');
- if not Assigned(glVertexAttrib4iv) then Exit;
- glVertexAttrib4s := SDL_GL_GetProcAddress('glVertexAttrib4s');
- if not Assigned(glVertexAttrib4s) then Exit;
- glVertexAttrib4sv := SDL_GL_GetProcAddress('glVertexAttrib4sv');
- if not Assigned(glVertexAttrib4sv) then Exit;
- glVertexAttrib4ubv := SDL_GL_GetProcAddress('glVertexAttrib4ubv');
- if not Assigned(glVertexAttrib4ubv) then Exit;
- glVertexAttrib4uiv := SDL_GL_GetProcAddress('glVertexAttrib4uiv');
- if not Assigned(glVertexAttrib4uiv) then Exit;
- glVertexAttrib4usv := SDL_GL_GetProcAddress('glVertexAttrib4usv');
- if not Assigned(glVertexAttrib4usv) then Exit;
- glVertexAttribPointer := SDL_GL_GetProcAddress('glVertexAttribPointer');
- if not Assigned(glVertexAttribPointer) then Exit;
- Result := TRUE;
-
-end;
-
-function glext_LoadExtension(ext: String): Boolean;
-begin
-
- Result := FALSE;
-
- if ext = 'GL_version_1_2' then Result := Load_GL_version_1_2
- else if ext = 'GL_ARB_imaging' then Result := Load_GL_ARB_imaging
- else if ext = 'GL_version_1_3' then Result := Load_GL_version_1_3
- else if ext = 'GL_ARB_multitexture' then Result := Load_GL_ARB_multitexture
- else if ext = 'GL_ARB_transpose_matrix' then Result := Load_GL_ARB_transpose_matrix
- else if ext = 'GL_ARB_multisample' then Result := Load_GL_ARB_multisample
- else if ext = 'GL_ARB_texture_env_add' then Result := Load_GL_ARB_texture_env_add
- {$IFDEF WINDOWS}
- else if ext = 'WGL_ARB_extensions_string' then Result := Load_WGL_ARB_extensions_string
- else if ext = 'WGL_ARB_buffer_region' then Result := Load_WGL_ARB_buffer_region
- {$ENDIF}
- else if ext = 'GL_ARB_texture_cube_map' then Result := Load_GL_ARB_texture_cube_map
- else if ext = 'GL_ARB_depth_texture' then Result := Load_GL_ARB_depth_texture
- else if ext = 'GL_ARB_point_parameters' then Result := Load_GL_ARB_point_parameters
- else if ext = 'GL_ARB_shadow' then Result := Load_GL_ARB_shadow
- else if ext = 'GL_ARB_shadow_ambient' then Result := Load_GL_ARB_shadow_ambient
- else if ext = 'GL_ARB_texture_border_clamp' then Result := Load_GL_ARB_texture_border_clamp
- else if ext = 'GL_ARB_texture_compression' then Result := Load_GL_ARB_texture_compression
- else if ext = 'GL_ARB_texture_env_combine' then Result := Load_GL_ARB_texture_env_combine
- else if ext = 'GL_ARB_texture_env_crossbar' then Result := Load_GL_ARB_texture_env_crossbar
- else if ext = 'GL_ARB_texture_env_dot3' then Result := Load_GL_ARB_texture_env_dot3
- else if ext = 'GL_ARB_texture_mirrored_repeat' then Result := Load_GL_ARB_texture_mirrored_repeat
- else if ext = 'GL_ARB_vertex_blend' then Result := Load_GL_ARB_vertex_blend
- else if ext = 'GL_ARB_vertex_program' then Result := Load_GL_ARB_vertex_program
- else if ext = 'GL_ARB_window_pos' then Result := Load_GL_ARB_window_pos
- else if ext = 'GL_EXT_422_pixels' then Result := Load_GL_EXT_422_pixels
- else if ext = 'GL_EXT_abgr' then Result := Load_GL_EXT_abgr
- else if ext = 'GL_EXT_bgra' then Result := Load_GL_EXT_bgra
- else if ext = 'GL_EXT_blend_color' then Result := Load_GL_EXT_blend_color
- else if ext = 'GL_EXT_blend_func_separate' then Result := Load_GL_EXT_blend_func_separate
- else if ext = 'GL_EXT_blend_logic_op' then Result := Load_GL_EXT_blend_logic_op
- else if ext = 'GL_EXT_blend_minmax' then Result := Load_GL_EXT_blend_minmax
- else if ext = 'GL_EXT_blend_subtract' then Result := Load_GL_EXT_blend_subtract
- else if ext = 'GL_EXT_clip_volume_hint' then Result := Load_GL_EXT_clip_volume_hint
- else if ext = 'GL_EXT_color_subtable' then Result := Load_GL_EXT_color_subtable
- else if ext = 'GL_EXT_compiled_vertex_array' then Result := Load_GL_EXT_compiled_vertex_array
- else if ext = 'GL_EXT_convolution' then Result := Load_GL_EXT_convolution
- else if ext = 'GL_EXT_histogram' then Result := Load_GL_EXT_histogram
- else if ext = 'GL_EXT_multi_draw_arrays' then Result := Load_GL_EXT_multi_draw_arrays
- else if ext = 'GL_EXT_packed_pixels' then Result := Load_GL_EXT_packed_pixels
- else if ext = 'GL_EXT_paletted_texture' then Result := Load_GL_EXT_paletted_texture
- else if ext = 'GL_EXT_point_parameters' then Result := Load_GL_EXT_point_parameters
- else if ext = 'GL_EXT_polygon_offset' then Result := Load_GL_EXT_polygon_offset
- else if ext = 'GL_EXT_separate_specular_color' then Result := Load_GL_EXT_separate_specular_color
- else if ext = 'GL_EXT_shadow_funcs' then Result := Load_GL_EXT_shadow_funcs
- else if ext = 'GL_EXT_shared_texture_palette' then Result := Load_GL_EXT_shared_texture_palette
- else if ext = 'GL_EXT_stencil_two_side' then Result := Load_GL_EXT_stencil_two_side
- else if ext = 'GL_EXT_stencil_wrap' then Result := Load_GL_EXT_stencil_wrap
- else if ext = 'GL_EXT_subtexture' then Result := Load_GL_EXT_subtexture
- else if ext = 'GL_EXT_texture3D' then Result := Load_GL_EXT_texture3D
- else if ext = 'GL_EXT_texture_compression_s3tc' then Result := Load_GL_EXT_texture_compression_s3tc
- else if ext = 'GL_EXT_texture_env_add' then Result := Load_GL_EXT_texture_env_add
- else if ext = 'GL_EXT_texture_env_combine' then Result := Load_GL_EXT_texture_env_combine
- else if ext = 'GL_EXT_texture_env_dot3' then Result := Load_GL_EXT_texture_env_dot3
- else if ext = 'GL_EXT_texture_filter_anisotropic' then Result := Load_GL_EXT_texture_filter_anisotropic
- else if ext = 'GL_EXT_texture_lod_bias' then Result := Load_GL_EXT_texture_lod_bias
- else if ext = 'GL_EXT_texture_object' then Result := Load_GL_EXT_texture_object
- else if ext = 'GL_EXT_vertex_array' then Result := Load_GL_EXT_vertex_array
- else if ext = 'GL_EXT_vertex_shader' then Result := Load_GL_EXT_vertex_shader
- else if ext = 'GL_EXT_vertex_weighting' then Result := Load_GL_EXT_vertex_weighting
- else if ext = 'GL_HP_occlusion_test' then Result := Load_GL_HP_occlusion_test
- else if ext = 'GL_NV_blend_square' then Result := Load_GL_NV_blend_square
- else if ext = 'GL_NV_copy_depth_to_color' then Result := Load_GL_NV_copy_depth_to_color
- else if ext = 'GL_NV_depth_clamp' then Result := Load_GL_NV_depth_clamp
- else if ext = 'GL_NV_evaluators' then Result := Load_GL_NV_evaluators
- else if ext = 'GL_NV_fence' then Result := Load_GL_NV_fence
- else if ext = 'GL_NV_fog_distance' then Result := Load_GL_NV_fog_distance
- else if ext = 'GL_NV_light_max_exponent' then Result := Load_GL_NV_light_max_exponent
- else if ext = 'GL_NV_multisample_filter_hint' then Result := Load_GL_NV_multisample_filter_hint
- else if ext = 'GL_NV_occlusion_query' then Result := Load_GL_NV_occlusion_query
- else if ext = 'GL_NV_packed_depth_stencil' then Result := Load_GL_NV_packed_depth_stencil
- else if ext = 'GL_NV_point_sprite' then Result := Load_GL_NV_point_sprite
- else if ext = 'GL_NV_register_combiners' then Result := Load_GL_NV_register_combiners
- else if ext = 'GL_NV_register_combiners2' then Result := Load_GL_NV_register_combiners2
- else if ext = 'GL_NV_texgen_emboss' then Result := Load_GL_NV_texgen_emboss
- else if ext = 'GL_NV_texgen_reflection' then Result := Load_GL_NV_texgen_reflection
- else if ext = 'GL_NV_texture_compression_vtc' then Result := Load_GL_NV_texture_compression_vtc
- else if ext = 'GL_NV_texture_env_combine4' then Result := Load_GL_NV_texture_env_combine4
- else if ext = 'GL_NV_texture_rectangle' then Result := Load_GL_NV_texture_rectangle
- else if ext = 'GL_NV_texture_shader' then Result := Load_GL_NV_texture_shader
- else if ext = 'GL_NV_texture_shader2' then Result := Load_GL_NV_texture_shader2
- else if ext = 'GL_NV_texture_shader3' then Result := Load_GL_NV_texture_shader3
- else if ext = 'GL_NV_vertex_array_range' then Result := Load_GL_NV_vertex_array_range
- else if ext = 'GL_NV_vertex_array_range2' then Result := Load_GL_NV_vertex_array_range2
- else if ext = 'GL_NV_vertex_program' then Result := Load_GL_NV_vertex_program
- else if ext = 'GL_NV_vertex_program1_1' then Result := Load_GL_NV_vertex_program1_1
- else if ext = 'GL_ATI_element_array' then Result := Load_GL_ATI_element_array
- else if ext = 'GL_ATI_envmap_bumpmap' then Result := Load_GL_ATI_envmap_bumpmap
- else if ext = 'GL_ATI_fragment_shader' then Result := Load_GL_ATI_fragment_shader
- else if ext = 'GL_ATI_pn_triangles' then Result := Load_GL_ATI_pn_triangles
- else if ext = 'GL_ATI_texture_mirror_once' then Result := Load_GL_ATI_texture_mirror_once
- else if ext = 'GL_ATI_vertex_array_object' then Result := Load_GL_ATI_vertex_array_object
- else if ext = 'GL_ATI_vertex_streams' then Result := Load_GL_ATI_vertex_streams
- {$IFDEF WINDOWS}
- else if ext = 'WGL_I3D_image_buffer' then Result := Load_WGL_I3D_image_buffer
- else if ext = 'WGL_I3D_swap_frame_lock' then Result := Load_WGL_I3D_swap_frame_lock
- else if ext = 'WGL_I3D_swap_frame_usage' then Result := Load_WGL_I3D_swap_frame_usage
- {$ENDIF}
- else if ext = 'GL_3DFX_texture_compression_FXT1' then Result := Load_GL_3DFX_texture_compression_FXT1
- else if ext = 'GL_IBM_cull_vertex' then Result := Load_GL_IBM_cull_vertex
- else if ext = 'GL_IBM_multimode_draw_arrays' then Result := Load_GL_IBM_multimode_draw_arrays
- else if ext = 'GL_IBM_raster_pos_clip' then Result := Load_GL_IBM_raster_pos_clip
- else if ext = 'GL_IBM_texture_mirrored_repeat' then Result := Load_GL_IBM_texture_mirrored_repeat
- else if ext = 'GL_IBM_vertex_array_lists' then Result := Load_GL_IBM_vertex_array_lists
- else if ext = 'GL_MESA_resize_buffers' then Result := Load_GL_MESA_resize_buffers
- else if ext = 'GL_MESA_window_pos' then Result := Load_GL_MESA_window_pos
- else if ext = 'GL_OML_interlace' then Result := Load_GL_OML_interlace
- else if ext = 'GL_OML_resample' then Result := Load_GL_OML_resample
- else if ext = 'GL_OML_subsample' then Result := Load_GL_OML_subsample
- else if ext = 'GL_SGIS_generate_mipmap' then Result := Load_GL_SGIS_generate_mipmap
- else if ext = 'GL_SGIS_multisample' then Result := Load_GL_SGIS_multisample
- else if ext = 'GL_SGIS_pixel_texture' then Result := Load_GL_SGIS_pixel_texture
- else if ext = 'GL_SGIS_texture_border_clamp' then Result := Load_GL_SGIS_texture_border_clamp
- else if ext = 'GL_SGIS_texture_color_mask' then Result := Load_GL_SGIS_texture_color_mask
- else if ext = 'GL_SGIS_texture_edge_clamp' then Result := Load_GL_SGIS_texture_edge_clamp
- else if ext = 'GL_SGIS_texture_lod' then Result := Load_GL_SGIS_texture_lod
- else if ext = 'GL_SGIS_depth_texture' then Result := Load_GL_SGIS_depth_texture
- else if ext = 'GL_SGIX_fog_offset' then Result := Load_GL_SGIX_fog_offset
- else if ext = 'GL_SGIX_interlace' then Result := Load_GL_SGIX_interlace
- else if ext = 'GL_SGIX_shadow_ambient' then Result := Load_GL_SGIX_shadow_ambient
- else if ext = 'GL_SGI_color_matrix' then Result := Load_GL_SGI_color_matrix
- else if ext = 'GL_SGI_color_table' then Result := Load_GL_SGI_color_table
- else if ext = 'GL_SGI_texture_color_table' then Result := Load_GL_SGI_texture_color_table
- else if ext = 'GL_SUN_vertex' then Result := Load_GL_SUN_vertex
- else if ext = 'GL_ARB_fragment_program' then Result := Load_GL_ARB_fragment_program
- else if ext = 'GL_ATI_text_fragment_shader' then Result := Load_GL_ATI_text_fragment_shader
- else if ext = 'GL_APPLE_client_storage' then Result := Load_GL_APPLE_client_storage
- else if ext = 'GL_APPLE_element_array' then Result := Load_GL_APPLE_element_array
- else if ext = 'GL_APPLE_fence' then Result := Load_GL_APPLE_fence
- else if ext = 'GL_APPLE_vertex_array_object' then Result := Load_GL_APPLE_vertex_array_object
- else if ext = 'GL_APPLE_vertex_array_range' then Result := Load_GL_APPLE_vertex_array_range
- {$IFDEF WINDOWS}
- else if ext = 'WGL_ARB_pixel_format' then Result := Load_WGL_ARB_pixel_format
- else if ext = 'WGL_ARB_make_current_read' then Result := Load_WGL_ARB_make_current_read
- else if ext = 'WGL_ARB_pbuffer' then Result := Load_WGL_ARB_pbuffer
- else if ext = 'WGL_EXT_swap_control' then Result := Load_WGL_EXT_swap_control
- else if ext = 'WGL_ARB_render_texture' then Result := Load_WGL_ARB_render_texture
- else if ext = 'WGL_EXT_extensions_string' then Result := Load_WGL_EXT_extensions_string
- else if ext = 'WGL_EXT_make_current_read' then Result := Load_WGL_EXT_make_current_read
- else if ext = 'WGL_EXT_pbuffer' then Result := Load_WGL_EXT_pbuffer
- else if ext = 'WGL_EXT_pixel_format' then Result := Load_WGL_EXT_pixel_format
- else if ext = 'WGL_I3D_digital_video_control' then Result := Load_WGL_I3D_digital_video_control
- else if ext = 'WGL_I3D_gamma' then Result := Load_WGL_I3D_gamma
- else if ext = 'WGL_I3D_genlock' then Result := Load_WGL_I3D_genlock
- {$ENDIF}
- else if ext = 'GL_ARB_matrix_palette' then Result := Load_GL_ARB_matrix_palette
- else if ext = 'GL_NV_element_array' then Result := Load_GL_NV_element_array
- else if ext = 'GL_NV_float_buffer' then Result := Load_GL_NV_float_buffer
- else if ext = 'GL_NV_fragment_program' then Result := Load_GL_NV_fragment_program
- else if ext = 'GL_NV_primitive_restart' then Result := Load_GL_NV_primitive_restart
- else if ext = 'GL_NV_vertex_program2' then Result := Load_GL_NV_vertex_program2
- {$IFDEF WINDOWS}
- else if ext = 'WGL_NV_render_texture_rectangle' then Result := Load_WGL_NV_render_texture_rectangle
- {$ENDIF}
- else if ext = 'GL_NV_pixel_data_range' then Result := Load_GL_NV_pixel_data_range
- else if ext = 'GL_EXT_texture_rectangle' then Result := Load_GL_EXT_texture_rectangle
- else if ext = 'GL_S3_s3tc' then Result := Load_GL_S3_s3tc
- else if ext = 'GL_ATI_draw_buffers' then Result := Load_GL_ATI_draw_buffers
- {$IFDEF WINDOWS}
- else if ext = 'WGL_ATI_pixel_format_float' then Result := Load_WGL_ATI_pixel_format_float
- {$ENDIF}
- else if ext = 'GL_ATI_texture_env_combine3' then Result := Load_GL_ATI_texture_env_combine3
- else if ext = 'GL_ATI_texture_float' then Result := Load_GL_ATI_texture_float
- else if ext = 'GL_NV_texture_expand_normal' then Result := Load_GL_NV_texture_expand_normal
- else if ext = 'GL_NV_half_float' then Result := Load_GL_NV_half_float
- else if ext = 'GL_ATI_map_object_buffer' then Result := Load_GL_ATI_map_object_buffer
- else if ext = 'GL_ATI_separate_stencil' then Result := Load_GL_ATI_separate_stencil
- else if ext = 'GL_ATI_vertex_attrib_array_object' then Result := Load_GL_ATI_vertex_attrib_array_object
- else if ext = 'GL_ARB_vertex_buffer_object' then Result := Load_GL_ARB_vertex_buffer_object
- else if ext = 'GL_ARB_occlusion_query' then Result := Load_GL_ARB_occlusion_query
- else if ext = 'GL_ARB_shader_objects' then Result := Load_GL_ARB_shader_objects
- else if ext = 'GL_ARB_vertex_shader' then Result := Load_GL_ARB_vertex_shader
- else if ext = 'GL_ARB_fragment_shader' then Result := Load_GL_ARB_fragment_shader
- else if ext = 'GL_ARB_shading_language_100' then Result := Load_GL_ARB_shading_language_100
- else if ext = 'GL_ARB_texture_non_power_of_two' then Result := Load_GL_ARB_texture_non_power_of_two
- else if ext = 'GL_ARB_point_sprite' then Result := Load_GL_ARB_point_sprite
- else if ext = 'GL_EXT_depth_bounds_test' then Result := Load_GL_EXT_depth_bounds_test
- else if ext = 'GL_EXT_secondary_color' then Result := Load_GL_EXT_secondary_color
- else if ext = 'GL_EXT_texture_mirror_clamp' then Result := Load_GL_EXT_texture_mirror_clamp
- else if ext = 'GL_EXT_blend_equation_separate' then Result := Load_GL_EXT_blend_equation_separate
- else if ext = 'GL_MESA_pack_invert' then Result := Load_GL_MESA_pack_invert
- else if ext = 'GL_MESA_ycbcr_texture' then Result := Load_GL_MESA_ycbcr_texture
- else if ext = 'GL_ARB_fragment_program_shadow' then Result := Load_GL_ARB_fragment_program_shadow
- else if ext = 'GL_EXT_fog_coord' then Result := Load_GL_EXT_fog_coord
- else if ext = 'GL_NV_fragment_program_option' then Result := Load_GL_NV_fragment_program_option
- else if ext = 'GL_EXT_pixel_buffer_object' then Result := Load_GL_EXT_pixel_buffer_object
- else if ext = 'GL_NV_fragment_program2' then Result := Load_GL_NV_fragment_program2
- else if ext = 'GL_NV_vertex_program2_option' then Result := Load_GL_NV_vertex_program2_option
- else if ext = 'GL_NV_vertex_program3' then Result := Load_GL_NV_vertex_program3
- else if ext = 'GL_ARB_draw_buffers' then Result := Load_GL_ARB_draw_buffers
- else if ext = 'GL_ARB_texture_rectangle' then Result := Load_GL_ARB_texture_rectangle
- else if ext = 'GL_ARB_color_buffer_float' then Result := Load_GL_ARB_color_buffer_float
- else if ext = 'GL_ARB_half_float_pixel' then Result := Load_GL_ARB_half_float_pixel
- else if ext = 'GL_ARB_texture_float' then Result := Load_GL_ARB_texture_float
- else if ext = 'GL_EXT_texture_compression_dxt1' then Result := Load_GL_EXT_texture_compression_dxt1
- else if ext = 'GL_ARB_pixel_buffer_object' then Result := Load_GL_ARB_pixel_buffer_object
- else if ext = 'GL_EXT_framebuffer_object' then Result := Load_GL_EXT_framebuffer_object
- else if ext = 'GL_version_1_4' then Result := Load_GL_version_1_4
- else if ext = 'GL_version_1_5' then Result := Load_GL_version_1_5
- else if ext = 'GL_version_2_0' then Result := Load_GL_version_2_0
-
-end;
-
-end.
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glu.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glu.pas
deleted file mode 100644
index 29647d12..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glu.pas
+++ /dev/null
@@ -1,582 +0,0 @@
-unit glu;
-{
- $Id: glu.pas,v 1.8 2007/05/20 20:28:31 savage Exp $
-
- Adaption of the delphi3d.net OpenGL units to FreePascal
- Sebastian Guenther (sg@freepascal.org) in 2002
- These units are free to use
-}
-
-(*++ BUILD Version: 0004 // Increment this if a change has global effects
-
-Copyright (c) 1985-95, Microsoft Corporation
-
-Module Name:
-
- glu.h
-
-Abstract:
-
- Procedure declarations, constant definitions and macros for the OpenGL
- Utility Library.
-
---*)
-
-(*
-** Copyright 1991-1993, Silicon Graphics, Inc.
-** All Rights Reserved.
-**
-** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
-** the contents of this file may not be disclosed to third parties, copied or
-** duplicated in any form, in whole or in part, without the prior written
-** permission of Silicon Graphics, Inc.
-**
-** RESTRICTED RIGHTS LEGEND:
-** Use, duplication or disclosure by the Government is subject to restrictions
-** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
-** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
-** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
-** rights reserved under the Copyright Laws of the United States.
-*)
-
-(*
-** Return the error string associated with a particular error code.
-** This will return 0 for an invalid error code.
-**
-** The generic function prototype that can be compiled for ANSI or Unicode
-** is defined as follows:
-**
-** LPCTSTR APIENTRY gluErrorStringWIN (GLenum errCode);
-*)
-
-{******************************************************************************}
-{ }
-{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
-{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
-{ }
-{ Modified for Delphi/Kylix and FreePascal }
-{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
-{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
-{ }
-{******************************************************************************}
-
-{
- $Log: glu.pas,v $
- Revision 1.8 2007/05/20 20:28:31 savage
- Initial Changes to Handle 64 Bits
-
- Revision 1.7 2006/11/26 16:35:49 savage
- Messed up the last change to GLUtessCombineDataProc, had to reapply it. Thanks Michalis.
-
- Revision 1.6 2006/11/25 23:38:02 savage
- Changes as proposed by Michalis Kamburelis for better FPC support
-
- Revision 1.5 2006/11/20 21:20:59 savage
- Updated to work in MacOS X
-
- Revision 1.4 2005/05/22 18:52:09 savage
- Changes as suggested by Michalis Kamburelis. Thanks again.
-
- Revision 1.3 2004/10/07 21:01:29 savage
- Fix for FPC
-
- Revision 1.2 2004/08/14 22:54:30 savage
- Updated so that Library name defines are correctly defined for MacOS X.
-
- Revision 1.1 2004/03/30 21:53:54 savage
- Moved to it's own folder.
-
- Revision 1.4 2004/02/20 17:09:55 savage
- Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
-
- Revision 1.3 2004/02/14 00:23:39 savage
- As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
-
- Revision 1.2 2004/02/14 00:09:19 savage
- Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
- Revision 1.4 2003/06/02 12:32:13 savage
- Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
-
- Revision 1.3 2003/05/29 22:55:00 savage
- Make use of new DLLFunctions
-
- Revision 1.2 2003/05/27 09:39:53 savage
- Added better Gnu Pascal support.
-
- Revision 1.1 2003/05/11 13:18:03 savage
- Newest OpenGL Headers For Delphi, Kylix and FPC
-
- Revision 1.2 2002/10/13 14:36:47 sg
- * Win32 fix: The OS symbol is called "Win32", not "Windows"
-
- Revision 1.1 2002/10/13 13:57:31 sg
- * Finally, the new units are available: Match the C headers more closely;
- support for OpenGL extensions, and much more. Based on the Delphi units
- by Tom Nuydens of delphi3d.net
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-uses
-{$IFDEF __GPC__}
- gpc,
-{$ENDIF}
- moduleloader,
- gl;
-
-const
-{$IFDEF WINDOWS}
- GLuLibName = 'glu32.dll';
-{$ENDIF}
-
-{$IFDEF UNIX}
-{$IFDEF DARWIN}
- GLuLibName = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib';
-{$ELSE}
- GLuLibName = 'libGLU.so';
-{$ENDIF}
-{$ENDIF}
-
-type
- TViewPortArray = array[ 0..3 ] of GLint;
- T16dArray = array[ 0..15 ] of GLdouble;
- TCallBack = procedure;
- T3dArray = array[ 0..2 ] of GLdouble;
- T4pArray = array[ 0..3 ] of Pointer;
- T4fArray = array[ 0..3 ] of GLfloat;
-{$IFNDEF __GPC__}
- PPointer = ^Pointer;
-{$ENDIF}
-
-var
- gluErrorString : function( errCode : GLenum ) : PChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluErrorUnicodeStringEXT : function( errCode : GLenum ) : PWideChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluGetString : function( name : GLenum ) : PChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluOrtho2D : procedure( left, right, bottom, top : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluPerspective : procedure( fovy, aspect, zNear, zFar : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluPickMatrix : procedure( x, y, width, height : GLdouble; var viewport : TViewPortArray ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluLookAt : procedure( eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluProject : function( objx, objy, objz : GLdouble; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray; winx, winy, winz : PGLdouble ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluUnProject : function( winx, winy, winz : GLdouble; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray; objx, objy, objz : PGLdouble ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluScaleImage : function( format : GLenum; widthin, heightin : GLint; typein : GLenum; const datain : Pointer; widthout, heightout : GLint; typeout : GLenum; dataout : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluBuild1DMipmaps : function( target : GLenum; components, width : GLint; format, atype : GLenum; const data : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluBuild2DMipmaps : function( target : GLenum; components, width, height : GLint; format, atype : GLenum; const data : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
-type
- GLUnurbs = record
- end; PGLUnurbs = ^GLUnurbs;
- GLUquadric = record
- end; PGLUquadric = ^GLUquadric;
- GLUtesselator = record
- end; PGLUtesselator = ^GLUtesselator;
-
- // backwards compatibility:
- GLUnurbsObj = GLUnurbs; PGLUnurbsObj = PGLUnurbs;
- GLUquadricObj = GLUquadric; PGLUquadricObj = PGLUquadric;
- GLUtesselatorObj = GLUtesselator; PGLUtesselatorObj = PGLUtesselator;
- GLUtriangulatorObj = GLUtesselator; PGLUtriangulatorObj = PGLUtesselator;
-
-var
- gluNewQuadric : function : PGLUquadric; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluDeleteQuadric : procedure( state : PGLUquadric ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluQuadricNormals : procedure( quadObject : PGLUquadric; normals : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluQuadricTexture : procedure( quadObject : PGLUquadric; textureCoords : GLboolean ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluQuadricOrientation : procedure( quadObject : PGLUquadric; orientation : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluQuadricDrawStyle : procedure( quadObject : PGLUquadric; drawStyle : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluCylinder : procedure( qobj : PGLUquadric; baseRadius, topRadius, height : GLdouble; slices, stacks : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluDisk : procedure( qobj : PGLUquadric; innerRadius, outerRadius : GLdouble; slices, loops : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluPartialDisk : procedure( qobj : PGLUquadric; innerRadius, outerRadius : GLdouble; slices, loops : GLint; startAngle, sweepAngle : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluSphere : procedure( qobj : PGLuquadric; radius : GLdouble; slices, stacks : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluQuadricCallback : procedure( qobj : PGLUquadric; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNewTess : function : PGLUtesselator; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluDeleteTess : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessBeginPolygon : procedure( tess : PGLUtesselator; polygon_data : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessBeginContour : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessVertex : procedure( tess : PGLUtesselator; var coords : T3dArray; data : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessEndContour : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessEndPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessProperty : procedure( tess : PGLUtesselator; which : GLenum; value : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessNormal : procedure( tess : PGLUtesselator; x, y, z : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluTessCallback : procedure( tess : PGLUtesselator; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluGetTessProperty : procedure( tess : PGLUtesselator; which : GLenum; value : PGLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNewNurbsRenderer : function : PGLUnurbs; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluDeleteNurbsRenderer : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluBeginSurface : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluBeginCurve : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluEndCurve : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluEndSurface : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluBeginTrim : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluEndTrim : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluPwlCurve : procedure( nobj : PGLUnurbs; count : GLint; aarray : PGLfloat; stride : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNurbsCurve : procedure( nobj : PGLUnurbs; nknots : GLint; knot : PGLfloat; stride : GLint; ctlarray : PGLfloat; order : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNurbsSurface : procedure( nobj : PGLUnurbs; sknot_count : GLint; sknot : PGLfloat; tknot_count : GLint; tknot : PGLfloat; s_stride, t_stride : GLint; ctlarray : PGLfloat; sorder, torder : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluLoadSamplingMatrices : procedure( nobj : PGLUnurbs; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNurbsProperty : procedure( nobj : PGLUnurbs; aproperty : GLenum; value : GLfloat ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluGetNurbsProperty : procedure( nobj : PGLUnurbs; aproperty : GLenum; value : PGLfloat ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNurbsCallback : procedure( nobj : PGLUnurbs; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
-(**** Callback function prototypes ****)
-
-type
- // gluQuadricCallback
- GLUquadricErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
- // gluTessCallback
- GLUtessBeginProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessEdgeFlagProc = procedure( p : GLboolean ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessVertexProc = procedure( p : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessEndProc = procedure; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessCombineProc = procedure( var p1 : T3dArray; p2 : T4pArray; p3 : T4fArray; p4 : PPointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessBeginDataProc = procedure( p1 : GLenum; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessEdgeFlagDataProc = procedure( p1 : GLboolean; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessVertexDataProc = procedure( p1, p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessEndDataProc = procedure( p : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessErrorDataProc = procedure( p1 : GLenum; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- GLUtessCombineDataProc = procedure( var p1 : T3dArray; var p2 : T4pArray; var p3 : T4fArray;
- p4 : PPointer; p5 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
- // gluNurbsCallback
- GLUnurbsErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
-
-//*** Generic constants ****/
-
-const
- // Version
- GLU_VERSION_1_1 = 1;
- GLU_VERSION_1_2 = 1;
-
- // Errors: (return value 0 = no error)
- GLU_INVALID_ENUM = 100900;
- GLU_INVALID_VALUE = 100901;
- GLU_OUT_OF_MEMORY = 100902;
- GLU_INCOMPATIBLE_GL_VERSION = 100903;
-
- // StringName
- GLU_VERSION = 100800;
- GLU_EXTENSIONS = 100801;
-
- // Boolean
- GLU_TRUE = GL_TRUE;
- GLU_FALSE = GL_FALSE;
-
-
- //*** Quadric constants ****/
-
- // QuadricNormal
- GLU_SMOOTH = 100000;
- GLU_FLAT = 100001;
- GLU_NONE = 100002;
-
- // QuadricDrawStyle
- GLU_POINT = 100010;
- GLU_LINE = 100011;
- GLU_FILL = 100012;
- GLU_SILHOUETTE = 100013;
-
- // QuadricOrientation
- GLU_OUTSIDE = 100020;
- GLU_INSIDE = 100021;
-
- // Callback types:
- // GLU_ERROR = 100103;
-
-
- //*** Tesselation constants ****/
-
- GLU_TESS_MAX_COORD = 1.0E150;
-
- // TessProperty
- GLU_TESS_WINDING_RULE = 100140;
- GLU_TESS_BOUNDARY_ONLY = 100141;
- GLU_TESS_TOLERANCE = 100142;
-
- // TessWinding
- GLU_TESS_WINDING_ODD = 100130;
- GLU_TESS_WINDING_NONZERO = 100131;
- GLU_TESS_WINDING_POSITIVE = 100132;
- GLU_TESS_WINDING_NEGATIVE = 100133;
- GLU_TESS_WINDING_ABS_GEQ_TWO = 100134;
-
- // TessCallback
- GLU_TESS_BEGIN = 100100; // void (CALLBACK*)(GLenum type)
- GLU_TESS_VERTEX = 100101; // void (CALLBACK*)(void *data)
- GLU_TESS_END = 100102; // void (CALLBACK*)(void)
- GLU_TESS_ERROR = 100103; // void (CALLBACK*)(GLenum errno)
- GLU_TESS_EDGE_FLAG = 100104; // void (CALLBACK*)(GLboolean boundaryEdge)
- GLU_TESS_COMBINE = 100105; { void (CALLBACK*)(GLdouble coords[3],
- void *data[4],
- GLfloat weight[4],
- void **dataOut) }
- GLU_TESS_BEGIN_DATA = 100106; { void (CALLBACK*)(GLenum type,
- void *polygon_data) }
- GLU_TESS_VERTEX_DATA = 100107; { void (CALLBACK*)(void *data,
- void *polygon_data) }
- GLU_TESS_END_DATA = 100108; // void (CALLBACK*)(void *polygon_data)
- GLU_TESS_ERROR_DATA = 100109; { void (CALLBACK*)(GLenum errno,
- void *polygon_data) }
- GLU_TESS_EDGE_FLAG_DATA = 100110; { void (CALLBACK*)(GLboolean boundaryEdge,
- void *polygon_data) }
- GLU_TESS_COMBINE_DATA = 100111; { void (CALLBACK*)(GLdouble coords[3],
- void *data[4],
- GLfloat weight[4],
- void **dataOut,
- void *polygon_data) }
-
- // TessError
- GLU_TESS_ERROR1 = 100151;
- GLU_TESS_ERROR2 = 100152;
- GLU_TESS_ERROR3 = 100153;
- GLU_TESS_ERROR4 = 100154;
- GLU_TESS_ERROR5 = 100155;
- GLU_TESS_ERROR6 = 100156;
- GLU_TESS_ERROR7 = 100157;
- GLU_TESS_ERROR8 = 100158;
-
- GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1;
- GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2;
- GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3;
- GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4;
- GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5;
- GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6;
-
- //*** NURBS constants ****/
-
- // NurbsProperty
- GLU_AUTO_LOAD_MATRIX = 100200;
- GLU_CULLING = 100201;
- GLU_SAMPLING_TOLERANCE = 100203;
- GLU_DISPLAY_MODE = 100204;
- GLU_PARAMETRIC_TOLERANCE = 100202;
- GLU_SAMPLING_METHOD = 100205;
- GLU_U_STEP = 100206;
- GLU_V_STEP = 100207;
-
- // NurbsSampling
- GLU_PATH_LENGTH = 100215;
- GLU_PARAMETRIC_ERROR = 100216;
- GLU_DOMAIN_DISTANCE = 100217;
-
-
- // NurbsTrim
- GLU_MAP1_TRIM_2 = 100210;
- GLU_MAP1_TRIM_3 = 100211;
-
- // NurbsDisplay
- // GLU_FILL = 100012;
- GLU_OUTLINE_POLYGON = 100240;
- GLU_OUTLINE_PATCH = 100241;
-
- // NurbsCallback
- // GLU_ERROR = 100103;
-
- // NurbsErrors
- GLU_NURBS_ERROR1 = 100251;
- GLU_NURBS_ERROR2 = 100252;
- GLU_NURBS_ERROR3 = 100253;
- GLU_NURBS_ERROR4 = 100254;
- GLU_NURBS_ERROR5 = 100255;
- GLU_NURBS_ERROR6 = 100256;
- GLU_NURBS_ERROR7 = 100257;
- GLU_NURBS_ERROR8 = 100258;
- GLU_NURBS_ERROR9 = 100259;
- GLU_NURBS_ERROR10 = 100260;
- GLU_NURBS_ERROR11 = 100261;
- GLU_NURBS_ERROR12 = 100262;
- GLU_NURBS_ERROR13 = 100263;
- GLU_NURBS_ERROR14 = 100264;
- GLU_NURBS_ERROR15 = 100265;
- GLU_NURBS_ERROR16 = 100266;
- GLU_NURBS_ERROR17 = 100267;
- GLU_NURBS_ERROR18 = 100268;
- GLU_NURBS_ERROR19 = 100269;
- GLU_NURBS_ERROR20 = 100270;
- GLU_NURBS_ERROR21 = 100271;
- GLU_NURBS_ERROR22 = 100272;
- GLU_NURBS_ERROR23 = 100273;
- GLU_NURBS_ERROR24 = 100274;
- GLU_NURBS_ERROR25 = 100275;
- GLU_NURBS_ERROR26 = 100276;
- GLU_NURBS_ERROR27 = 100277;
- GLU_NURBS_ERROR28 = 100278;
- GLU_NURBS_ERROR29 = 100279;
- GLU_NURBS_ERROR30 = 100280;
- GLU_NURBS_ERROR31 = 100281;
- GLU_NURBS_ERROR32 = 100282;
- GLU_NURBS_ERROR33 = 100283;
- GLU_NURBS_ERROR34 = 100284;
- GLU_NURBS_ERROR35 = 100285;
- GLU_NURBS_ERROR36 = 100286;
- GLU_NURBS_ERROR37 = 100287;
-
-//*** Backwards compatibility for old tesselator ****/
-
-var
- gluBeginPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluNextContour : procedure( tess : PGLUtesselator; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
- gluEndPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
-
-const
- // Contours types -- obsolete!
- GLU_CW = 100120;
- GLU_CCW = 100121;
- GLU_INTERIOR = 100122;
- GLU_EXTERIOR = 100123;
- GLU_UNKNOWN = 100124;
-
- // Names without "TESS_" prefix
- GLU_BEGIN = GLU_TESS_BEGIN;
- GLU_VERTEX = GLU_TESS_VERTEX;
- GLU_END = GLU_TESS_END;
- GLU_ERROR = GLU_TESS_ERROR;
- GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG;
-
-procedure LoadGLu( const dll : PChar );
-procedure FreeGLu;
-
-implementation
-
-var
- LibGlu : TModuleHandle;
-
-procedure FreeGLu;
-begin
-
- @gluErrorString := nil;
- @gluErrorUnicodeStringEXT := nil;
- @gluGetString := nil;
- @gluOrtho2D := nil;
- @gluPerspective := nil;
- @gluPickMatrix := nil;
- @gluLookAt := nil;
- @gluProject := nil;
- @gluUnProject := nil;
- @gluScaleImage := nil;
- @gluBuild1DMipmaps := nil;
- @gluBuild2DMipmaps := nil;
- @gluNewQuadric := nil;
- @gluDeleteQuadric := nil;
- @gluQuadricNormals := nil;
- @gluQuadricTexture := nil;
- @gluQuadricOrientation := nil;
- @gluQuadricDrawStyle := nil;
- @gluCylinder := nil;
- @gluDisk := nil;
- @gluPartialDisk := nil;
- @gluSphere := nil;
- @gluQuadricCallback := nil;
- @gluNewTess := nil;
- @gluDeleteTess := nil;
- @gluTessBeginPolygon := nil;
- @gluTessBeginContour := nil;
- @gluTessVertex := nil;
- @gluTessEndContour := nil;
- @gluTessEndPolygon := nil;
- @gluTessProperty := nil;
- @gluTessNormal := nil;
- @gluTessCallback := nil;
- @gluGetTessProperty := nil;
- @gluNewNurbsRenderer := nil;
- @gluDeleteNurbsRenderer := nil;
- @gluBeginSurface := nil;
- @gluBeginCurve := nil;
- @gluEndCurve := nil;
- @gluEndSurface := nil;
- @gluBeginTrim := nil;
- @gluEndTrim := nil;
- @gluPwlCurve := nil;
- @gluNurbsCurve := nil;
- @gluNurbsSurface := nil;
- @gluLoadSamplingMatrices := nil;
- @gluNurbsProperty := nil;
- @gluGetNurbsProperty := nil;
- @gluNurbsCallback := nil;
- @gluBeginPolygon := nil;
- @gluNextContour := nil;
- @gluEndPolygon := nil;
-
- UnLoadModule( LibGlu );
-
-end;
-
-procedure LoadGLu( const dll : PChar );
-begin
-
- FreeGLu;
-
- if LoadModule( LibGlu, dll ) then
- begin
- @gluErrorString := GetModuleSymbol( LibGlu, 'gluErrorString' );
- @gluErrorUnicodeStringEXT := GetModuleSymbol( LibGlu, 'gluErrorUnicodeStringEXT' );
- @gluGetString := GetModuleSymbol( LibGlu, 'gluGetString' );
- @gluOrtho2D := GetModuleSymbol( LibGlu, 'gluOrtho2D' );
- @gluPerspective := GetModuleSymbol( LibGlu, 'gluPerspective' );
- @gluPickMatrix := GetModuleSymbol( LibGlu, 'gluPickMatrix' );
- @gluLookAt := GetModuleSymbol( LibGlu, 'gluLookAt' );
- @gluProject := GetModuleSymbol( LibGlu, 'gluProject' );
- @gluUnProject := GetModuleSymbol( LibGlu, 'gluUnProject' );
- @gluScaleImage := GetModuleSymbol( LibGlu, 'gluScaleImage' );
- @gluBuild1DMipmaps := GetModuleSymbol( LibGlu, 'gluBuild1DMipmaps' );
- @gluBuild2DMipmaps := GetModuleSymbol( LibGlu, 'gluBuild2DMipmaps' );
- @gluNewQuadric := GetModuleSymbol( LibGlu, 'gluNewQuadric' );
- @gluDeleteQuadric := GetModuleSymbol( LibGlu, 'gluDeleteQuadric' );
- @gluQuadricNormals := GetModuleSymbol( LibGlu, 'gluQuadricNormals' );
- @gluQuadricTexture := GetModuleSymbol( LibGlu, 'gluQuadricTexture' );
- @gluQuadricOrientation := GetModuleSymbol( LibGlu, 'gluQuadricOrientation' );
- @gluQuadricDrawStyle := GetModuleSymbol( LibGlu, 'gluQuadricDrawStyle' );
- @gluCylinder := GetModuleSymbol( LibGlu, 'gluCylinder' );
- @gluDisk := GetModuleSymbol( LibGlu, 'gluDisk' );
- @gluPartialDisk := GetModuleSymbol( LibGlu, 'gluPartialDisk' );
- @gluSphere := GetModuleSymbol( LibGlu, 'gluSphere' );
- @gluQuadricCallback := GetModuleSymbol( LibGlu, 'gluQuadricCallback' );
- @gluNewTess := GetModuleSymbol( LibGlu, 'gluNewTess' );
- @gluDeleteTess := GetModuleSymbol( LibGlu, 'gluDeleteTess' );
- @gluTessBeginPolygon := GetModuleSymbol( LibGlu, 'gluTessBeginPolygon' );
- @gluTessBeginContour := GetModuleSymbol( LibGlu, 'gluTessBeginContour' );
- @gluTessVertex := GetModuleSymbol( LibGlu, 'gluTessVertex' );
- @gluTessEndContour := GetModuleSymbol( LibGlu, 'gluTessEndContour' );
- @gluTessEndPolygon := GetModuleSymbol( LibGlu, 'gluTessEndPolygon' );
- @gluTessProperty := GetModuleSymbol( LibGlu, 'gluTessProperty' );
- @gluTessNormal := GetModuleSymbol( LibGlu, 'gluTessNormal' );
- @gluTessCallback := GetModuleSymbol( LibGlu, 'gluTessCallback' );
- @gluGetTessProperty := GetModuleSymbol( LibGlu, 'gluGetTessProperty' );
- @gluNewNurbsRenderer := GetModuleSymbol( LibGlu, 'gluNewNurbsRenderer' );
- @gluDeleteNurbsRenderer := GetModuleSymbol( LibGlu, 'gluDeleteNurbsRenderer' );
- @gluBeginSurface := GetModuleSymbol( LibGlu, 'gluBeginSurface' );
- @gluBeginCurve := GetModuleSymbol( LibGlu, 'gluBeginCurve' );
- @gluEndCurve := GetModuleSymbol( LibGlu, 'gluEndCurve' );
- @gluEndSurface := GetModuleSymbol( LibGlu, 'gluEndSurface' );
- @gluBeginTrim := GetModuleSymbol( LibGlu, 'gluBeginTrim' );
- @gluEndTrim := GetModuleSymbol( LibGlu, 'gluEndTrim' );
- @gluPwlCurve := GetModuleSymbol( LibGlu, 'gluPwlCurve' );
- @gluNurbsCurve := GetModuleSymbol( LibGlu, 'gluNurbsCurve' );
- @gluNurbsSurface := GetModuleSymbol( LibGlu, 'gluNurbsSurface' );
- @gluLoadSamplingMatrices := GetModuleSymbol( LibGlu, 'gluLoadSamplingMatrices' );
- @gluNurbsProperty := GetModuleSymbol( LibGlu, 'gluNurbsProperty' );
- @gluGetNurbsProperty := GetModuleSymbol( LibGlu, 'gluGetNurbsProperty' );
- @gluNurbsCallback := GetModuleSymbol( LibGlu, 'gluNurbsCallback' );
-
- @gluBeginPolygon := GetModuleSymbol( LibGlu, 'gluBeginPolygon' );
- @gluNextContour := GetModuleSymbol( LibGlu, 'gluNextContour' );
- @gluEndPolygon := GetModuleSymbol( LibGlu, 'gluEndPolygon' );
- end;
-end;
-
-initialization
-
- LoadGLu( GLuLibName );
-
-finalization
-
- FreeGLu;
-
-end.
-
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glut.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glut.pas
deleted file mode 100644
index 04f69267..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glut.pas
+++ /dev/null
@@ -1,688 +0,0 @@
-unit glut;
-{
- $Id: glut.pas,v 1.4 2007/05/20 20:28:31 savage Exp $
-
- Adaption of the delphi3d.net OpenGL units to FreePascal
- Sebastian Guenther (sg@freepascal.org) in 2002
- These units are free to use
-}
-
-// Copyright (c) Mark J. Kilgard, 1994, 1995, 1996. */
-
-(* This program is freely distributable without licensing fees and is
- provided without guarantee or warrantee expressed or implied. This
- program is -not- in the public domain. *)
-
-{******************************************************************************}
-{ }
-{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
-{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
-{ }
-{ Modified for Delphi/Kylix and FreePascal }
-{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
-{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
-{ }
-{******************************************************************************}
-
-{
- $Log: glut.pas,v $
- Revision 1.4 2007/05/20 20:28:31 savage
- Initial Changes to Handle 64 Bits
-
- Revision 1.3 2006/11/20 21:20:59 savage
- Updated to work in MacOS X
-
- Revision 1.2 2004/08/14 22:54:30 savage
- Updated so that Library name defines are correctly defined for MacOS X.
-
- Revision 1.1 2004/03/30 21:53:54 savage
- Moved to it's own folder.
-
- Revision 1.5 2004/02/20 17:09:55 savage
- Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
-
- Revision 1.4 2004/02/14 22:36:29 savage
- Fixed inconsistencies of using LoadLibrary and LoadModule.
- Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
-
- Revision 1.3 2004/02/14 00:23:39 savage
- As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
-
- Revision 1.2 2004/02/14 00:09:19 savage
- Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
- Revision 1.4 2003/06/02 12:32:13 savage
- Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-uses
-{$IFDEF __GPC__}
- system,
- gpc,
-{$ENDIF}
-
-{$IFDEF WINDOWS}
- Windows,
-{$ENDIF}
- moduleloader,
- gl;
-
-type
- {$IFNDEF __GPC__}
- PInteger = ^Integer;
- PPChar = ^PChar;
- {$ENDIF}
- TGlutVoidCallback = procedure; {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
- TGlut1IntCallback = procedure(value: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
- TGlut2IntCallback = procedure(v1, v2: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
- TGlut3IntCallback = procedure(v1, v2, v3: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
- TGlut4IntCallback = procedure(v1, v2, v3, v4: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
- TGlut1Char2IntCallback = procedure(c: Byte; v1, v2: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
-
-const
-{$IFDEF WINDOWS}
- GlutLibName = 'glut32.dll';
-{$ENDIF}
-
-{$IFDEF UNIX}
-{$IFDEF DARWIN}
- GlutLibName = '/System/Library/Frameworks/GLUT.framework/Libraries/libglut.dylib';
-{$ELSE}
- GlutLibName = 'libglut.so';
-{$ENDIF}
-{$ENDIF}
-
- GLUT_API_VERSION = 3;
- GLUT_XLIB_IMPLEMENTATION = 12;
- // Display mode bit masks.
- GLUT_RGB = 0;
- GLUT_RGBA = GLUT_RGB;
- GLUT_INDEX = 1;
- GLUT_SINGLE = 0;
- GLUT_DOUBLE = 2;
- GLUT_ACCUM = 4;
- GLUT_ALPHA = 8;
- GLUT_DEPTH = 16;
- GLUT_STENCIL = 32;
- GLUT_MULTISAMPLE = 128;
- GLUT_STEREO = 256;
- GLUT_LUMINANCE = 512;
-
- // Mouse buttons.
- GLUT_LEFT_BUTTON = 0;
- GLUT_MIDDLE_BUTTON = 1;
- GLUT_RIGHT_BUTTON = 2;
-
- // Mouse button state.
- GLUT_DOWN = 0;
- GLUT_UP = 1;
-
- // function keys
- GLUT_KEY_F1 = 1;
- GLUT_KEY_F2 = 2;
- GLUT_KEY_F3 = 3;
- GLUT_KEY_F4 = 4;
- GLUT_KEY_F5 = 5;
- GLUT_KEY_F6 = 6;
- GLUT_KEY_F7 = 7;
- GLUT_KEY_F8 = 8;
- GLUT_KEY_F9 = 9;
- GLUT_KEY_F10 = 10;
- GLUT_KEY_F11 = 11;
- GLUT_KEY_F12 = 12;
- // directional keys
- GLUT_KEY_LEFT = 100;
- GLUT_KEY_UP = 101;
- GLUT_KEY_RIGHT = 102;
- GLUT_KEY_DOWN = 103;
- GLUT_KEY_PAGE_UP = 104;
- GLUT_KEY_PAGE_DOWN = 105;
- GLUT_KEY_HOME = 106;
- GLUT_KEY_END = 107;
- GLUT_KEY_INSERT = 108;
-
- // Entry/exit state.
- GLUT_LEFT = 0;
- GLUT_ENTERED = 1;
-
- // Menu usage state.
- GLUT_MENU_NOT_IN_USE = 0;
- GLUT_MENU_IN_USE = 1;
-
- // Visibility state.
- GLUT_NOT_VISIBLE = 0;
- GLUT_VISIBLE = 1;
-
- // Window status state.
- GLUT_HIDDEN = 0;
- GLUT_FULLY_RETAINED = 1;
- GLUT_PARTIALLY_RETAINED = 2;
- GLUT_FULLY_COVERED = 3;
-
- // Color index component selection values.
- GLUT_RED = 0;
- GLUT_GREEN = 1;
- GLUT_BLUE = 2;
-
- // Layers for use.
- GLUT_NORMAL = 0;
- GLUT_OVERLAY = 1;
-
- // Stroke font constants (use these in GLUT program).
- GLUT_STROKE_ROMAN = Pointer(0);
- GLUT_STROKE_MONO_ROMAN = Pointer(1);
-
- // Bitmap font constants (use these in GLUT program).
- GLUT_BITMAP_9_BY_15 = Pointer(2);
- GLUT_BITMAP_8_BY_13 = Pointer(3);
- GLUT_BITMAP_TIMES_ROMAN_10 = Pointer(4);
- GLUT_BITMAP_TIMES_ROMAN_24 = Pointer(5);
- GLUT_BITMAP_HELVETICA_10 = Pointer(6);
- GLUT_BITMAP_HELVETICA_12 = Pointer(7);
- GLUT_BITMAP_HELVETICA_18 = Pointer(8);
-
- // glutGet parameters.
- GLUT_WINDOW_X = 100;
- GLUT_WINDOW_Y = 101;
- GLUT_WINDOW_WIDTH = 102;
- GLUT_WINDOW_HEIGHT = 103;
- GLUT_WINDOW_BUFFER_SIZE = 104;
- GLUT_WINDOW_STENCIL_SIZE = 105;
- GLUT_WINDOW_DEPTH_SIZE = 106;
- GLUT_WINDOW_RED_SIZE = 107;
- GLUT_WINDOW_GREEN_SIZE = 108;
- GLUT_WINDOW_BLUE_SIZE = 109;
- GLUT_WINDOW_ALPHA_SIZE = 110;
- GLUT_WINDOW_ACCUM_RED_SIZE = 111;
- GLUT_WINDOW_ACCUM_GREEN_SIZE = 112;
- GLUT_WINDOW_ACCUM_BLUE_SIZE = 113;
- GLUT_WINDOW_ACCUM_ALPHA_SIZE = 114;
- GLUT_WINDOW_DOUBLEBUFFER = 115;
- GLUT_WINDOW_RGBA = 116;
- GLUT_WINDOW_PARENT = 117;
- GLUT_WINDOW_NUM_CHILDREN = 118;
- GLUT_WINDOW_COLORMAP_SIZE = 119;
- GLUT_WINDOW_NUM_SAMPLES = 120;
- GLUT_WINDOW_STEREO = 121;
- GLUT_WINDOW_CURSOR = 122;
- GLUT_SCREEN_WIDTH = 200;
- GLUT_SCREEN_HEIGHT = 201;
- GLUT_SCREEN_WIDTH_MM = 202;
- GLUT_SCREEN_HEIGHT_MM = 203;
- GLUT_MENU_NUM_ITEMS = 300;
- GLUT_DISPLAY_MODE_POSSIBLE = 400;
- GLUT_INIT_WINDOW_X = 500;
- GLUT_INIT_WINDOW_Y = 501;
- GLUT_INIT_WINDOW_WIDTH = 502;
- GLUT_INIT_WINDOW_HEIGHT = 503;
- GLUT_INIT_DISPLAY_MODE = 504;
- GLUT_ELAPSED_TIME = 700;
-
- // glutDeviceGet parameters.
- GLUT_HAS_KEYBOARD = 600;
- GLUT_HAS_MOUSE = 601;
- GLUT_HAS_SPACEBALL = 602;
- GLUT_HAS_DIAL_AND_BUTTON_BOX = 603;
- GLUT_HAS_TABLET = 604;
- GLUT_NUM_MOUSE_BUTTONS = 605;
- GLUT_NUM_SPACEBALL_BUTTONS = 606;
- GLUT_NUM_BUTTON_BOX_BUTTONS = 607;
- GLUT_NUM_DIALS = 608;
- GLUT_NUM_TABLET_BUTTONS = 609;
-
- // glutLayerGet parameters.
- GLUT_OVERLAY_POSSIBLE = 800;
- GLUT_LAYER_IN_USE = 801;
- GLUT_HAS_OVERLAY = 802;
- GLUT_TRANSPARENT_INDEX = 803;
- GLUT_NORMAL_DAMAGED = 804;
- GLUT_OVERLAY_DAMAGED = 805;
-
- // glutVideoResizeGet parameters.
- GLUT_VIDEO_RESIZE_POSSIBLE = 900;
- GLUT_VIDEO_RESIZE_IN_USE = 901;
- GLUT_VIDEO_RESIZE_X_DELTA = 902;
- GLUT_VIDEO_RESIZE_Y_DELTA = 903;
- GLUT_VIDEO_RESIZE_WIDTH_DELTA = 904;
- GLUT_VIDEO_RESIZE_HEIGHT_DELTA = 905;
- GLUT_VIDEO_RESIZE_X = 906;
- GLUT_VIDEO_RESIZE_Y = 907;
- GLUT_VIDEO_RESIZE_WIDTH = 908;
- GLUT_VIDEO_RESIZE_HEIGHT = 909;
-
- // glutGetModifiers return mask.
- GLUT_ACTIVE_SHIFT = 1;
- GLUT_ACTIVE_CTRL = 2;
- GLUT_ACTIVE_ALT = 4;
-
- // glutSetCursor parameters.
- // Basic arrows.
- GLUT_CURSOR_RIGHT_ARROW = 0;
- GLUT_CURSOR_LEFT_ARROW = 1;
- // Symbolic cursor shapes.
- GLUT_CURSOR_INFO = 2;
- GLUT_CURSOR_DESTROY = 3;
- GLUT_CURSOR_HELP = 4;
- GLUT_CURSOR_CYCLE = 5;
- GLUT_CURSOR_SPRAY = 6;
- GLUT_CURSOR_WAIT = 7;
- GLUT_CURSOR_TEXT = 8;
- GLUT_CURSOR_CROSSHAIR = 9;
- // Directional cursors.
- GLUT_CURSOR_UP_DOWN = 10;
- GLUT_CURSOR_LEFT_RIGHT = 11;
- // Sizing cursors.
- GLUT_CURSOR_TOP_SIDE = 12;
- GLUT_CURSOR_BOTTOM_SIDE = 13;
- GLUT_CURSOR_LEFT_SIDE = 14;
- GLUT_CURSOR_RIGHT_SIDE = 15;
- GLUT_CURSOR_TOP_LEFT_CORNER = 16;
- GLUT_CURSOR_TOP_RIGHT_CORNER = 17;
- GLUT_CURSOR_BOTTOM_RIGHT_CORNER = 18;
- GLUT_CURSOR_BOTTOM_LEFT_CORNER = 19;
- // Inherit from parent window.
- GLUT_CURSOR_INHERIT = 100;
- // Blank cursor.
- GLUT_CURSOR_NONE = 101;
- // Fullscreen crosshair (if available).
- GLUT_CURSOR_FULL_CROSSHAIR = 102;
-
- // GLUT game mode sub-API.
- // glutGameModeGet.
- GLUT_GAME_MODE_ACTIVE = 0;
- GLUT_GAME_MODE_POSSIBLE = 1;
- GLUT_GAME_MODE_WIDTH = 2;
- GLUT_GAME_MODE_HEIGHT = 3;
- GLUT_GAME_MODE_PIXEL_DEPTH = 4;
- GLUT_GAME_MODE_REFRESH_RATE = 5;
- GLUT_GAME_MODE_DISPLAY_CHANGED = 6;
-
-var
-// GLUT initialization sub-API.
- glutInit: procedure(argcp: PInteger; argv: PPChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutInitDisplayMode: procedure(mode: Word); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutInitDisplayString: procedure(const str: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutInitWindowPosition: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutInitWindowSize: procedure(width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutMainLoop: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT window sub-API.
- glutCreateWindow: function(const title: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutCreateSubWindow: function(win, x, y, width, height: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutDestroyWindow: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPostRedisplay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPostWindowRedisplay: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSwapBuffers: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutGetWindow: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetWindow: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetWindowTitle: procedure(const title: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetIconTitle: procedure(const title: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPositionWindow: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutReshapeWindow: procedure(width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPopWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPushWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutIconifyWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutShowWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutHideWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutFullScreen: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetCursor: procedure(cursor: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWarpPointer: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT overlay sub-API.
- glutEstablishOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutRemoveOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutUseLayer: procedure(layer: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPostOverlayRedisplay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPostWindowOverlayRedisplay: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutShowOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutHideOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT menu sub-API.
- glutCreateMenu: function(callback: TGlut1IntCallback): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutDestroyMenu: procedure(menu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutGetMenu: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetMenu: procedure(menu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutAddMenuEntry: procedure(const caption: PChar; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutAddSubMenu: procedure(const caption: PChar; submenu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutChangeToMenuEntry: procedure(item: Integer; const caption: PChar; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutChangeToSubMenu: procedure(item: Integer; const caption: PChar; submenu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutRemoveMenuItem: procedure(item: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutAttachMenu: procedure(button: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutDetachMenu: procedure(button: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUTsub-API.
- glutDisplayFunc: procedure(f: TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutReshapeFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutKeyboardFunc: procedure(f: TGlut1Char2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutMouseFunc: procedure(f: TGlut4IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutPassiveMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutEntryFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutVisibilityFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutIdleFunc: procedure(f: TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutTimerFunc: procedure(millis: Word; f: TGlut1IntCallback; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutMenuStateFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSpecialFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSpaceballMotionFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSpaceballRotateFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSpaceballButtonFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutButtonBoxFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutDialsFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutTabletMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutTabletButtonFunc: procedure(f: TGlut4IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutMenuStatusFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutOverlayDisplayFunc: procedure(f:TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWindowStatusFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT color index sub-API.
- glutSetColor: procedure(cell: Integer; red, green, blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutGetColor: function(ndx, component: Integer): GLfloat; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutCopyColormap: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT state retrieval sub-API.
- glutGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutDeviceGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT extension support sub-API
- glutExtensionSupported: function(const name: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutGetModifiers: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutLayerGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT font sub-API
- glutBitmapCharacter: procedure(font : pointer; character: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutBitmapWidth: function(font : pointer; character: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutStrokeCharacter: procedure(font : pointer; character: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutStrokeWidth: function(font : pointer; character: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutBitmapLength: function(font: pointer; const str: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutStrokeLength: function(font: pointer; const str: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT pre-built models sub-API
- glutWireSphere: procedure(radius: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidSphere: procedure(radius: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireCone: procedure(base, height: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidCone: procedure(base, height: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireCube: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidCube: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireTorus: procedure(innerRadius, outerRadius: GLdouble; sides, rings: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidTorus: procedure(innerRadius, outerRadius: GLdouble; sides, rings: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireDodecahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidDodecahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireTeapot: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidTeapot: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireOctahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidOctahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireTetrahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidTetrahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutWireIcosahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSolidIcosahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT video resize sub-API.
- glutVideoResizeGet: function(param: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutSetupVideoResizing: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutStopVideoResizing: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutVideoResize: procedure(x, y, width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutVideoPan: procedure(x, y, width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-// GLUT debugging sub-API.
- glutReportErrors: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-var
- //example glutGameModeString('1280x1024:32@75');
- glutGameModeString : procedure (const AString : PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutEnterGameMode : function : integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutLeaveGameMode : procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- glutGameModeGet : function (mode : GLenum) : integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
-
-procedure LoadGlut(const dll: PChar);
-procedure FreeGlut;
-
-implementation
-
-var
- LibGLUT : TModuleHandle;
-
-procedure FreeGlut;
-begin
-
- UnLoadModule( LibGLUT );
-
- @glutInit := nil;
- @glutInitDisplayMode := nil;
- @glutInitDisplayString := nil;
- @glutInitWindowPosition := nil;
- @glutInitWindowSize := nil;
- @glutMainLoop := nil;
- @glutCreateWindow := nil;
- @glutCreateSubWindow := nil;
- @glutDestroyWindow := nil;
- @glutPostRedisplay := nil;
- @glutPostWindowRedisplay := nil;
- @glutSwapBuffers := nil;
- @glutGetWindow := nil;
- @glutSetWindow := nil;
- @glutSetWindowTitle := nil;
- @glutSetIconTitle := nil;
- @glutPositionWindow := nil;
- @glutReshapeWindow := nil;
- @glutPopWindow := nil;
- @glutPushWindow := nil;
- @glutIconifyWindow := nil;
- @glutShowWindow := nil;
- @glutHideWindow := nil;
- @glutFullScreen := nil;
- @glutSetCursor := nil;
- @glutWarpPointer := nil;
- @glutEstablishOverlay := nil;
- @glutRemoveOverlay := nil;
- @glutUseLayer := nil;
- @glutPostOverlayRedisplay := nil;
- @glutPostWindowOverlayRedisplay := nil;
- @glutShowOverlay := nil;
- @glutHideOverlay := nil;
- @glutCreateMenu := nil;
- @glutDestroyMenu := nil;
- @glutGetMenu := nil;
- @glutSetMenu := nil;
- @glutAddMenuEntry := nil;
- @glutAddSubMenu := nil;
- @glutChangeToMenuEntry := nil;
- @glutChangeToSubMenu := nil;
- @glutRemoveMenuItem := nil;
- @glutAttachMenu := nil;
- @glutDetachMenu := nil;
- @glutDisplayFunc := nil;
- @glutReshapeFunc := nil;
- @glutKeyboardFunc := nil;
- @glutMouseFunc := nil;
- @glutMotionFunc := nil;
- @glutPassiveMotionFunc := nil;
- @glutEntryFunc := nil;
- @glutVisibilityFunc := nil;
- @glutIdleFunc := nil;
- @glutTimerFunc := nil;
- @glutMenuStateFunc := nil;
- @glutSpecialFunc := nil;
- @glutSpaceballMotionFunc := nil;
- @glutSpaceballRotateFunc := nil;
- @glutSpaceballButtonFunc := nil;
- @glutButtonBoxFunc := nil;
- @glutDialsFunc := nil;
- @glutTabletMotionFunc := nil;
- @glutTabletButtonFunc := nil;
- @glutMenuStatusFunc := nil;
- @glutOverlayDisplayFunc := nil;
- @glutWindowStatusFunc := nil;
- @glutSetColor := nil;
- @glutGetColor := nil;
- @glutCopyColormap := nil;
- @glutGet := nil;
- @glutDeviceGet := nil;
- @glutExtensionSupported := nil;
- @glutGetModifiers := nil;
- @glutLayerGet := nil;
- @glutBitmapCharacter := nil;
- @glutBitmapWidth := nil;
- @glutStrokeCharacter := nil;
- @glutStrokeWidth := nil;
- @glutBitmapLength := nil;
- @glutStrokeLength := nil;
- @glutWireSphere := nil;
- @glutSolidSphere := nil;
- @glutWireCone := nil;
- @glutSolidCone := nil;
- @glutWireCube := nil;
- @glutSolidCube := nil;
- @glutWireTorus := nil;
- @glutSolidTorus := nil;
- @glutWireDodecahedron := nil;
- @glutSolidDodecahedron := nil;
- @glutWireTeapot := nil;
- @glutSolidTeapot := nil;
- @glutWireOctahedron := nil;
- @glutSolidOctahedron := nil;
- @glutWireTetrahedron := nil;
- @glutSolidTetrahedron := nil;
- @glutWireIcosahedron := nil;
- @glutSolidIcosahedron := nil;
- @glutVideoResizeGet := nil;
- @glutSetupVideoResizing := nil;
- @glutStopVideoResizing := nil;
- @glutVideoResize := nil;
- @glutVideoPan := nil;
- @glutReportErrors := nil;
-
-end;
-
-procedure LoadGlut(const dll: PChar);
-begin
-
- FreeGlut;
-
- if LoadModule( LibGLUT, dll ) then
- begin
- @glutInit := GetModuleSymbol(LibGLUT, 'glutInit');
- @glutInitDisplayMode := GetModuleSymbol(LibGLUT, 'glutInitDisplayMode');
- @glutInitDisplayString := GetModuleSymbol(LibGLUT, 'glutInitDisplayString');
- @glutInitWindowPosition := GetModuleSymbol(LibGLUT, 'glutInitWindowPosition');
- @glutInitWindowSize := GetModuleSymbol(LibGLUT, 'glutInitWindowSize');
- @glutMainLoop := GetModuleSymbol(LibGLUT, 'glutMainLoop');
- @glutCreateWindow := GetModuleSymbol(LibGLUT, 'glutCreateWindow');
- @glutCreateSubWindow := GetModuleSymbol(LibGLUT, 'glutCreateSubWindow');
- @glutDestroyWindow := GetModuleSymbol(LibGLUT, 'glutDestroyWindow');
- @glutPostRedisplay := GetModuleSymbol(LibGLUT, 'glutPostRedisplay');
- @glutPostWindowRedisplay := GetModuleSymbol(LibGLUT, 'glutPostWindowRedisplay');
- @glutSwapBuffers := GetModuleSymbol(LibGLUT, 'glutSwapBuffers');
- @glutGetWindow := GetModuleSymbol(LibGLUT, 'glutGetWindow');
- @glutSetWindow := GetModuleSymbol(LibGLUT, 'glutSetWindow');
- @glutSetWindowTitle := GetModuleSymbol(LibGLUT, 'glutSetWindowTitle');
- @glutSetIconTitle := GetModuleSymbol(LibGLUT, 'glutSetIconTitle');
- @glutPositionWindow := GetModuleSymbol(LibGLUT, 'glutPositionWindow');
- @glutReshapeWindow := GetModuleSymbol(LibGLUT, 'glutReshapeWindow');
- @glutPopWindow := GetModuleSymbol(LibGLUT, 'glutPopWindow');
- @glutPushWindow := GetModuleSymbol(LibGLUT, 'glutPushWindow');
- @glutIconifyWindow := GetModuleSymbol(LibGLUT, 'glutIconifyWindow');
- @glutShowWindow := GetModuleSymbol(LibGLUT, 'glutShowWindow');
- @glutHideWindow := GetModuleSymbol(LibGLUT, 'glutHideWindow');
- @glutFullScreen := GetModuleSymbol(LibGLUT, 'glutFullScreen');
- @glutSetCursor := GetModuleSymbol(LibGLUT, 'glutSetCursor');
- @glutWarpPointer := GetModuleSymbol(LibGLUT, 'glutWarpPointer');
- @glutEstablishOverlay := GetModuleSymbol(LibGLUT, 'glutEstablishOverlay');
- @glutRemoveOverlay := GetModuleSymbol(LibGLUT, 'glutRemoveOverlay');
- @glutUseLayer := GetModuleSymbol(LibGLUT, 'glutUseLayer');
- @glutPostOverlayRedisplay := GetModuleSymbol(LibGLUT, 'glutPostOverlayRedisplay');
- @glutPostWindowOverlayRedisplay := GetModuleSymbol(LibGLUT, 'glutPostWindowOverlayRedisplay');
- @glutShowOverlay := GetModuleSymbol(LibGLUT, 'glutShowOverlay');
- @glutHideOverlay := GetModuleSymbol(LibGLUT, 'glutHideOverlay');
- @glutCreateMenu := GetModuleSymbol(LibGLUT, 'glutCreateMenu');
- @glutDestroyMenu := GetModuleSymbol(LibGLUT, 'glutDestroyMenu');
- @glutGetMenu := GetModuleSymbol(LibGLUT, 'glutGetMenu');
- @glutSetMenu := GetModuleSymbol(LibGLUT, 'glutSetMenu');
- @glutAddMenuEntry := GetModuleSymbol(LibGLUT, 'glutAddMenuEntry');
- @glutAddSubMenu := GetModuleSymbol(LibGLUT, 'glutAddSubMenu');
- @glutChangeToMenuEntry := GetModuleSymbol(LibGLUT, 'glutChangeToMenuEntry');
- @glutChangeToSubMenu := GetModuleSymbol(LibGLUT, 'glutChangeToSubMenu');
- @glutRemoveMenuItem := GetModuleSymbol(LibGLUT, 'glutRemoveMenuItem');
- @glutAttachMenu := GetModuleSymbol(LibGLUT, 'glutAttachMenu');
- @glutDetachMenu := GetModuleSymbol(LibGLUT, 'glutDetachMenu');
- @glutDisplayFunc := GetModuleSymbol(LibGLUT, 'glutDisplayFunc');
- @glutReshapeFunc := GetModuleSymbol(LibGLUT, 'glutReshapeFunc');
- @glutKeyboardFunc := GetModuleSymbol(LibGLUT, 'glutKeyboardFunc');
- @glutMouseFunc := GetModuleSymbol(LibGLUT, 'glutMouseFunc');
- @glutMotionFunc := GetModuleSymbol(LibGLUT, 'glutMotionFunc');
- @glutPassiveMotionFunc := GetModuleSymbol(LibGLUT, 'glutPassiveMotionFunc');
- @glutEntryFunc := GetModuleSymbol(LibGLUT, 'glutEntryFunc');
- @glutVisibilityFunc := GetModuleSymbol(LibGLUT, 'glutVisibilityFunc');
- @glutIdleFunc := GetModuleSymbol(LibGLUT, 'glutIdleFunc');
- @glutTimerFunc := GetModuleSymbol(LibGLUT, 'glutTimerFunc');
- @glutMenuStateFunc := GetModuleSymbol(LibGLUT, 'glutMenuStateFunc');
- @glutSpecialFunc := GetModuleSymbol(LibGLUT, 'glutSpecialFunc');
- @glutSpaceballMotionFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballMotionFunc');
- @glutSpaceballRotateFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballRotateFunc');
- @glutSpaceballButtonFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballButtonFunc');
- @glutButtonBoxFunc := GetModuleSymbol(LibGLUT, 'glutButtonBoxFunc');
- @glutDialsFunc := GetModuleSymbol(LibGLUT, 'glutDialsFunc');
- @glutTabletMotionFunc := GetModuleSymbol(LibGLUT, 'glutTabletMotionFunc');
- @glutTabletButtonFunc := GetModuleSymbol(LibGLUT, 'glutTabletButtonFunc');
- @glutMenuStatusFunc := GetModuleSymbol(LibGLUT, 'glutMenuStatusFunc');
- @glutOverlayDisplayFunc := GetModuleSymbol(LibGLUT, 'glutOverlayDisplayFunc');
- @glutWindowStatusFunc := GetModuleSymbol(LibGLUT, 'glutWindowStatusFunc');
- @glutSetColor := GetModuleSymbol(LibGLUT, 'glutSetColor');
- @glutGetColor := GetModuleSymbol(LibGLUT, 'glutGetColor');
- @glutCopyColormap := GetModuleSymbol(LibGLUT, 'glutCopyColormap');
- @glutGet := GetModuleSymbol(LibGLUT, 'glutGet');
- @glutDeviceGet := GetModuleSymbol(LibGLUT, 'glutDeviceGet');
- @glutExtensionSupported := GetModuleSymbol(LibGLUT, 'glutExtensionSupported');
- @glutGetModifiers := GetModuleSymbol(LibGLUT, 'glutGetModifiers');
- @glutLayerGet := GetModuleSymbol(LibGLUT, 'glutLayerGet');
- @glutBitmapCharacter := GetModuleSymbol(LibGLUT, 'glutBitmapCharacter');
- @glutBitmapWidth := GetModuleSymbol(LibGLUT, 'glutBitmapWidth');
- @glutStrokeCharacter := GetModuleSymbol(LibGLUT, 'glutStrokeCharacter');
- @glutStrokeWidth := GetModuleSymbol(LibGLUT, 'glutStrokeWidth');
- @glutBitmapLength := GetModuleSymbol(LibGLUT, 'glutBitmapLength');
- @glutStrokeLength := GetModuleSymbol(LibGLUT, 'glutStrokeLength');
- @glutWireSphere := GetModuleSymbol(LibGLUT, 'glutWireSphere');
- @glutSolidSphere := GetModuleSymbol(LibGLUT, 'glutSolidSphere');
- @glutWireCone := GetModuleSymbol(LibGLUT, 'glutWireCone');
- @glutSolidCone := GetModuleSymbol(LibGLUT, 'glutSolidCone');
- @glutWireCube := GetModuleSymbol(LibGLUT, 'glutWireCube');
- @glutSolidCube := GetModuleSymbol(LibGLUT, 'glutSolidCube');
- @glutWireTorus := GetModuleSymbol(LibGLUT, 'glutWireTorus');
- @glutSolidTorus := GetModuleSymbol(LibGLUT, 'glutSolidTorus');
- @glutWireDodecahedron := GetModuleSymbol(LibGLUT, 'glutWireDodecahedron');
- @glutSolidDodecahedron := GetModuleSymbol(LibGLUT, 'glutSolidDodecahedron');
- @glutWireTeapot := GetModuleSymbol(LibGLUT, 'glutWireTeapot');
- @glutSolidTeapot := GetModuleSymbol(LibGLUT, 'glutSolidTeapot');
- @glutWireOctahedron := GetModuleSymbol(LibGLUT, 'glutWireOctahedron');
- @glutSolidOctahedron := GetModuleSymbol(LibGLUT, 'glutSolidOctahedron');
- @glutWireTetrahedron := GetModuleSymbol(LibGLUT, 'glutWireTetrahedron');
- @glutSolidTetrahedron := GetModuleSymbol(LibGLUT, 'glutSolidTetrahedron');
- @glutWireIcosahedron := GetModuleSymbol(LibGLUT, 'glutWireIcosahedron');
- @glutSolidIcosahedron := GetModuleSymbol(LibGLUT, 'glutSolidIcosahedron');
- @glutVideoResizeGet := GetModuleSymbol(LibGLUT, 'glutVideoResizeGet');
- @glutSetupVideoResizing := GetModuleSymbol(LibGLUT, 'glutSetupVideoResizing');
- @glutStopVideoResizing := GetModuleSymbol(LibGLUT, 'glutStopVideoResizing');
- @glutVideoResize := GetModuleSymbol(LibGLUT, 'glutVideoResize');
- @glutVideoPan := GetModuleSymbol(LibGLUT, 'glutVideoPan');
- @glutReportErrors := GetModuleSymbol(LibGLUT, 'glutReportErrors');
- @glutGameModeString := GetModuleSymbol(LibGLUT, 'glutGameModeString');
- @glutEnterGameMode := GetModuleSymbol(LibGLUT, 'glutEnterGameMode');
- @glutLeaveGameMode := GetModuleSymbol(LibGLUT, 'glutLeaveGameMode');
- @glutGameModeGet := GetModuleSymbol(LibGLUT, 'glutGameModeGet');
- end;
-end;
-
-initialization
- LoadGlut( GlutLibName );
-
-finalization
- FreeGlut;
-
-end.
diff --git a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glx.pas b/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glx.pas
deleted file mode 100644
index f43a4e4c..00000000
--- a/Game/Code/lib/JEDI-SDL/OpenGL/Pas/glx.pas
+++ /dev/null
@@ -1,280 +0,0 @@
-unit glx;
-{
- $Id: glx.pas,v 1.3 2006/11/20 21:20:59 savage Exp $
-
- Translation of the Mesa GLX headers for FreePascal
- Copyright (C) 1999 Sebastian Guenther
-
-
- Mesa 3-D graphics library
- Version: 3.0
- Copyright (C) 1995-1998 Brian Paul
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-}
-
-// {$MODE delphi} // objfpc would not work because of direct proc var assignments
-
-{You have to enable Macros (compiler switch "-Sm") for compiling this unit!
- This is necessary for supporting different platforms with different calling
- conventions via a single unit.}
-
-{
- $Log: glx.pas,v $
- Revision 1.3 2006/11/20 21:20:59 savage
- Updated to work in MacOS X
-
- Revision 1.2 2006/04/18 18:38:33 savage
- fixed boolean test - thanks grudzio
-
- Revision 1.1 2004/03/30 21:53:55 savage
- Moved to it's own folder.
-
- Revision 1.5 2004/02/15 22:48:35 savage
- More FPC and FreeBSD support changes.
-
- Revision 1.4 2004/02/14 22:36:29 savage
- Fixed inconsistencies of using LoadLibrary and LoadModule.
- Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
-
- Revision 1.3 2004/02/14 00:23:39 savage
- As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
-
- Revision 1.2 2004/02/14 00:09:19 savage
- Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
-
- Revision 1.1 2004/02/05 00:08:19 savage
- Module 1.0 release
-
- Revision 1.1 2003/05/11 13:18:03 savage
- Newest OpenGL Headers For Delphi, Kylix and FPC
-
- Revision 1.1 2002/10/13 13:57:31 sg
- * Finally, the new units are available: Match the C headers more closely;
- support for OpenGL extensions, and much more. Based on the Delphi units
- by Tom Nuydens of delphi3d.net
-
-}
-
-interface
-
-{$I jedi-sdl.inc}
-
-{$IFDEF UNIX}
- uses
- {$IFDEF FPC}
- x,
- xlib,
- xutil;
- {$ELSE}
- xlib;
- {$ENDIF}
- {$DEFINE HasGLX} // Activate GLX stuff
-{$ELSE}
- {$MESSAGE Unsupported platform.}
-{$ENDIF}
-
-{$IFNDEF HasGLX}
- {$MESSAGE GLX not present on this platform.}
-{$ENDIF}
-
-
-// =======================================================
-// Unit specific extensions
-// =======================================================
-
-// Note: Requires that the GL library has already been initialized
-function InitGLX: Boolean;
-
-var
- GLXDumpUnresolvedFunctions,
- GLXInitialized: Boolean;
-
-
-// =======================================================
-// GLX consts, types and functions
-// =======================================================
-
-// Tokens for glXChooseVisual and glXGetConfig:
-const
- GLX_USE_GL = 1;
- GLX_BUFFER_SIZE = 2;
- GLX_LEVEL = 3;
- GLX_RGBA = 4;
- GLX_DOUBLEBUFFER = 5;
- GLX_STEREO = 6;
- GLX_AUX_BUFFERS = 7;
- GLX_RED_SIZE = 8;
- GLX_GREEN_SIZE = 9;
- GLX_BLUE_SIZE = 10;
- GLX_ALPHA_SIZE = 11;
- GLX_DEPTH_SIZE = 12;
- GLX_STENCIL_SIZE = 13;
- GLX_ACCUM_RED_SIZE = 14;
- GLX_ACCUM_GREEN_SIZE = 15;
- GLX_ACCUM_BLUE_SIZE = 16;
- GLX_ACCUM_ALPHA_SIZE = 17;
-
- // GLX_EXT_visual_info extension
- GLX_X_VISUAL_TYPE_EXT = $22;
- GLX_TRANSPARENT_TYPE_EXT = $23;
- GLX_TRANSPARENT_INDEX_VALUE_EXT = $24;
- GLX_TRANSPARENT_RED_VALUE_EXT = $25;
- GLX_TRANSPARENT_GREEN_VALUE_EXT = $26;
- GLX_TRANSPARENT_BLUE_VALUE_EXT = $27;
- GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28;
-
-
- // Error codes returned by glXGetConfig:
- GLX_BAD_SCREEN = 1;
- GLX_BAD_ATTRIBUTE = 2;
- GLX_NO_EXTENSION = 3;
- GLX_BAD_VISUAL = 4;
- GLX_BAD_CONTEXT = 5;
- GLX_BAD_VALUE = 6;
- GLX_BAD_ENUM = 7;
-
- // GLX 1.1 and later:
- GLX_VENDOR = 1;
- GLX_VERSION = 2;
- GLX_EXTENSIONS = 3;
-
- // GLX_visual_info extension
- GLX_TRUE_COLOR_EXT = $8002;
- GLX_DIRECT_COLOR_EXT = $8003;
- GLX_PSEUDO_COLOR_EXT = $8004;
- GLX_STATIC_COLOR_EXT = $8005;
- GLX_GRAY_SCALE_EXT = $8006;
- GLX_STATIC_GRAY_EXT = $8007;
- GLX_NONE_EXT = $8000;
- GLX_TRANSPARENT_RGB_EXT = $8008;
- GLX_TRANSPARENT_INDEX_EXT = $8009;
-
-type
- // From XLib:
- {$IFNDEF FPC}
- TXID = XID;
- {$ENDIF}
- XPixmap = TXID;
- XFont = TXID;
- XColormap = TXID;
-
- GLXContext = Pointer;
- GLXPixmap = TXID;
- GLXDrawable = TXID;
- GLXContextID = TXID;
-
-var
- glXChooseVisual: function(dpy: PDisplay; screen: Integer; var attribList: Integer): PXVisualInfo; cdecl;
- glXCreateContext: function(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: Boolean): GLXContext; cdecl;
- glXDestroyContext: procedure(dpy: PDisplay; ctx: GLXContext); cdecl;
- glXMakeCurrent: function(dpy: PDisplay; drawable: GLXDrawable; ctx: GLXContext): Boolean; cdecl;
- glXCopyContext: procedure(dpy: PDisplay; src, dst: GLXContext; mask: LongWord); cdecl;
- glXSwapBuffers: procedure(dpy: PDisplay; drawable: GLXDrawable); cdecl;
- glXCreateGLXPixmap: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap): GLXPixmap; cdecl;
- glXDestroyGLXPixmap: procedure(dpy: PDisplay; pixmap: GLXPixmap); cdecl;
- glXQueryExtension: function(dpy: PDisplay; var errorb, event: Integer): Boolean; cdecl;
- glXQueryVersion: function(dpy: PDisplay; var maj, min: Integer): Boolean; cdecl;
- glXIsDirect: function(dpy: PDisplay; ctx: GLXContext): Boolean; cdecl;
- glXGetConfig: function(dpy: PDisplay; visual: PXVisualInfo; attrib: Integer; var value: Integer): Integer; cdecl;
- glXGetCurrentContext: function: GLXContext; cdecl;
- glXGetCurrentDrawable: function: GLXDrawable; cdecl;
- glXWaitGL: procedure; cdecl;
- glXWaitX: procedure; cdecl;
- glXUseXFont: procedure(font: XFont; first, count, list: Integer); cdecl;
-
- // GLX 1.1 and later
- glXQueryExtensionsString: function(dpy: PDisplay; screen: Integer): PChar; cdecl;
- glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl;
- glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl;
-
- // Mesa GLX Extensions
- glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl;
- glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl;
- glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl;
- glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl;
- glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl;
-
-
-// =======================================================
-//
-// =======================================================
-
-implementation
-
-uses
- {$IFNDEF __GPC__}
- SysUtils,
- {$ENDIF}
- moduleloader;
-
-(* {$LINKLIB m} *)
-
-var
- libGLX: TModuleHandle;
-
-function InitGLXFromLibrary( dll : PChar ): Boolean;
-begin
- Result := False;
-
- if not LoadModule( libGLX, dll ) then
- exit;
-
- glXChooseVisual := GetModuleSymbol(libglx, 'glXChooseVisual');
- glXCreateContext := GetModuleSymbol(libglx, 'glXCreateContext');
- glXDestroyContext := GetModuleSymbol(libglx, 'glXDestroyContext');
- glXMakeCurrent := GetModuleSymbol(libglx, 'glXMakeCurrent');
- glXCopyContext := GetModuleSymbol(libglx, 'glXCopyContext');
- glXSwapBuffers := GetModuleSymbol(libglx, 'glXSwapBuffers');
- glXCreateGLXPixmap := GetModuleSymbol(libglx, 'glXCreateGLXPixmap');
- glXDestroyGLXPixmap := GetModuleSymbol(libglx, 'glXDestroyGLXPixmap');
- glXQueryExtension := GetModuleSymbol(libglx, 'glXQueryExtension');
- glXQueryVersion := GetModuleSymbol(libglx, 'glXQueryVersion');
- glXIsDirect := GetModuleSymbol(libglx, 'glXIsDirect');
- glXGetConfig := GetModuleSymbol(libglx, 'glXGetConfig');
- glXGetCurrentContext := GetModuleSymbol(libglx, 'glXGetCurrentContext');
- glXGetCurrentDrawable := GetModuleSymbol(libglx, 'glXGetCurrentDrawable');
- glXWaitGL := GetModuleSymbol(libglx, 'glXWaitGL');
- glXWaitX := GetModuleSymbol(libglx, 'glXWaitX');
- glXUseXFont := GetModuleSymbol(libglx, 'glXUseXFont');
- // GLX 1.1 and later
- glXQueryExtensionsString := GetModuleSymbol(libglx, 'glXQueryExtensionsString');
- glXQueryServerString := GetModuleSymbol(libglx, 'glXQueryServerString');
- glXGetClientString := GetModuleSymbol(libglx, 'glXGetClientString');
- // Mesa GLX Extensions
- glXCreateGLXPixmapMESA := GetModuleSymbol(libglx, 'glXCreateGLXPixmapMESA');
- glXReleaseBufferMESA := GetModuleSymbol(libglx, 'glXReleaseBufferMESA');
- glXCopySubBufferMESA := GetModuleSymbol(libglx, 'glXCopySubBufferMESA');
- glXGetVideoSyncSGI := GetModuleSymbol(libglx, 'glXGetVideoSyncSGI');
- glXWaitVideoSyncSGI := GetModuleSymbol(libglx, 'glXWaitVideoSyncSGI');
-
- GLXInitialized := True;
- Result := True;
-end;
-
-function InitGLX: Boolean;
-begin
- Result := InitGLXFromLibrary('libGL.so') or
- InitGLXFromLibrary('libGL.so.1') or
- InitGLXFromLibrary('libMesaGL.so') or
- InitGLXFromLibrary('libMesaGL.so.3');
-end;
-
-
-initialization
- InitGLX;
-finalization
- UnloadModule(libGLX);
-end.
diff --git a/Game/Code/lib/JEDI-SDL/SDL/Pas/Readme.txt b/Game/Code/lib/JEDI-SDL/SDL/Pas/Readme.txt
deleted file mode 100644
index f176d0c9..00000000
--- a/Game/Code/lib/JEDI-SDL/SDL/Pas/Readme.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Delphi interface unit for OpenGL version 1.2 compilable with Delphi 3-6 and Kylix.
-
-This unit is open source under the Mozilla Public License and
-the original author is Dipl. Ing. Mike Lischke (public@lischke-online.de).
-
-You can obtain this unit also from the JEDI (Joint Endeavor of Delphi Innovators)
-API page at www.delphi-jedi.org.
-
-Note for GLScene users: Eric Grange has provided a general vector types unit which
-resolves conflicts for types which are defined in OpenGL12.pas as well as Geometry.pas.
-This unit is located in the sub folder "GLScene AddOn".
-Please add this unit to the uses clause of OpenGL12.pas and remove the few types which
-are already declared in VectorTypes.pas.
-
-For tests and as starting point three demos are included into the package. Two of them (GLDiag and GLTest)
-need the (also provided) simple OpenGL control GLControl (see "GLControl\Package").
-
-- Basic is a very simple test program which only uses an empty form.
-- GLTest (in GLControl) uses GLControl to show four rendering contexts simultanously.
-- GLDiag is a diagnosis tool similar to DXDiag which shows some properties of the current
- OpenGL driver implementation.
-
-Have fun and
-
-Ciao, Mike
-www.lischke-online.de
-www.delphi-unicode.net
\ No newline at end of file
diff --git a/Game/Code/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc b/Game/Code/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
deleted file mode 100644
index 0130ad32..00000000
--- a/Game/Code/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
+++ /dev/null
@@ -1,438 +0,0 @@
-{
- $Id: jedi-sdl.inc,v 1.15 2007/05/29 21:30:48 savage Exp $
-}
-{******************************************************************************}
-{ }
-{ Borland Delphi SDL - Simple DirectMedia Layer }
-{ Global Conditional Definitions for JEDI-SDL cross-compilation }
-{ }
-{ }
-{ The initial developer of this Pascal code was : }
-{ Prof. Abimbola Olowofoyeku }
-{ }
-{ Portions created by Prof. Abimbola Olowofoyeku are }
-{ Copyright (C) 2000 - 2100 Prof. Abimbola Olowofoyeku. }
-{ }
-{ }
-{ Contributor(s) }
-{ -------------- }
-{ Prof. Abimbola Olowofoyeku }
-{ Dominqiue Louis }
-{ }
-{ Obtained through: }
-{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
-{ }
-{ You may retrieve the latest version of this file at the Project }
-{ JEDI home page, located at http://delphi-jedi.org }
-{ }
-{ The contents of this file are used with permission, subject to }
-{ the Mozilla Public License Version 1.1 (the "License"); you may }
-{ not use this file except in compliance with the License. You may }
-{ obtain a copy of the License at }
-{ http://www.mozilla.org/MPL/MPL-1.1.html }
-{ }
-{ Software distributed under the License is distributed on an }
-{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
-{ implied. See the License for the specific language governing }
-{ rights and limitations under the License. }
-{ }
-{ Description }
-{ ----------- }
-{ This code has been copied from... }
-{ Global Conditional Definitions for Chief's UNZIP package }
-{ By Prof. Abimbola Olowofoyeku (The African Chief) }
-{ http://www.bigfoot.com/~African_Chief/ }
-{ }
-{ }
-{ Requires }
-{ -------- }
-{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
-{ They are available from... }
-{ http://www.libsdl.org . }
-{ }
-{ Programming Notes }
-{ ----------------- }
-{ }
-{ }
-{ }
-{ }
-{ Revision History }
-{ ---------------- }
-{ 2003-04-03 DL - Initial addition }
-{ }
-{ 2003-04-07 DL - Added Macro ON derective for FPC and OpenGL and removed }
-{ WEAKPACKAGE derective. WEAKPACKAGE should be set when }
-{ appropriate. }
-{ }
-{ 2003-04-23 - DL : under instruction from Alexey Barkovoy I have added }
-{ better TMT Pascal support and under instruction }
-{ from Prof. Abimbola Olowofoyeku (The African Chief) }
-{ I have added better Gnu Pascal support }
-{ }
-{ 2004-01-19 - DL : Under instruction from Marco van de Voort, I have added }
-{ Better FPC support for FreeBSD. }
-{ }
-(*
- $Log: jedi-sdl.inc,v $
- Revision 1.15 2007/05/29 21:30:48 savage
- Changes as suggested by Almindor for 64bit compatibility.
-
- Revision 1.14 2007/05/20 20:29:11 savage
- Initial Changes to Handle 64 Bits
-
- Revision 1.13 2007/01/21 15:51:45 savage
- Added Delphi 2006 support
-
- Revision 1.12 2006/11/19 18:41:01 savage
- removed THREADING ON flag as it is no longer needed in latest versions of FPC.
-
- Revision 1.11 2006/01/04 00:52:41 drellis
- Updated to include defined for ENDIAN values, SDL_BYTEORDER should now be correctly defined depending onthe platform. Code taken from sdl_mixer
-
- Revision 1.10 2005/05/22 18:42:31 savage
- Changes as suggested by Michalis Kamburelis. Thanks again.
-
- Revision 1.9 2004/12/23 23:42:17 savage
- Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability.
-
- Revision 1.8 2004/10/20 22:43:04 savage
- Ensure that UNSAFE type warning are off in D9 as well
-
- Revision 1.7 2004/04/05 09:59:51 savage
- Changes for FreePacal as suggested by Marco
-
- Revision 1.6 2004/03/31 22:18:15 savage
- Small comment for turning off warning under GnuPascal
-
- Revision 1.5 2004/03/30 22:41:02 savage
- Added extra commenting due to previous compiler directive
-
- Revision 1.4 2004/03/30 22:08:33 savage
- Added Kylix Define
-
- Revision 1.3 2004/03/30 21:34:40 savage
- {$H+} needed for FPC compatiblity
-
- Revision 1.2 2004/02/14 00:23:39 savage
- As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
-
-*)
-{******************************************************************************}
-
-{.$define Debug} { uncomment for debugging }
-
-{$IFNDEF FPC}
- {$IFDEF __GPC__}
- {$I-}
- {$W-} // turn off GPC warnings
- {$X+}
- {$ELSE} {__GPC__}
- {$IFDEF Debug}
- {$F+,D+,Q-,L+,R+,I-,S+,Y+,A+}
- {$ELSE}
- {$F+,Q-,R-,S-,I-,A+}
- {$ENDIF}
- {$ENDIF} {__GPC__}
-{$ELSE} {FPC}
- //{$M+}
-{$ENDIF} {FPC}
-
-{$IFDEF LINUX}
-{$DEFINE UNIX}
-{$ENDIF}
-
-{$IFDEF ver70}
- {$IFDEF Windows}
- {$DEFINE Win16}
- {$ENDIF Windows}
- {$IFDEF MSDOS}
- {$DEFINE NO_EXPORTS}
- {$ENDIF MSDOS}
- {$IFDEF DPMI}
- {$DEFINE BP_DPMI}
- {$ENDIF}
- {$DEFINE OS_16_BIT}
- {$DEFINE __OS_DOS__}
-{$ENDIF ver70}
-
-{$IFDEF ver80}
- {$DEFINE Delphi} {Delphi 1.x}
- {$DEFINE Delphi16}
- {$DEFINE Win16}
- {$DEFINE OS_16_BIT}
- {$DEFINE __OS_DOS__}
-{$ENDIF ver80}
-
-{$IFDEF ver90}
- {$DEFINE Delphi} {Delphi 2.x}
- {$DEFINE Delphi32}
- {$DEFINE WIN32}
- {$DEFINE WINDOWS}
-{$ENDIF ver90}
-
-{$IFDEF ver100}
- {$DEFINE Delphi} {Delphi 3.x}
- {$DEFINE Delphi32}
- {$DEFINE WIN32}
- {$DEFINE WINDOWS}
-{$ENDIF ver100}
-
-{$IFDEF ver93}
- {$DEFINE Delphi} {C++ Builder 1.x}
- {$DEFINE Delphi32}
- {$DEFINE WINDOWS}
-{$ENDIF ver93}
-
-{$IFDEF ver110}
- {$DEFINE Delphi} {C++ Builder 3.x}
- {$DEFINE Delphi32}
- {$DEFINE WINDOWS}
-{$ENDIF ver110}
-
-{$IFDEF ver120}
- {$DEFINE Delphi} {Delphi 4.x}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Has_Int64}
- {$DEFINE WINDOWS}
-{$ENDIF ver120}
-
-{$IFDEF ver130}
- {$DEFINE Delphi} {Delphi 5.x}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Has_Int64}
- {$DEFINE WINDOWS}
-{$ENDIF ver130}
-
-{$IFDEF ver140}
- {$DEFINE Delphi} {Delphi 6.x}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver140}
-
-{$IFDEF ver150}
- {$DEFINE Delphi} {Delphi 7.x}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Delphi7UP}
- {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver150}
-
-{$IFDEF ver160}
- {$DEFINE Delphi} {Delphi 8}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Delphi7UP}
- {$DEFINE Delphi8UP}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver160}
-
-{$IFDEF ver170}
- {$DEFINE Delphi} {Delphi 2005}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Delphi7UP}
- {$DEFINE Delphi8UP}
- {$DEFINE Delphi9UP}
- {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver170}
-
-{$IFDEF ver180}
- {$DEFINE Delphi} {Delphi 2006}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Delphi7UP}
- {$DEFINE Delphi8UP}
- {$DEFINE Delphi9UP}
- {$DEFINE Delphi10UP}
- {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver180}
-
-{$IFDEF ver185}
- {$DEFINE Delphi} {Delphi 2007}
- {$DEFINE Delphi32}
- {$DEFINE Delphi4UP}
- {$DEFINE Delphi5UP}
- {$DEFINE Delphi6UP}
- {$DEFINE Delphi7UP}
- {$DEFINE Delphi8UP}
- {$DEFINE Delphi9UP}
- {$DEFINE Delphi10UP}
- {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
- {$DEFINE Has_Int64}
- {$DEFINE HAS_TYPES}
-{$ENDIF ver180}
-
-{$IFDEF UNIX}
- {$ifdef VER140} // Kylix 1 & 2
- {$DEFINE KYLIX}
- {$DEFINE KYLIX1UP}
- {$DEFINE KYLIX2UP}
- {$DEFINE HAS_TYPES}
- {$endif}
-
- {$ifdef VER150} // Kylix 3
- {$DEFINE KYLIX}
- {$DEFINE KYLIX1UP}
- {$DEFINE KYLIX2UP}
- {$DEFINE KYLIX3UP}
- {$DEFINE HAS_TYPES}
- {$endif}
-{$ENDIF UNIX}
-
-{$IFDEF VirtualPascal} { Virtual Pascal 2.x }
- {$DEFINE Delphi} { Use Delphi Syntax }
- {$DEFINE VP2}
- {&Delphi+}
-{$ENDIF VirtualPascal}
-
-{$IFDEF Delphi}
- {$DEFINE Windows}
- {$DEFINE USE_STDCALL}
- //{$ALIGN ON}
-{$ENDIF Delphi}
-
-{$IFDEF FPC}
- {$MODE Delphi} { use Delphi compatibility mode }
- {$H+}
- {$PACKRECORDS C} // Added for record
- {$MACRO ON} // Added For OpenGL
- {$DEFINE Delphi}
- {$DEFINE UseAT}
- {$UNDEF USE_STDCALL}
- {$DEFINE OS_BigMem}
- {$DEFINE NO_EXPORTS}
- {$DEFINE Has_Int64}
- {$DEFINE NOCRT}
- {$IFDEF UNIX}
- {$DEFINE fpc_unix}
- {$ELSE}
- {$DEFINE __OS_DOS__}
- {$ENDIF}
- {$IFDEF WIN32}
- {$DEFINE UseWin}
- {$ENDIF}
- {$DEFINE HAS_TYPES}
-{$ENDIF FPC}
-
-{$IFDEF Win16}
- {$K+} {smart callbacks}
-{$ENDIF Win16}
-
- {$IFDEF OS2}
- {$UNDEF Windows}
- {$DEFINE UseWin}
- {$DEFINE OS_BigMem}
- {$ENDIF OS2}
-
-{$IFDEF __GPC__}
- {$UNDEF UseWin}
- {$UNDEF USE_STDCALL}
- {$DEFINE OS_BigMem}
- {$DEFINE NO_EXPORTS}
- {$DEFINE NOCRT}
- {$DEFINE cdecl attribute(cdecl)}
-{$ENDIF}
-
-{$IFDEF __TMT__}
- {$DEFINE OS_BigMem}
- {$DEFINE NO_EXPORTS}
- {$DEFINE __OS_DOS__}
- {$DEFINE UseAT}
- {$IFNDEF MSDOS}
- {$DEFINE USE_STDCALL}
- {$ENDIF}
-
- {$IFDEF __WIN32__}
- {$DEFINE Win32}
- {$DEFINE UseWin}
- {$DEFINE NOCRT}
- {$DEFINE Win32}
- {$IFNDEF __CON__}
- {$DEFINE Windows}
- {$ENDIF}
- {$ENDIF}
-
- {$A+} // Word alignment data
- {$OA+} // Objects and structures align
-{$ENDIF}
-
-{$IFDEF Win32}
- {$DEFINE OS_BigMem}
-{$ELSE Win32}
- {$IFDEF ver70}
- {$DEFINE assembler}
- {$ENDIF} { use 16-bit assembler! }
-{$ENDIF Win32}
-
-{ ************************** dos/dos-like platforms **************}
-{$IFDEF Windows}
- {$DEFINE __OS_DOS__}
- {$DEFINE UseWin}
- {$DEFINE MSWINDOWS}
-{$ENDIF Delphi}
-
-{$IFDEF OS2}
- {$DEFINE __OS_DOS__}
- {$DEFINE Can_Use_DLL}
-{$ENDIF Delphi}
-
-{$IFDEF UseWin}
- {$DEFINE Can_Use_DLL}
-{$ENDIF}
-
-{$IFDEF Win16}
- {$DEFINE Can_Use_DLL}
-{$ENDIF}
-
-{$IFDEF BP_DPMI}
- {$DEFINE Can_Use_DLL}
-{$ENDIF}
-
-{$IFDEF USE_STDCALL}
- {$IFNDEF __TMT__}
- {$DEFINE BY_NAME}
- {$ENDIF}
-{$ENDIF}
-
-{$IFNDEF ver70}
- {$UNDEF assembler}
-{$ENDIF}
-
-{*************** define LITTLE ENDIAN platforms ********************}
-
-
-{$IFDEF Delphi}
-{$DEFINE IA32}
-{$ENDIF}
-
-{$IFDEF KYLIX}
-{$DEFINE IA32}
-{$ENDIF}
-
-{$IFDEF FPC}
-{$IFDEF FPC_LITTLE_ENDIAN}
-{$DEFINE IA32}
-{$ENDIF}
-{$ENDIF}
diff --git a/Game/Code/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas b/Game/Code/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
deleted file mode 100644
index 63e7b7fb..00000000
--- a/Game/Code/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
+++ /dev/null
@@ -1,2688 +0,0 @@
-(**
-===============================================================================================
-Name : LibXmlParser
-===============================================================================================
-Project : All Projects
-===============================================================================================
-Subject : Progressive XML Parser for all types of XML Files
-===============================================================================================
-Author : Stefan Heymann
- Eschenweg 3
- 72076 Tübingen
- GERMANY
-
-E-Mail: stefan@destructor.de
-URL: www.destructor.de
-===============================================================================================
-Source, Legals ("Licence")
---------------------------
-The official site to get this parser is http://www.destructor.de/
-
-Usage and Distribution of this Source Code is ruled by the
-"Destructor.de Source code Licence" (DSL) which comes with this file or
-can be downloaded at http://www.destructor.de/
-
-IN SHORT: Usage and distribution of this source code is free.
- You use it completely on your own risk.
-
-Postcardware
-------------
-If you like this code, please send a postcard of your city to my above address.
-===============================================================================================
-!!! All parts of this code which are not finished or not conforming exactly to
- the XmlSpec are marked with three exclamation marks
-
--!- Parts where the parser may be able to detect errors in the document's syntax are
- marked with the dash-exlamation mark-dash sequence.
-===============================================================================================
-Terminology:
-------------
-- Start: Start of a buffer part
-- Final: End (last character) of a buffer part
-- DTD: Document Type Definition
-- DTDc: Document Type Declaration
-- XMLSpec: The current W3C XML Recommendation (version 1.0 as of 1998-02-10), Chapter No.
-- Cur*: Fields concerning the "Current" part passed back by the "Scan" method
-===============================================================================================
-Scanning the XML document
--------------------------
-- Create TXmlParser Instance MyXml := TXmlParser.Create;
-- Load XML Document MyXml.LoadFromFile (Filename);
-- Start Scanning MyXml.StartScan;
-- Scan Loop WHILE MyXml.Scan DO
-- Test for Part Type CASE MyXml.CurPartType OF
-- Handle Parts ... : ;;;
-- Handle Parts ... : ;;;
-- Handle Parts ... : ;;;
- END;
-- Destroy MyXml.Free;
-===============================================================================================
-Loading the XML document
-------------------------
-You can load the XML document from a file with the "LoadFromFile" method.
-It is beyond the scope of this parser to perform HTTP or FTP accesses. If you want your
-application to handle such requests (URLs), you can load the XML via HTTP or FTP or whatever
-protocol and hand over the data buffer using the "LoadFromBuffer" or "SetBuffer" method.
-"LoadFromBuffer" loads the internal buffer of TXmlParser with the given null-terminated
-string, thereby creating a copy of that buffer.
-"SetBuffer" just takes the pointer to another buffer, which means that the given
-buffer pointer must be valid while the document is accessed via TXmlParser.
-===============================================================================================
-Encodings:
-----------
-This XML parser kind of "understands" the following encodings:
-- UTF-8
-- ISO-8859-1
-- Windows-1252
-
-Any flavor of multi-byte characters (and this includes UTF-16) is not supported. Sorry.
-
-Every string which has to be passed to the application passes the virtual method
-"TranslateEncoding" which translates the string from the current encoding (stored in
-"CurEncoding") into the encoding the application wishes to receive.
-The "TranslateEncoding" method that is built into TXmlParser assumes that the application
-wants to receive Windows ANSI (Windows-1252, about the same as ISO-8859-1) and is able
-to convert UTF-8 and ISO-8859-1 encodings.
-For other source and target encodings, you will have to override "TranslateEncoding".
-===============================================================================================
-Buffer Handling
----------------
-- The document must be loaded completely into a piece of RAM
-- All character positions are referenced by PChar pointers
-- The TXmlParser instance can either "own" the buffer itself (then, FBufferSize is > 0)
- or reference the buffer of another instance or object (then, FBuffersize is 0 and
- FBuffer is not NIL)
-- The Property DocBuffer passes back a pointer to the first byte of the document. If there
- is no document stored (FBuffer is NIL), the DocBuffer returns a pointer to a NULL character.
-===============================================================================================
-Whitespace Handling
--------------------
-The TXmlParser property "PackSpaces" determines how Whitespace is returned in Text Content:
-While PackSpaces is true, all leading and trailing whitespace characters are trimmed of, all
-Whitespace is converted to Space #x20 characters and contiguous Whitespace characters are
-compressed to one.
-If the "Scan" method reports a ptContent part, the application can get the original text
-with all whitespace characters by extracting the characters from "CurStart" to "CurFinal".
-If the application detects an xml:space attribute, it can set "PackSpaces" accordingly or
-use CurStart/CurFinal.
-Please note that TXmlParser does _not_ normalize Line Breaks to single LineFeed characters
-as the XmlSpec requires (XmlSpec 2.11).
-The xml:space attribute is not handled by TXmlParser. This is on behalf of the application.
-===============================================================================================
-Non-XML-Conforming
-------------------
-TXmlParser does not conform 100 % exactly to the XmlSpec:
-- UTF-16 is not supported (XmlSpec 2.2)
- (Workaround: Convert UTF-16 to UTF-8 and hand the buffer over to TXmlParser)
-- As the parser only works with single byte strings, all Unicode characters > 255
- can currently not be handled correctly.
-- Line breaks are not normalized to single Linefeed #x0A characters (XmlSpec 2.11)
- (Workaround: The Application can access the text contents on its own [CurStart, CurFinal],
- thereby applying every normalization it wishes to)
-- The attribute value normalization does not work exactly as defined in the
- Second Edition of the XML 1.0 specification.
-- See also the code parts marked with three consecutive exclamation marks. These are
- parts which are not finished in the current code release.
-
-This list may be incomplete, so it may grow if I get to know any other points.
-As work on the parser proceeds, this list may also shrink.
-===============================================================================================
-Things Todo
------------
-- Introduce a new event/callback which is called when there is an unresolvable
- entity or character reference
-- Support Unicode
-- Use Streams instead of reading the whole XML into memory
-===============================================================================================
-Change History, Version numbers
--------------------------------
-The Date is given in ISO Year-Month-Day (YYYY-MM-DD) order.
-Versions are counted from 1.0.0 beginning with the version from 2000-03-16.
-Unreleased versions don't get a version number.
-
-Date Author Version Changes
------------------------------------------------------------------------------------------------
-2000-03-16 HeySt 1.0.0 Start
-2000-03-28 HeySt 1.0.1 Initial Publishing of TXmlParser on the destructor.de Web Site
-2000-03-30 HeySt 1.0.2 TXmlParser.AnalyzeCData: Call "TranslateEncoding" for CurContent
-2000-03-31 HeySt 1.0.3 Deleted the StrPosE function (was not needed anyway)
-2000-04-04 HeySt 1.0.4 TDtdElementRec modified: Start/Final for all Elements;
- Should be backwards compatible.
- AnalyzeDtdc: Set CurPartType to ptDtdc
-2000-04-23 HeySt 1.0.5 New class TObjectList. Eliminated reference to the Delphi 5
- "Contnrs" unit so LibXmlParser is Delphi 4 compatible.
-2000-07-03 HeySt 1.0.6 TNvpNode: Added Constructor
-2000-07-11 HeySt 1.0.7 Removed "Windows" from USES clause
- Added three-exclamation-mark comments for Utf8ToAnsi/AnsiToUtf8
- Added three-exclamation-mark comments for CHR function calls
-2000-07-23 HeySt 1.0.8 TXmlParser.Clear: CurAttr.Clear; EntityStack.Clear;
- (This was not a bug; just defensive programming)
-2000-07-29 HeySt 1.0.9 TNvpList: Added methods: Node(Index), Value(Index), Name(Index);
-2000-10-07 HeySt Introduced Conditional Defines
- Uses Contnrs unit and its TObjectList class again for
- Delphi 5 and newer versions
-2001-01-30 HeySt Introduced Version Numbering
- Made LoadFromFile and LoadFromBuffer BOOLEAN functions
- Introduced FileMode parameter for LoadFromFile
- BugFix: TAttrList.Analyze: Must add CWhitespace to ExtractName call
- Comments worked over
-2001-02-28 HeySt 1.0.10 Completely worked over and tested the UTF-8 functions
- Fixed a bug in TXmlParser.Scan which caused it to start over when it
- was called after the end of scanning, resulting in an endless loop
- TEntityStack is now a TObjectList instead of TList
-2001-07-03 HeySt 1.0.11 Updated Compiler Version IFDEFs for Kylix
-2001-07-11 HeySt 1.0.12 New TCustomXmlScanner component (taken over from LibXmlComps.pas)
-2001-07-14 HeySt 1.0.13 Bugfix TCustomXmlScanner.FOnTranslateEncoding
-2001-10-22 HeySt Don't clear CurName anymore when the parser finds a CDATA section.
-2001-12-03 HeySt 1.0.14 TObjectList.Clear: Make call to INHERITED method (fixes a memory leak)
-2001-12-05 HeySt 1.0.15 TObjectList.Clear: removed call to INHERITED method
- TObjectList.Destroy: Inserted SetCapacity call.
- Reduces need for frequent re-allocation of pointer buffer
- Dedicated to my father, Theodor Heymann
-2002-06-26 HeySt 1.0.16 TXmlParser.Scan: Fixed a bug with PIs whose name is beginning
- with 'xml'. Thanks to Uwe Kamm for submitting this bug.
- The CurEncoding property is now always in uppercase letters (the XML
- spec wants it to be treated case independently so when it's uppercase
- comparisons are faster)
-2002-03-04 HeySt 1.0.17 Included an IFDEF for Delphi 7 (VER150) and Kylix
- There is a new symbol HAS_CONTNRS_UNIT which is used now to
- distinguish between IDEs which come with the Contnrs unit and
- those that don't.
-*)
-
-UNIT libxmlparser;
-
-{$I jedi-sdl.inc}
-
-INTERFACE
-
-USES
- SysUtils, Classes,
- (*$IFDEF HAS_CONTNRS_UNIT *) // The Contnrs Unit was introduced in Delphi 5
- Contnrs,
- (*$ENDIF*)
- Math;
-
-CONST
- CVersion = '1.0.17'; // This variable will be updated for every release
- // (I hope, I won't forget to do it everytime ...)
-
-TYPE
- TPartType = // --- Document Part Types
- (ptNone, // Nothing
- ptXmlProlog, // XML Prolog XmlSpec 2.8 / 4.3.1
- ptComment, // Comment XmlSpec 2.5
- ptPI, // Processing Instruction XmlSpec 2.6
- ptDtdc, // Document Type Declaration XmlSpec 2.8
- ptStartTag, // Start Tag XmlSpec 3.1
- ptEmptyTag, // Empty-Element Tag XmlSpec 3.1
- ptEndTag, // End Tag XmlSpec 3.1
- ptContent, // Text Content between Tags
- ptCData); // CDATA Section XmlSpec 2.7
-
- TDtdElemType = // --- DTD Elements
- (deElement, // !ELEMENT declaration
- deAttList, // !ATTLIST declaration
- deEntity, // !ENTITY declaration
- deNotation, // !NOTATION declaration
- dePI, // PI in DTD
- deComment, // Comment in DTD
- deError); // Error found in the DTD
-
-TYPE
- TAttrList = CLASS;
- TEntityStack = CLASS;
- TNvpList = CLASS;
- TElemDef = CLASS;
- TElemList = CLASS;
- TEntityDef = CLASS;
- TNotationDef = CLASS;
-
- TDtdElementRec = RECORD // --- This Record is returned by the DTD parser callback function
- Start, Final : PChar; // Start/End of the Element's Declaration
- CASE ElementType : TDtdElemType OF // Type of the Element
- deElement, //
- deAttList : (ElemDef : TElemDef); //
- deEntity : (EntityDef : TEntityDef); //
- deNotation : (NotationDef : TNotationDef); //
- dePI : (Target : PChar; //
- Content : PChar;
- AttrList : TAttrList);
- deError : (Pos : PChar); // Error
- // deComment : ((No additional fields here)); //
- END;
-
- TXmlParser = CLASS // --- Internal Properties and Methods
- PROTECTED
- FBuffer : PChar; // NIL if there is no buffer available
- FBufferSize : INTEGER; // 0 if the buffer is not owned by the Document instance
- FSource : STRING; // Name of Source of document. Filename for Documents loaded with LoadFromFile
-
- FXmlVersion : STRING; // XML version from Document header. Default is '1.0'
- FEncoding : STRING; // Encoding from Document header. Default is 'UTF-8'
- FStandalone : BOOLEAN; // Standalone declaration from Document header. Default is 'yes'
- FRootName : STRING; // Name of the Root Element (= DTD name)
- FDtdcFinal : PChar; // Pointer to the '>' character terminating the DTD declaration
-
- FNormalize : BOOLEAN; // If true: Pack Whitespace and don't return empty contents
- EntityStack : TEntityStack; // Entity Stack for Parameter and General Entities
- FCurEncoding : STRING; // Current Encoding during parsing (always uppercase)
-
- PROCEDURE AnalyzeProlog; // Analyze XML Prolog or Text Declaration
- PROCEDURE AnalyzeComment (Start : PChar; VAR Final : PChar); // Analyze Comments
- PROCEDURE AnalyzePI (Start : PChar; VAR Final : PChar); // Analyze Processing Instructions (PI)
- PROCEDURE AnalyzeDtdc; // Analyze Document Type Declaration
- PROCEDURE AnalyzeDtdElements (Start : PChar; VAR Final : PChar); // Analyze DTD declarations
- PROCEDURE AnalyzeTag; // Analyze Start/End/Empty-Element Tags
- PROCEDURE AnalyzeCData; // Analyze CDATA Sections
- PROCEDURE AnalyzeText (VAR IsDone : BOOLEAN); // Analyze Text Content between Tags
- PROCEDURE AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
- PROCEDURE AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
- PROCEDURE AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
- PROCEDURE AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
-
- PROCEDURE PushPE (VAR Start : PChar);
- PROCEDURE ReplaceCharacterEntities (VAR Str : STRING);
- PROCEDURE ReplaceParameterEntities (VAR Str : STRING);
- PROCEDURE ReplaceGeneralEntities (VAR Str : STRING);
-
- FUNCTION GetDocBuffer : PChar; // Returns FBuffer or a pointer to a NUL char if Buffer is empty
-
- PUBLIC // --- Document Properties
- PROPERTY XmlVersion : STRING READ FXmlVersion; // XML version from the Document Prolog
- PROPERTY Encoding : STRING READ FEncoding; // Document Encoding from Prolog
- PROPERTY Standalone : BOOLEAN READ FStandalone; // Standalone Declaration from Prolog
- PROPERTY RootName : STRING READ FRootName; // Name of the Root Element
- PROPERTY Normalize : BOOLEAN READ FNormalize WRITE FNormalize; // True if Content is to be normalized
- PROPERTY Source : STRING READ FSource; // Name of Document Source (Filename)
- PROPERTY DocBuffer : PChar READ GetDocBuffer; // Returns document buffer
- PUBLIC // --- DTD Objects
- Elements : TElemList; // Elements: List of TElemDef (contains Attribute Definitions)
- Entities : TNvpList; // General Entities: List of TEntityDef
- ParEntities : TNvpList; // Parameter Entities: List of TEntityDef
- Notations : TNvpList; // Notations: List of TNotationDef
- PUBLIC
- CONSTRUCTOR Create;
- DESTRUCTOR Destroy; OVERRIDE;
-
- // --- Document Handling
- FUNCTION LoadFromFile (Filename : STRING;
- FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
- // Loads Document from given file
- FUNCTION LoadFromBuffer (Buffer : PChar) : BOOLEAN; // Loads Document from another buffer
- PROCEDURE SetBuffer (Buffer : PChar); // References another buffer
- PROCEDURE Clear; // Clear Document
-
- PUBLIC
- // --- Scanning through the document
- CurPartType : TPartType; // Current Type
- CurName : STRING; // Current Name
- CurContent : STRING; // Current Normalized Content
- CurStart : PChar; // Current First character
- CurFinal : PChar; // Current Last character
- CurAttr : TAttrList; // Current Attribute List
- PROPERTY CurEncoding : STRING READ FCurEncoding; // Current Encoding
- PROCEDURE StartScan;
- FUNCTION Scan : BOOLEAN;
-
- // --- Events / Callbacks
- FUNCTION LoadExternalEntity (SystemId, PublicId,
- Notation : STRING) : TXmlParser; VIRTUAL;
- FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; VIRTUAL;
- PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); VIRTUAL;
- END;
-
- TValueType = // --- Attribute Value Type
- (vtNormal, // Normal specified Attribute
- vtImplied, // #IMPLIED attribute value
- vtFixed, // #FIXED attribute value
- vtDefault); // Attribute value from default value in !ATTLIST declaration
-
- TAttrDefault = // --- Attribute Default Type
- (adDefault, // Normal default value
- adRequired, // #REQUIRED attribute
- adImplied, // #IMPLIED attribute
- adFixed); // #FIXED attribute
-
- TAttrType = // --- Type of attribute
- (atUnknown, // Unknown type
- atCData, // Character data only
- atID, // ID
- atIdRef, // ID Reference
- atIdRefs, // Several ID References, separated by Whitespace
- atEntity, // Name of an unparsed Entity
- atEntities, // Several unparsed Entity names, separated by Whitespace
- atNmToken, // Name Token
- atNmTokens, // Several Name Tokens, separated by Whitespace
- atNotation, // A selection of Notation names (Unparsed Entity)
- atEnumeration); // Enumeration
-
- TElemType = // --- Element content type
- (etEmpty, // Element is always empty
- etAny, // Element can have any mixture of PCDATA and any elements
- etChildren, // Element must contain only elements
- etMixed); // Mixed PCDATA and elements
-
- (*$IFDEF HAS_CONTNRS_UNIT *)
- TObjectList = Contnrs.TObjectList; // Re-Export this identifier
- (*$ELSE *)
- TObjectList = CLASS (TList)
- DESTRUCTOR Destroy; OVERRIDE;
- PROCEDURE Delete (Index : INTEGER);
- PROCEDURE Clear; OVERRIDE;
- END;
- (*$ENDIF *)
-
- TNvpNode = CLASS // Name-Value Pair Node
- Name : STRING;
- Value : STRING;
- CONSTRUCTOR Create (TheName : STRING = ''; TheValue : STRING = '');
- END;
-
- TNvpList = CLASS (TObjectList) // Name-Value Pair List
- PROCEDURE Add (Node : TNvpNode);
- FUNCTION Node (Name : STRING) : TNvpNode; OVERLOAD;
- FUNCTION Node (Index : INTEGER) : TNvpNode; OVERLOAD;
- FUNCTION Value (Name : STRING) : STRING; OVERLOAD;
- FUNCTION Value (Index : INTEGER) : STRING; OVERLOAD;
- FUNCTION Name (Index : INTEGER) : STRING;
- END;
-
- TAttr = CLASS (TNvpNode) // Attribute of a Start-Tag or Empty-Element-Tag
- ValueType : TValueType;
- AttrType : TAttrType;
- END;
-
- TAttrList = CLASS (TNvpList) // List of Attributes
- PROCEDURE Analyze (Start : PChar; VAR Final : PChar);
- END;
-
- TEntityStack = CLASS (TObjectList) // Stack where current position is stored before parsing entities
- PROTECTED
- Owner : TXmlParser;
- PUBLIC
- CONSTRUCTOR Create (TheOwner : TXmlParser);
- PROCEDURE Push (LastPos : PChar); OVERLOAD;
- PROCEDURE Push (Instance : TObject; LastPos : PChar); OVERLOAD;
- FUNCTION Pop : PChar; // Returns next char or NIL if EOF is reached. Frees Instance.
- END;
-
- TAttrDef = CLASS (TNvpNode) // Represents a ';
-
- // --- Name Constants for the above enumeration types
- CPartType_Name : ARRAY [TPartType] OF STRING =
- ('', 'XML Prolog', 'Comment', 'PI',
- 'DTD Declaration', 'Start Tag', 'Empty Tag', 'End Tag',
- 'Text', 'CDATA');
- CValueType_Name : ARRAY [TValueType] OF STRING = ('Normal', 'Implied', 'Fixed', 'Default');
- CAttrDefault_Name : ARRAY [TAttrDefault] OF STRING = ('Default', 'Required', 'Implied', 'Fixed');
- CElemType_Name : ARRAY [TElemType] OF STRING = ('Empty', 'Any', 'Childs only', 'Mixed');
- CAttrType_Name : ARRAY [TAttrType] OF STRING = ('Unknown', 'CDATA',
- 'ID', 'IDREF', 'IDREFS',
- 'ENTITY', 'ENTITIES',
- 'NMTOKEN', 'NMTOKENS',
- 'Notation', 'Enumeration');
-
-FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING; // Convert WS to spaces #x20
-PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar); // SetString by Start/Final of buffer
-FUNCTION StrSFPas (Start, Finish : PChar) : STRING; // Convert buffer part to Pascal string
-FUNCTION TrimWs (Source : STRING) : STRING; // Trim Whitespace
-
-FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING; // Convert Win-1252 to UTF-8
-FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING; // Convert UTF-8 to Win-1252
-
-
-(*
-===============================================================================================
-TCustomXmlScanner event based component wrapper for TXmlParser
-===============================================================================================
-*)
-
-TYPE
- TCustomXmlScanner = CLASS;
- TXmlPrologEvent = PROCEDURE (Sender : TObject; XmlVersion, Encoding: STRING; Standalone : BOOLEAN) OF OBJECT;
- TCommentEvent = PROCEDURE (Sender : TObject; Comment : STRING) OF OBJECT;
- TPIEvent = PROCEDURE (Sender : TObject; Target, Content: STRING; Attributes : TAttrList) OF OBJECT;
- TDtdEvent = PROCEDURE (Sender : TObject; RootElementName : STRING) OF OBJECT;
- TStartTagEvent = PROCEDURE (Sender : TObject; TagName : STRING; Attributes : TAttrList) OF OBJECT;
- TEndTagEvent = PROCEDURE (Sender : TObject; TagName : STRING) OF OBJECT;
- TContentEvent = PROCEDURE (Sender : TObject; Content : STRING) OF OBJECT;
- TElementEvent = PROCEDURE (Sender : TObject; ElemDef : TElemDef) OF OBJECT;
- TEntityEvent = PROCEDURE (Sender : TObject; EntityDef : TEntityDef) OF OBJECT;
- TNotationEvent = PROCEDURE (Sender : TObject; NotationDef : TNotationDef) OF OBJECT;
- TErrorEvent = PROCEDURE (Sender : TObject; ErrorPos : PChar) OF OBJECT;
- TExternalEvent = PROCEDURE (Sender : TObject; SystemId, PublicId, NotationId : STRING;
- VAR Result : TXmlParser) OF OBJECT;
- TEncodingEvent = FUNCTION (Sender : TObject; CurrentEncoding, Source : STRING) : STRING OF OBJECT;
-
-
- TCustomXmlScanner = CLASS (TComponent)
- PROTECTED
- FXmlParser : TXmlParser;
- FOnXmlProlog : TXmlPrologEvent;
- FOnComment : TCommentEvent;
- FOnPI : TPIEvent;
- FOnDtdRead : TDtdEvent;
- FOnStartTag : TStartTagEvent;
- FOnEmptyTag : TStartTagEvent;
- FOnEndTag : TEndTagEvent;
- FOnContent : TContentEvent;
- FOnCData : TContentEvent;
- FOnElement : TElementEvent;
- FOnAttList : TElementEvent;
- FOnEntity : TEntityEvent;
- FOnNotation : TNotationEvent;
- FOnDtdError : TErrorEvent;
- FOnLoadExternal : TExternalEvent;
- FOnTranslateEncoding : TEncodingEvent;
- FStopParser : BOOLEAN;
- FUNCTION GetNormalize : BOOLEAN;
- PROCEDURE SetNormalize (Value : BOOLEAN);
-
- PROCEDURE WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN); VIRTUAL;
- PROCEDURE WhenComment (Comment : STRING); VIRTUAL;
- PROCEDURE WhenPI (Target, Content: STRING; Attributes : TAttrList); VIRTUAL;
- PROCEDURE WhenDtdRead (RootElementName : STRING); VIRTUAL;
- PROCEDURE WhenStartTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
- PROCEDURE WhenEmptyTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
- PROCEDURE WhenEndTag (TagName : STRING); VIRTUAL;
- PROCEDURE WhenContent (Content : STRING); VIRTUAL;
- PROCEDURE WhenCData (Content : STRING); VIRTUAL;
- PROCEDURE WhenElement (ElemDef : TElemDef); VIRTUAL;
- PROCEDURE WhenAttList (ElemDef : TElemDef); VIRTUAL;
- PROCEDURE WhenEntity (EntityDef : TEntityDef); VIRTUAL;
- PROCEDURE WhenNotation (NotationDef : TNotationDef); VIRTUAL;
- PROCEDURE WhenDtdError (ErrorPos : PChar); VIRTUAL;
-
- PUBLIC
- CONSTRUCTOR Create (AOwner: TComponent); OVERRIDE;
- DESTRUCTOR Destroy; OVERRIDE;
-
- PROCEDURE LoadFromFile (Filename : TFilename); // Load XML Document from file
- PROCEDURE LoadFromBuffer (Buffer : PChar); // Load XML Document from buffer
- PROCEDURE SetBuffer (Buffer : PChar); // Refer to Buffer
- FUNCTION GetFilename : TFilename;
-
- PROCEDURE Execute; // Perform scanning
-
- PROTECTED
- PROPERTY XmlParser : TXmlParser READ FXmlParser;
- PROPERTY StopParser : BOOLEAN READ FStopParser WRITE FStopParser;
- PROPERTY Filename : TFilename READ GetFilename WRITE LoadFromFile;
- PROPERTY Normalize : BOOLEAN READ GetNormalize WRITE SetNormalize;
- PROPERTY OnXmlProlog : TXmlPrologEvent READ FOnXmlProlog WRITE FOnXmlProlog;
- PROPERTY OnComment : TCommentEvent READ FOnComment WRITE FOnComment;
- PROPERTY OnPI : TPIEvent READ FOnPI WRITE FOnPI;
- PROPERTY OnDtdRead : TDtdEvent READ FOnDtdRead WRITE FOnDtdRead;
- PROPERTY OnStartTag : TStartTagEvent READ FOnStartTag WRITE FOnStartTag;
- PROPERTY OnEmptyTag : TStartTagEvent READ FOnEmptyTag WRITE FOnEmptyTag;
- PROPERTY OnEndTag : TEndTagEvent READ FOnEndTag WRITE FOnEndTag;
- PROPERTY OnContent : TContentEvent READ FOnContent WRITE FOnContent;
- PROPERTY OnCData : TContentEvent READ FOnCData WRITE FOnCData;
- PROPERTY OnElement : TElementEvent READ FOnElement WRITE FOnElement;
- PROPERTY OnAttList : TElementEvent READ FOnAttList WRITE FOnAttList;
- PROPERTY OnEntity : TEntityEvent READ FOnEntity WRITE FOnEntity;
- PROPERTY OnNotation : TNotationEvent READ FOnNotation WRITE FOnNotation;
- PROPERTY OnDtdError : TErrorEvent READ FOnDtdError WRITE FOnDtdError;
- PROPERTY OnLoadExternal : TExternalEvent READ FOnLoadExternal WRITE FOnLoadExternal;
- PROPERTY OnTranslateEncoding : TEncodingEvent READ FOnTranslateEncoding WRITE FOnTranslateEncoding;
- END;
-
-(*
-===============================================================================================
-IMPLEMENTATION
-===============================================================================================
-*)
-
-IMPLEMENTATION
-
-
-(*
-===============================================================================================
-Unicode and UTF-8 stuff
-===============================================================================================
-*)
-
-CONST
- // --- Character Translation Table for Unicode <-> Win-1252
- WIN1252_UNICODE : ARRAY [$00..$FF] OF WORD = (
- $0000, $0001, $0002, $0003, $0004, $0005, $0006, $0007, $0008, $0009,
- $000A, $000B, $000C, $000D, $000E, $000F, $0010, $0011, $0012, $0013,
- $0014, $0015, $0016, $0017, $0018, $0019, $001A, $001B, $001C, $001D,
- $001E, $001F, $0020, $0021, $0022, $0023, $0024, $0025, $0026, $0027,
- $0028, $0029, $002A, $002B, $002C, $002D, $002E, $002F, $0030, $0031,
- $0032, $0033, $0034, $0035, $0036, $0037, $0038, $0039, $003A, $003B,
- $003C, $003D, $003E, $003F, $0040, $0041, $0042, $0043, $0044, $0045,
- $0046, $0047, $0048, $0049, $004A, $004B, $004C, $004D, $004E, $004F,
- $0050, $0051, $0052, $0053, $0054, $0055, $0056, $0057, $0058, $0059,
- $005A, $005B, $005C, $005D, $005E, $005F, $0060, $0061, $0062, $0063,
- $0064, $0065, $0066, $0067, $0068, $0069, $006A, $006B, $006C, $006D,
- $006E, $006F, $0070, $0071, $0072, $0073, $0074, $0075, $0076, $0077,
- $0078, $0079, $007A, $007B, $007C, $007D, $007E, $007F,
-
- $20AC, $0081, $201A, $0192, $201E, $2026, $2020, $2021, $02C6, $2030,
- $0160, $2039, $0152, $008D, $017D, $008F, $0090, $2018, $2019, $201C,
- $201D, $2022, $2013, $2014, $02DC, $2122, $0161, $203A, $0153, $009D,
- $017E, $0178, $00A0, $00A1, $00A2, $00A3, $00A4, $00A5, $00A6, $00A7,
- $00A8, $00A9, $00AA, $00AB, $00AC, $00AD, $00AE, $00AF, $00B0, $00B1,
- $00B2, $00B3, $00B4, $00B5, $00B6, $00B7, $00B8, $00B9, $00BA, $00BB,
- $00BC, $00BD, $00BE, $00BF, $00C0, $00C1, $00C2, $00C3, $00C4, $00C5,
- $00C6, $00C7, $00C8, $00C9, $00CA, $00CB, $00CC, $00CD, $00CE, $00CF,
- $00D0, $00D1, $00D2, $00D3, $00D4, $00D5, $00D6, $00D7, $00D8, $00D9,
- $00DA, $00DB, $00DC, $00DD, $00DE, $00DF, $00E0, $00E1, $00E2, $00E3,
- $00E4, $00E5, $00E6, $00E7, $00E8, $00E9, $00EA, $00EB, $00EC, $00ED,
- $00EE, $00EF, $00F0, $00F1, $00F2, $00F3, $00F4, $00F5, $00F6, $00F7,
- $00F8, $00F9, $00FA, $00FB, $00FC, $00FD, $00FE, $00FF);
-
-(* UTF-8 (somewhat simplified)
- -----
- Character Range Byte sequence
- --------------- -------------------------- (x=Bits from original character)
- $0000..$007F 0xxxxxxx
- $0080..$07FF 110xxxxx 10xxxxxx
- $8000..$FFFF 1110xxxx 10xxxxxx 10xxxxxx
-
- Example
- --------
- Transforming the Unicode character U+00E4 LATIN SMALL LETTER A WITH DIAERESIS ("ä"):
-
- ISO-8859-1, Decimal 228
- Win1252, Hex $E4
- ANSI Bin 1110 0100
- abcd efgh
-
- UTF-8 Binary 1100xxab 10cdefgh
- Binary 11000011 10100100
- Hex $C3 $A4
- Decimal 195 164
- ANSI Ã ¤ *)
-
-
-FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING;
- (* Converts the given Windows ANSI (Win1252) String to UTF-8. *)
-VAR
- I : INTEGER; // Loop counter
- U : WORD; // Current Unicode value
- Len : INTEGER; // Current real length of "Result" string
-BEGIN
- SetLength (Result, Length (Source) * 3); // Worst case
- Len := 0;
- FOR I := 1 TO Length (Source) DO BEGIN
- U := WIN1252_UNICODE [ORD (Source [I])];
- CASE U OF
- $0000..$007F : BEGIN
- INC (Len);
- Result [Len] := CHR (U);
- END;
- $0080..$07FF : BEGIN
- INC (Len);
- Result [Len] := CHR ($C0 OR (U SHR 6));
- INC (Len);
- Result [Len] := CHR ($80 OR (U AND $3F));
- END;
- $0800..$FFFF : BEGIN
- INC (Len);
- Result [Len] := CHR ($E0 OR (U SHR 12));
- INC (Len);
- Result [Len] := CHR ($80 OR ((U SHR 6) AND $3F));
- INC (Len);
- Result [Len] := CHR ($80 OR (U AND $3F));
- END;
- END;
- END;
- SetLength (Result, Len);
-END;
-
-
-FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING;
- (* Converts the given UTF-8 String to Windows ANSI (Win-1252).
- If a character can not be converted, the "UnknownChar" is inserted. *)
-VAR
- SourceLen : INTEGER; // Length of Source string
- I, K : INTEGER;
- A : BYTE; // Current ANSI character value
- U : WORD;
- Ch : CHAR; // Dest char
- Len : INTEGER; // Current real length of "Result" string
-BEGIN
- SourceLen := Length (Source);
- SetLength (Result, SourceLen); // Enough room to live
- Len := 0;
- I := 1;
- WHILE I <= SourceLen DO BEGIN
- A := ORD (Source [I]);
- IF A < $80 THEN BEGIN // Range $0000..$007F
- INC (Len);
- Result [Len] := Source [I];
- INC (I);
- END
- ELSE BEGIN // Determine U, Inc I
- IF (A AND $E0 = $C0) AND (I < SourceLen) THEN BEGIN // Range $0080..$07FF
- U := (WORD (A AND $1F) SHL 6) OR (ORD (Source [I+1]) AND $3F);
- INC (I, 2);
- END
- ELSE IF (A AND $F0 = $E0) AND (I < SourceLen-1) THEN BEGIN // Range $0800..$FFFF
- U := (WORD (A AND $0F) SHL 12) OR
- (WORD (ORD (Source [I+1]) AND $3F) SHL 6) OR
- ( ORD (Source [I+2]) AND $3F);
- INC (I, 3);
- END
- ELSE BEGIN // Unknown/unsupported
- INC (I);
- FOR K := 7 DOWNTO 0 DO
- IF A AND (1 SHL K) = 0 THEN BEGIN
- INC (I, (A SHR (K+1))-1);
- BREAK;
- END;
- U := WIN1252_UNICODE [ORD (UnknownChar)];
- END;
- Ch := UnknownChar; // Retrieve ANSI char
- FOR A := $00 TO $FF DO
- IF WIN1252_UNICODE [A] = U THEN BEGIN
- Ch := CHR (A);
- BREAK;
- END;
- INC (Len);
- Result [Len] := Ch;
- END;
- END;
- SetLength (Result, Len);
-END;
-
-
-(*
-===============================================================================================
-"Special" Helper Functions
-
-Don't ask me why. But including these functions makes the parser *DRAMATICALLY* faster
-on my K6-233 machine. You can test it yourself just by commenting them out.
-They do exactly the same as the Assembler routines defined in SysUtils.
-(This is where you can see how great the Delphi compiler really is. The compiled code is
-faster than hand-coded assembler!)
-===============================================================================================
---> Just move this line below the StrScan function --> *)
-
-
-FUNCTION StrPos (CONST Str, SearchStr : PChar) : PChar;
- // Same functionality as SysUtils.StrPos
-VAR
- First : CHAR;
- Len : INTEGER;
-BEGIN
- First := SearchStr^;
- Len := StrLen (SearchStr);
- Result := Str;
- REPEAT
- IF Result^ = First THEN
- IF StrLComp (Result, SearchStr, Len) = 0 THEN BREAK;
- IF Result^ = #0 THEN BEGIN
- Result := NIL;
- BREAK;
- END;
- INC (Result);
- UNTIL FALSE;
-END;
-
-
-FUNCTION StrScan (CONST Start : PChar; CONST Ch : CHAR) : PChar;
- // Same functionality as SysUtils.StrScan
-BEGIN
- Result := Start;
- WHILE Result^ <> Ch DO BEGIN
- IF Result^ = #0 THEN BEGIN
- Result := NIL;
- EXIT;
- END;
- INC (Result);
- END;
-END;
-
-
-(*
-===============================================================================================
-Helper Functions
-===============================================================================================
-*)
-
-FUNCTION DelChars (Source : STRING; CharsToDelete : TCharset) : STRING;
- // Delete all "CharsToDelete" from the string
-VAR
- I : INTEGER;
-BEGIN
- Result := Source;
- FOR I := Length (Result) DOWNTO 1 DO
- IF Result [I] IN CharsToDelete THEN
- Delete (Result, I, 1);
-END;
-
-
-FUNCTION TrimWs (Source : STRING) : STRING;
- // Trimms off Whitespace characters from both ends of the string
-VAR
- I : INTEGER;
-BEGIN
- // --- Trim Left
- I := 1;
- WHILE (I <= Length (Source)) AND (Source [I] IN CWhitespace) DO
- INC (I);
- Result := Copy (Source, I, MaxInt);
-
- // --- Trim Right
- I := Length (Result);
- WHILE (I > 1) AND (Result [I] IN CWhitespace) DO
- DEC (I);
- Delete (Result, I+1, Length (Result)-I);
-END;
-
-
-FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING;
- // Converts all Whitespace characters to the Space #x20 character
- // If "PackWs" is true, contiguous Whitespace characters are packed to one
-VAR
- I : INTEGER;
-BEGIN
- Result := Source;
- FOR I := Length (Result) DOWNTO 1 DO
- IF (Result [I] IN CWhitespace) THEN
- IF PackWs AND (I > 1) AND (Result [I-1] IN CWhitespace)
- THEN Delete (Result, I, 1)
- ELSE Result [I] := #32;
-END;
-
-
-PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar);
-BEGIN
- SetString (S, BufferStart, BufferFinal-BufferStart+1);
-END;
-
-
-FUNCTION StrLPas (Start : PChar; Len : INTEGER) : STRING;
-BEGIN
- SetString (Result, Start, Len);
-END;
-
-
-FUNCTION StrSFPas (Start, Finish : PChar) : STRING;
-BEGIN
- SetString (Result, Start, Finish-Start+1);
-END;
-
-
-FUNCTION StrScanE (CONST Source : PChar; CONST CharToScanFor : CHAR) : PChar;
- // If "CharToScanFor" is not found, StrScanE returns the last char of the
- // buffer instead of NIL
-BEGIN
- Result := StrScan (Source, CharToScanFor);
- IF Result = NIL THEN
- Result := StrEnd (Source)-1;
-END;
-
-
-PROCEDURE ExtractName (Start : PChar; Terminators : TCharset; VAR Final : PChar);
- (* Extracts the complete Name beginning at "Start".
- It is assumed that the name is contained in Markup, so the '>' character is
- always a Termination.
- Start: IN Pointer to first char of name. Is always considered to be valid
- Terminators: IN Characters which terminate the name
- Final: OUT Pointer to last char of name *)
-BEGIN
- Final := Start+1;
- Include (Terminators, #0);
- Include (Terminators, '>');
- WHILE NOT (Final^ IN Terminators) DO
- INC (Final);
- DEC (Final);
-END;
-
-
-PROCEDURE ExtractQuote (Start : PChar; VAR Content : STRING; VAR Final : PChar);
- (* Extract a string which is contained in single or double Quotes.
- Start: IN Pointer to opening quote
- Content: OUT The quoted string
- Final: OUT Pointer to closing quote *)
-BEGIN
- Final := StrScan (Start+1, Start^);
- IF Final = NIL THEN BEGIN
- Final := StrEnd (Start+1)-1;
- SetString (Content, Start+1, Final-Start);
- END
- ELSE
- SetString (Content, Start+1, Final-1-Start);
-END;
-
-
-(*
-===============================================================================================
-TEntityStackNode
-This Node is pushed to the "Entity Stack" whenever the parser parses entity replacement text.
-The "Instance" field holds the Instance pointer of an External Entity buffer. When it is
-popped, the Instance is freed.
-The "Encoding" field holds the name of the Encoding. External Parsed Entities may have
-another encoding as the document entity (XmlSpec 4.3.3). So when there is an " 0 THEN BEGIN
- ESN := TEntityStackNode (Items [Count-1]);
- Result := ESN.LastPos;
- IF ESN.Instance <> NIL THEN
- ESN.Instance.Free;
- IF ESN.Encoding <> '' THEN
- Owner.FCurEncoding := ESN.Encoding; // Restore current Encoding
- Delete (Count-1);
- END
- ELSE
- Result := NIL;
-END;
-
-
-(*
-===============================================================================================
-TExternalID
------------
-XmlSpec 4.2.2: ExternalID ::= 'SYSTEM' S SystemLiteral |
- 'PUBLIC' S PubidLiteral S SystemLiteral
-XmlSpec 4.7: PublicID ::= 'PUBLIC' S PubidLiteral
-SystemLiteral and PubidLiteral are quoted
-===============================================================================================
-*)
-
-TYPE
- TExternalID = CLASS
- PublicId : STRING;
- SystemId : STRING;
- Final : PChar;
- CONSTRUCTOR Create (Start : PChar);
- END;
-
-CONSTRUCTOR TExternalID.Create (Start : PChar);
-BEGIN
- INHERITED Create;
- Final := Start;
- IF StrLComp (Start, 'SYSTEM', 6) = 0 THEN BEGIN
- WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
- IF NOT (Final^ IN CQuoteChar) THEN EXIT;
- ExtractQuote (Final, SystemID, Final);
- END
- ELSE IF StrLComp (Start, 'PUBLIC', 6) = 0 THEN BEGIN
- WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
- IF NOT (Final^ IN CQuoteChar) THEN EXIT;
- ExtractQuote (Final, PublicID, Final);
- INC (Final);
- WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
- IF NOT (Final^ IN CQuoteChar) THEN EXIT;
- ExtractQuote (Final, SystemID, Final);
- END;
-END;
-
-
-(*
-===============================================================================================
-TXmlParser
-===============================================================================================
-*)
-
-CONSTRUCTOR TXmlParser.Create;
-BEGIN
- INHERITED Create;
- FBuffer := NIL;
- FBufferSize := 0;
- Elements := TElemList.Create;
- Entities := TNvpList.Create;
- ParEntities := TNvpList.Create;
- Notations := TNvpList.Create;
- CurAttr := TAttrList.Create;
- EntityStack := TEntityStack.Create (Self);
- Clear;
-END;
-
-
-DESTRUCTOR TXmlParser.Destroy;
-BEGIN
- Clear;
- Elements.Free;
- Entities.Free;
- ParEntities.Free;
- Notations.Free;
- CurAttr.Free;
- EntityStack.Free;
- INHERITED Destroy;
-END;
-
-
-PROCEDURE TXmlParser.Clear;
- // Free Buffer and clear all object attributes
-BEGIN
- IF (FBufferSize > 0) AND (FBuffer <> NIL) THEN
- FreeMem (FBuffer);
- FBuffer := NIL;
- FBufferSize := 0;
- FSource := '';
- FXmlVersion := '';
- FEncoding := '';
- FStandalone := FALSE;
- FRootName := '';
- FDtdcFinal := NIL;
- FNormalize := TRUE;
- Elements.Clear;
- Entities.Clear;
- ParEntities.Clear;
- Notations.Clear;
- CurAttr.Clear;
- EntityStack.Clear;
-END;
-
-
-FUNCTION TXmlParser.LoadFromFile (Filename : STRING; FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
- // Loads Document from given file
- // Returns TRUE if successful
-VAR
- f : FILE;
- ReadIn : INTEGER;
- OldFileMode : INTEGER;
-BEGIN
- Result := FALSE;
- Clear;
-
- // --- Open File
- OldFileMode := SYSTEM.FileMode;
- TRY
- SYSTEM.FileMode := FileMode;
- TRY
- AssignFile (f, Filename);
- Reset (f, 1);
- EXCEPT
- EXIT;
- END;
-
- TRY
- // --- Allocate Memory
- TRY
- FBufferSize := Filesize (f) + 1;
- GetMem (FBuffer, FBufferSize);
- EXCEPT
- Clear;
- EXIT;
- END;
-
- // --- Read File
- TRY
- BlockRead (f, FBuffer^, FBufferSize, ReadIn);
- (FBuffer+ReadIn)^ := #0; // NULL termination
- EXCEPT
- Clear;
- EXIT;
- END;
- FINALLY
- CloseFile (f);
- END;
-
- FSource := Filename;
- Result := TRUE;
-
- FINALLY
- SYSTEM.FileMode := OldFileMode;
- END;
-END;
-
-
-FUNCTION TXmlParser.LoadFromBuffer (Buffer : PChar) : BOOLEAN;
- // Loads Document from another buffer
- // Returns TRUE if successful
- // The "Source" property becomes '' if successful
-BEGIN
- Result := FALSE;
- Clear;
- FBufferSize := StrLen (Buffer) + 1;
- TRY
- GetMem (FBuffer, FBufferSize);
- EXCEPT
- Clear;
- EXIT;
- END;
- StrCopy (FBuffer, Buffer);
- FSource := '';
- Result := TRUE;
-END;
-
-
-PROCEDURE TXmlParser.SetBuffer (Buffer : PChar); // References another buffer
-BEGIN
- Clear;
- FBuffer := Buffer;
- FBufferSize := 0;
- FSource := '';
-END;
-
-
-//-----------------------------------------------------------------------------------------------
-// Scanning through the document
-//-----------------------------------------------------------------------------------------------
-
-PROCEDURE TXmlParser.StartScan;
-BEGIN
- CurPartType := ptNone;
- CurName := '';
- CurContent := '';
- CurStart := NIL;
- CurFinal := NIL;
- CurAttr.Clear;
- EntityStack.Clear;
-END;
-
-
-FUNCTION TXmlParser.Scan : BOOLEAN;
- // Scans the next Part
- // Returns TRUE if a part could be found, FALSE if there is no part any more
- //
- // "IsDone" can be set to FALSE by AnalyzeText in order to go to the next part
- // if there is no Content due to normalization
-VAR
- IsDone : BOOLEAN;
-BEGIN
- REPEAT
- IsDone := TRUE;
-
- // --- Start of next Part
- IF CurStart = NIL
- THEN CurStart := DocBuffer
- ELSE CurStart := CurFinal+1;
- CurFinal := CurStart;
-
- // --- End of Document of Pop off a new part from the Entity stack?
- IF CurStart^ = #0 THEN
- CurStart := EntityStack.Pop;
-
- // --- No Document or End Of Document: Terminate Scan
- IF (CurStart = NIL) OR (CurStart^ = #0) THEN BEGIN
- CurStart := StrEnd (DocBuffer);
- CurFinal := CurStart-1;
- EntityStack.Clear;
- Result := FALSE;
- EXIT;
- END;
-
- IF (StrLComp (CurStart, '');
- IF CurFinal <> NIL
- THEN INC (CurFinal)
- ELSE CurFinal := StrEnd (CurStart)-1;
- FCurEncoding := AnsiUpperCase (CurAttr.Value ('encoding'));
- IF FCurEncoding = '' THEN
- FCurEncoding := 'UTF-8'; // Default XML Encoding is UTF-8
- CurPartType := ptXmlProlog;
- CurName := '';
- CurContent := '';
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeComment (Start : PChar; VAR Final : PChar);
- // Analyze Comments
-BEGIN
- Final := StrPos (Start+4, '-->');
- IF Final = NIL
- THEN Final := StrEnd (Start)-1
- ELSE INC (Final, 2);
- CurPartType := ptComment;
-END;
-
-
-PROCEDURE TXmlParser.AnalyzePI (Start : PChar; VAR Final : PChar);
- // Analyze Processing Instructions (PI)
- // This is also called for Character
-VAR
- F : PChar;
-BEGIN
- CurPartType := ptPI;
- Final := StrPos (Start+2, '?>');
- IF Final = NIL
- THEN Final := StrEnd (Start)-1
- ELSE INC (Final);
- ExtractName (Start+2, CWhitespace + ['?', '>'], F);
- SetStringSF (CurName, Start+2, F);
- SetStringSF (CurContent, F+1, Final-2);
- CurAttr.Analyze (F+1, F);
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeDtdc;
- (* Analyze Document Type Declaration
- doctypedecl ::= ''
- markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
- PEReference ::= '%' Name ';'
-
- elementdecl ::= ''
- AttlistDecl ::= ''
- EntityDecl ::= '' |
- ''
- NotationDecl ::= ''
- PI ::= '' PITarget (S (Char* - (Char* '?>' Char* )))? '?>'
- Comment ::= '' *)
-TYPE
- TPhase = (phName, phDtd, phInternal, phFinishing);
-VAR
- Phase : TPhase;
- F : PChar;
- ExternalID : TExternalID;
- ExternalDTD : TXmlParser;
- DER : TDtdElementRec;
-BEGIN
- DER.Start := CurStart;
- EntityStack.Clear; // Clear stack for Parameter Entities
- CurPartType := ptDtdc;
-
- // --- Don't read DTDc twice
- IF FDtdcFinal <> NIL THEN BEGIN
- CurFinal := FDtdcFinal;
- EXIT;
- END;
-
- // --- Scan DTDc
- CurFinal := CurStart + 9; // First char after '' : BREAK;
- ELSE IF NOT (CurFinal^ IN CWhitespace) THEN BEGIN
- CASE Phase OF
- phName : IF (CurFinal^ IN CNameStart) THEN BEGIN
- ExtractName (CurFinal, CWhitespace + ['[', '>'], F);
- SetStringSF (FRootName, CurFinal, F);
- CurFinal := F;
- Phase := phDtd;
- END;
- phDtd : IF (StrLComp (CurFinal, 'SYSTEM', 6) = 0) OR
- (StrLComp (CurFinal, 'PUBLIC', 6) = 0) THEN BEGIN
- ExternalID := TExternalID.Create (CurFinal);
- ExternalDTD := LoadExternalEntity (ExternalId.SystemId, ExternalID.PublicId, '');
- F := StrPos (ExternalDtd.DocBuffer, ' NIL THEN
- AnalyzeDtdElements (F, F);
- ExternalDTD.Free;
- CurFinal := ExternalID.Final;
- ExternalID.Free;
- END;
- ELSE BEGIN
- DER.ElementType := deError;
- DER.Pos := CurFinal;
- DER.Final := CurFinal;
- DtdElementFound (DER);
- END;
- END;
-
- END;
- END;
- INC (CurFinal);
- UNTIL FALSE;
-
- CurPartType := ptDtdc;
- CurName := '';
- CurContent := '';
-
- // It is an error in the document if "EntityStack" is not empty now
- IF EntityStack.Count > 0 THEN BEGIN
- DER.ElementType := deError;
- DER.Final := CurFinal;
- DER.Pos := CurFinal;
- DtdElementFound (DER);
- END;
-
- EntityStack.Clear; // Clear stack for General Entities
- FDtdcFinal := CurFinal;
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeDtdElements (Start : PChar; VAR Final : PChar);
- // Analyze the "Elements" of a DTD contained in the external or
- // internal DTD subset.
-VAR
- DER : TDtdElementRec;
-BEGIN
- Final := Start;
- REPEAT
- CASE Final^ OF
- '%' : BEGIN
- PushPE (Final);
- CONTINUE;
- END;
- #0 : IF EntityStack.Count = 0 THEN
- BREAK
- ELSE BEGIN
- CurFinal := EntityStack.Pop;
- CONTINUE;
- END;
- ']',
- '>' : BREAK;
- '<' : IF StrLComp (Final, '');
-
- // --- Set Default Attribute values for nonexistent attributes
- IF (CurPartType = ptStartTag) OR (CurPartType = ptEmptyTag) THEN BEGIN
- ElemDef := Elements.Node (CurName);
- IF ElemDef <> NIL THEN BEGIN
- FOR I := 0 TO ElemDef.Count-1 DO BEGIN
- AttrDef := TAttrDef (ElemDef [I]);
- Attr := TAttr (CurAttr.Node (AttrDef.Name));
- IF (Attr = NIL) AND (AttrDef.Value <> '') THEN BEGIN
- Attr := TAttr.Create (AttrDef.Name, AttrDef.Value);
- Attr.ValueType := vtDefault;
- CurAttr.Add (Attr);
- END;
- IF Attr <> NIL THEN BEGIN
- CASE AttrDef.DefaultType OF
- adDefault : ;
- adRequired : ; // -!- It is an error in the document if "Attr.Value" is an empty string
- adImplied : Attr.ValueType := vtImplied;
- adFixed : BEGIN
- Attr.ValueType := vtFixed;
- Attr.Value := AttrDef.Value;
- END;
- END;
- Attr.AttrType := AttrDef.AttrType;
- END;
- END;
- END;
-
- // --- Normalize Attribute Values. XmlSpec:
- // - a character reference is processed by appending the referenced character to the attribute value
- // - an entity reference is processed by recursively processing the replacement text of the entity
- // - a whitespace character (#x20, #xD, #xA, #x9) is processed by appending #x20 to the normalized value,
- // except that only a single #x20 is appended for a "#xD#xA" sequence that is part of an external
- // parsed entity or the literal entity value of an internal parsed entity
- // - other characters are processed by appending them to the normalized value
- // If the declared value is not CDATA, then the XML processor must further process the
- // normalized attribute value by discarding any leading and trailing space (#x20) characters,
- // and by replacing sequences of space (#x20) characters by a single space (#x20) character.
- // All attributes for which no declaration has been read should be treated by a
- // non-validating parser as if declared CDATA.
- // !!! The XML 1.0 SE specification is somewhat different here
- // This code does not conform exactly to this specification
- FOR I := 0 TO CurAttr.Count-1 DO
- WITH TAttr (CurAttr [I]) DO BEGIN
- ReplaceGeneralEntities (Value);
- ReplaceCharacterEntities (Value);
- IF (AttrType <> atCData) AND (AttrType <> atUnknown)
- THEN Value := TranslateEncoding (TrimWs (ConvertWs (Value, TRUE)))
- ELSE Value := TranslateEncoding (ConvertWs (Value, FALSE));
- END;
- END;
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeCData;
- // Analyze CDATA Sections
-BEGIN
- CurPartType := ptCData;
- CurFinal := StrPos (CurStart, CDEnd);
- IF CurFinal = NIL THEN BEGIN
- CurFinal := StrEnd (CurStart)-1;
- CurContent := TranslateEncoding (StrPas (CurStart+Length (CDStart)));
- END
- ELSE BEGIN
- SetStringSF (CurContent, CurStart+Length (CDStart), CurFinal-1);
- INC (CurFinal, Length (CDEnd)-1);
- CurContent := TranslateEncoding (CurContent);
- END;
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeText (VAR IsDone : BOOLEAN);
- (* Analyzes Text Content between Tags. CurFinal will point to the last content character.
- Content ends at a '<' character or at the end of the document.
- Entity References and Character Entity references are resolved.
- If PackSpaces is TRUE, contiguous Whitespace Characters will be compressed to
- one Space #x20 character, Whitespace at the beginning and end of content will
- be trimmed off and content which is or becomes empty is not returned to
- the application (in this case, "IsDone" is set to FALSE which causes the
- Scan method to proceed directly to the next part. *)
-
- PROCEDURE ProcessEntity;
- (* Is called if there is an ampsersand '&' character found in the document.
- IN "CurFinal" points to the ampersand
- OUT "CurFinal" points to the first character after the semi-colon ';' *)
- VAR
- P : PChar;
- Name : STRING;
- EntityDef : TEntityDef;
- ExternalEntity : TXmlParser;
- BEGIN
- P := StrScan (CurFinal , ';');
- IF P <> NIL THEN BEGIN
- SetStringSF (Name, CurFinal+1, P-1);
-
- // Is it a Character Entity?
- IF (CurFinal+1)^ = '#' THEN BEGIN
- IF UpCase ((CurFinal+2)^) = 'X' // !!! Can't use "CHR" for Unicode characters > 255:
- THEN CurContent := CurContent + CHR (StrToIntDef ('$'+Copy (Name, 3, MaxInt), 32))
- ELSE CurContent := CurContent + CHR (StrToIntDef (Copy (Name, 2, MaxInt), 32));
- CurFinal := P+1;
- EXIT;
- END
-
- // Is it a Predefined Entity?
- ELSE IF Name = 'lt' THEN BEGIN CurContent := CurContent + '<'; CurFinal := P+1; EXIT; END
- ELSE IF Name = 'gt' THEN BEGIN CurContent := CurContent + '>'; CurFinal := P+1; EXIT; END
- ELSE IF Name = 'amp' THEN BEGIN CurContent := CurContent + '&'; CurFinal := P+1; EXIT; END
- ELSE IF Name = 'apos' THEN BEGIN CurContent := CurContent + ''''; CurFinal := P+1; EXIT; END
- ELSE IF Name = 'quot' THEN BEGIN CurContent := CurContent + '"'; CurFinal := P+1; EXIT; END;
-
- // Replace with Entity from DTD
- EntityDef := TEntityDef (Entities.Node (Name));
- IF EntityDef <> NIL THEN BEGIN
- IF EntityDef.Value <> '' THEN BEGIN
- EntityStack.Push (P+1);
- CurFinal := PChar (EntityDef.Value);
- END
- ELSE BEGIN
- ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
- EntityStack.Push (ExternalEntity, P+1);
- CurFinal := ExternalEntity.DocBuffer;
- END;
- END
- ELSE BEGIN
- CurContent := CurContent + Name;
- CurFinal := P+1;
- END;
- END
- ELSE BEGIN
- INC (CurFinal);
- END;
- END;
-
-VAR
- C : INTEGER;
-BEGIN
- CurFinal := CurStart;
- CurPartType := ptContent;
- CurContent := '';
- C := 0;
- REPEAT
- CASE CurFinal^ OF
- '&' : BEGIN
- CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
- C := 0;
- ProcessEntity;
- CONTINUE;
- END;
- #0 : BEGIN
- IF EntityStack.Count = 0 THEN
- BREAK
- ELSE BEGIN
- CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
- C := 0;
- CurFinal := EntityStack.Pop;
- CONTINUE;
- END;
- END;
- '<' : BREAK;
- ELSE INC (C);
- END;
- INC (CurFinal);
- UNTIL FALSE;
- CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
- DEC (CurFinal);
-
- IF FNormalize THEN BEGIN
- CurContent := ConvertWs (TrimWs (CurContent), TRUE);
- IsDone := CurContent <> ''; // IsDone will only get FALSE if PackSpaces is TRUE
- END;
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
- (* Parse ' character
- XmlSpec 3.2:
- elementdecl ::= ''
- contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
- Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
- '(' S? '#PCDATA' S? ')'
- children ::= (choice | seq) ('?' | '*' | '+')?
- choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
- cp ::= (Name | choice | seq) ('?' | '*' | '+')?
- seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
-
- More simply:
- contentspec ::= EMPTY
- ANY
- '(#PCDATA)'
- '(#PCDATA | A | B)*'
- '(A, B, C)'
- '(A | B | C)'
- '(A?, B*, C+),
- '(A, (B | C | D)* )' *)
-VAR
- Element : TElemDef;
- Elem2 : TElemDef;
- F : PChar;
- DER : TDtdElementRec;
-BEGIN
- Element := TElemDef.Create;
- Final := Start + 9;
- DER.Start := Start;
- REPEAT
- IF Final^ = '>' THEN BREAK;
- IF (Final^ IN CNameStart) AND (Element.Name = '') THEN BEGIN
- ExtractName (Final, CWhitespace, F);
- SetStringSF (Element.Name, Final, F);
- Final := F;
- F := StrScan (Final+1, '>');
- IF F = NIL THEN BEGIN
- Element.Definition := STRING (Final);
- Final := StrEnd (Final);
- BREAK;
- END
- ELSE BEGIN
- SetStringSF (Element.Definition, Final+1, F-1);
- Final := F;
- BREAK;
- END;
- END;
- INC (Final);
- UNTIL FALSE;
- Element.Definition := DelChars (Element.Definition, CWhitespace);
- ReplaceParameterEntities (Element.Definition);
- IF Element.Definition = 'EMPTY' THEN Element.ElemType := etEmpty
- ELSE IF Element.Definition = 'ANY' THEN Element.ElemType := etAny
- ELSE IF Copy (Element.Definition, 1, 8) = '(#PCDATA' THEN Element.ElemType := etMixed
- ELSE IF Copy (Element.Definition, 1, 1) = '(' THEN Element.ElemType := etChildren
- ELSE Element.ElemType := etAny;
-
- Elem2 := Elements.Node (Element.Name);
- IF Elem2 <> NIL THEN
- Elements.Delete (Elements.IndexOf (Elem2));
- Elements.Add (Element);
- Final := StrScanE (Final, '>');
- DER.ElementType := deElement;
- DER.ElemDef := Element;
- DER.Final := Final;
- DtdElementFound (DER);
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
- (* Parse ' character
- XmlSpec 3.3:
- AttlistDecl ::= ''
- AttDef ::= S Name S AttType S DefaultDecl
- AttType ::= StringType | TokenizedType | EnumeratedType
- StringType ::= 'CDATA'
- TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
- EnumeratedType ::= NotationType | Enumeration
- NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
- Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
- DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
- AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
- Examples:
- *)
-TYPE
- TPhase = (phElementName, phName, phType, phNotationContent, phDefault);
-VAR
- Phase : TPhase;
- F : PChar;
- ElementName : STRING;
- ElemDef : TElemDef;
- AttrDef : TAttrDef;
- AttrDef2 : TAttrDef;
- Strg : STRING;
- DER : TDtdElementRec;
-BEGIN
- Final := Start + 9; // The character after ' : BREAK;
- ELSE CASE Phase OF
- phElementName : BEGIN
- ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
- SetStringSF (ElementName, Final, F);
- Final := F;
- ElemDef := Elements.Node (ElementName);
- IF ElemDef = NIL THEN BEGIN
- ElemDef := TElemDef.Create;
- ElemDef.Name := ElementName;
- ElemDef.Definition := 'ANY';
- ElemDef.ElemType := etAny;
- Elements.Add (ElemDef);
- END;
- Phase := phName;
- END;
- phName : BEGIN
- AttrDef := TAttrDef.Create;
- ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
- SetStringSF (AttrDef.Name, Final, F);
- Final := F;
- AttrDef2 := TAttrDef (ElemDef.Node (AttrDef.Name));
- IF AttrDef2 <> NIL THEN
- ElemDef.Delete (ElemDef.IndexOf (AttrDef2));
- ElemDef.Add (AttrDef);
- Phase := phType;
- END;
- phType : BEGIN
- IF Final^ = '(' THEN BEGIN
- F := StrScan (Final+1, ')');
- IF F <> NIL
- THEN SetStringSF (AttrDef.TypeDef, Final+1, F-1)
- ELSE AttrDef.TypeDef := STRING (Final+1);
- AttrDef.TypeDef := DelChars (AttrDef.TypeDef, CWhitespace);
- AttrDef.AttrType := atEnumeration;
- ReplaceParameterEntities (AttrDef.TypeDef);
- ReplaceCharacterEntities (AttrDef.TypeDef);
- Phase := phDefault;
- END
- ELSE IF StrLComp (Final, 'NOTATION', 8) = 0 THEN BEGIN
- INC (Final, 8);
- AttrDef.AttrType := atNotation;
- Phase := phNotationContent;
- END
- ELSE BEGIN
- ExtractName (Final, CWhitespace+CQuoteChar+['#'], F);
- SetStringSF (AttrDef.TypeDef, Final, F);
- IF AttrDef.TypeDef = 'CDATA' THEN AttrDef.AttrType := atCData
- ELSE IF AttrDef.TypeDef = 'ID' THEN AttrDef.AttrType := atId
- ELSE IF AttrDef.TypeDef = 'IDREF' THEN AttrDef.AttrType := atIdRef
- ELSE IF AttrDef.TypeDef = 'IDREFS' THEN AttrDef.AttrType := atIdRefs
- ELSE IF AttrDef.TypeDef = 'ENTITY' THEN AttrDef.AttrType := atEntity
- ELSE IF AttrDef.TypeDef = 'ENTITIES' THEN AttrDef.AttrType := atEntities
- ELSE IF AttrDef.TypeDef = 'NMTOKEN' THEN AttrDef.AttrType := atNmToken
- ELSE IF AttrDef.TypeDef = 'NMTOKENS' THEN AttrDef.AttrType := atNmTokens;
- Phase := phDefault;
- END
- END;
- phNotationContent : BEGIN
- F := StrScan (Final, ')');
- IF F <> NIL THEN
- SetStringSF (AttrDef.Notations, Final+1, F-1)
- ELSE BEGIN
- AttrDef.Notations := STRING (Final+1);
- Final := StrEnd (Final);
- END;
- ReplaceParameterEntities (AttrDef.Notations);
- AttrDef.Notations := DelChars (AttrDef.Notations, CWhitespace);
- Phase := phDefault;
- END;
- phDefault : BEGIN
- IF Final^ = '#' THEN BEGIN
- ExtractName (Final, CWhiteSpace + CQuoteChar, F);
- SetStringSF (Strg, Final, F);
- Final := F;
- ReplaceParameterEntities (Strg);
- IF Strg = '#REQUIRED' THEN BEGIN AttrDef.DefaultType := adRequired; Phase := phName; END
- ELSE IF Strg = '#IMPLIED' THEN BEGIN AttrDef.DefaultType := adImplied; Phase := phName; END
- ELSE IF Strg = '#FIXED' THEN AttrDef.DefaultType := adFixed;
- END
- ELSE IF (Final^ IN CQuoteChar) THEN BEGIN
- ExtractQuote (Final, AttrDef.Value, Final);
- ReplaceParameterEntities (AttrDef.Value);
- ReplaceCharacterEntities (AttrDef.Value);
- Phase := phName;
- END;
- IF Phase = phName THEN BEGIN
- AttrDef := NIL;
- END;
- END;
-
- END;
- END;
- INC (Final);
- UNTIL FALSE;
-
- Final := StrScan (Final, '>');
-
- DER.ElementType := deAttList;
- DER.ElemDef := ElemDef;
- DER.Final := Final;
- DtdElementFound (DER);
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
- (* Parse ' character
- XmlSpec 4.2:
- EntityDecl ::= '' |
- ''
- EntityDef ::= EntityValue | (ExternalID NDataDecl?)
- PEDef ::= EntityValue | ExternalID
- NDataDecl ::= S 'NDATA' S Name
- EntityValue ::= '"' ([^%&"] | PEReference | EntityRef | CharRef)* '"' |
- "'" ([^%&'] | PEReference | EntityRef | CharRef)* "'"
- PEReference ::= '%' Name ';'
-
- Examples
-
-
-
- ">
-
-
- Dies ist ein Test-Absatz
">
- *)
-TYPE
- TPhase = (phName, phContent, phNData, phNotationName, phFinalGT);
-VAR
- Phase : TPhase;
- IsParamEntity : BOOLEAN;
- F : PChar;
- ExternalID : TExternalID;
- EntityDef : TEntityDef;
- EntityDef2 : TEntityDef;
- DER : TDtdElementRec;
-BEGIN
- Final := Start + 8; // First char after ' : BREAK;
- ELSE CASE Phase OF
- phName : IF Final^ IN CNameStart THEN BEGIN
- ExtractName (Final, CWhitespace + CQuoteChar, F);
- SetStringSF (EntityDef.Name, Final, F);
- Final := F;
- Phase := phContent;
- END;
- phContent : IF Final^ IN CQuoteChar THEN BEGIN
- ExtractQuote (Final, EntityDef.Value, Final);
- Phase := phFinalGT;
- END
- ELSE IF (StrLComp (Final, 'SYSTEM', 6) = 0) OR
- (StrLComp (Final, 'PUBLIC', 6) = 0) THEN BEGIN
- ExternalID := TExternalID.Create (Final);
- EntityDef.SystemId := ExternalID.SystemId;
- EntityDef.PublicId := ExternalID.PublicId;
- Final := ExternalID.Final;
- Phase := phNData;
- ExternalID.Free;
- END;
- phNData : IF StrLComp (Final, 'NDATA', 5) = 0 THEN BEGIN
- INC (Final, 4);
- Phase := phNotationName;
- END;
- phNotationName : IF Final^ IN CNameStart THEN BEGIN
- ExtractName (Final, CWhitespace + ['>'], F);
- SetStringSF (EntityDef.NotationName, Final, F);
- Final := F;
- Phase := phFinalGT;
- END;
- phFinalGT : ; // -!- There is an error in the document if this branch is called
- END;
- END;
- INC (Final);
- UNTIL FALSE;
- IF IsParamEntity THEN BEGIN
- EntityDef2 := TEntityDef (ParEntities.Node (EntityDef.Name));
- IF EntityDef2 <> NIL THEN
- ParEntities.Delete (ParEntities.IndexOf (EntityDef2));
- ParEntities.Add (EntityDef);
- ReplaceCharacterEntities (EntityDef.Value);
- END
- ELSE BEGIN
- EntityDef2 := TEntityDef (Entities.Node (EntityDef.Name));
- IF EntityDef2 <> NIL THEN
- Entities.Delete (Entities.IndexOf (EntityDef2));
- Entities.Add (EntityDef);
- ReplaceParameterEntities (EntityDef.Value); // Create replacement texts (see XmlSpec 4.5)
- ReplaceCharacterEntities (EntityDef.Value);
- END;
- Final := StrScanE (Final, '>');
-
- DER.ElementType := deEntity;
- DER.EntityDef := EntityDef;
- DER.Final := Final;
- DtdElementFound (DER);
-END;
-
-
-PROCEDURE TXmlParser.AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
- // Parse ' character
- // XmlSpec 4.7: NotationDecl ::= ''
-TYPE
- TPhase = (phName, phExtId, phEnd);
-VAR
- ExternalID : TExternalID;
- Phase : TPhase;
- F : PChar;
- NotationDef : TNotationDef;
- DER : TDtdElementRec;
-BEGIN
- Final := Start + 10; // Character after ',
- #0 : BREAK;
- ELSE CASE Phase OF
- phName : BEGIN
- ExtractName (Final, CWhitespace + ['>'], F);
- SetStringSF (NotationDef.Name, Final, F);
- Final := F;
- Phase := phExtId;
- END;
- phExtId : BEGIN
- ExternalID := TExternalID.Create (Final);
- NotationDef.Value := ExternalID.SystemId;
- NotationDef.PublicId := ExternalID.PublicId;
- Final := ExternalId.Final;
- ExternalId.Free;
- Phase := phEnd;
- END;
- phEnd : ; // -!- There is an error in the document if this branch is called
- END;
- END;
- INC (Final);
- UNTIL FALSE;
- Notations.Add (NotationDef);
- Final := StrScanE (Final, '>');
-
- DER.ElementType := deNotation;
- DER.NotationDef := NotationDef;
- DER.Final := Final;
- DtdElementFound (DER);
-END;
-
-
-PROCEDURE TXmlParser.PushPE (VAR Start : PChar);
- (* If there is a parameter entity reference found in the data stream,
- the current position will be pushed to the entity stack.
- Start: IN Pointer to the '%' character starting the PE reference
- OUT Pointer to first character of PE replacement text *)
-VAR
- P : PChar;
- EntityDef : TEntityDef;
-BEGIN
- P := StrScan (Start, ';');
- IF P <> NIL THEN BEGIN
- EntityDef := TEntityDef (ParEntities.Node (StrSFPas (Start+1, P-1)));
- IF EntityDef <> NIL THEN BEGIN
- EntityStack.Push (P+1);
- Start := PChar (EntityDef.Value);
- END
- ELSE
- Start := P+1;
- END;
-END;
-
-
-PROCEDURE TXmlParser.ReplaceCharacterEntities (VAR Str : STRING);
- // Replaces all Character Entity References in the String
-VAR
- Start : INTEGER;
- PAmp : PChar;
- PSemi : PChar;
- PosAmp : INTEGER;
- Len : INTEGER; // Length of Entity Reference
-BEGIN
- IF Str = '' THEN EXIT;
- Start := 1;
- REPEAT
- PAmp := StrPos (PChar (Str) + Start-1, '');
- IF PAmp = NIL THEN BREAK;
- PSemi := StrScan (PAmp+2, ';');
- IF PSemi = NIL THEN BREAK;
- PosAmp := PAmp - PChar (Str) + 1;
- Len := PSemi-PAmp+1;
- IF CompareText (Str [PosAmp+2], 'x') = 0 // !!! Can't use "CHR" for Unicode characters > 255
- THEN Str [PosAmp] := CHR (StrToIntDef ('$'+Copy (Str, PosAmp+3, Len-4), 0))
- ELSE Str [PosAmp] := CHR (StrToIntDef (Copy (Str, PosAmp+2, Len-3), 32));
- Delete (Str, PosAmp+1, Len-1);
- Start := PosAmp + 1;
- UNTIL FALSE;
-END;
-
-
-PROCEDURE TXmlParser.ReplaceParameterEntities (VAR Str : STRING);
- // Recursively replaces all Parameter Entity References in the String
- PROCEDURE ReplaceEntities (VAR Str : STRING);
- VAR
- Start : INTEGER;
- PAmp : PChar;
- PSemi : PChar;
- PosAmp : INTEGER;
- Len : INTEGER;
- Entity : TEntityDef;
- Repl : STRING; // Replacement
- BEGIN
- IF Str = '' THEN EXIT;
- Start := 1;
- REPEAT
- PAmp := StrPos (PChar (Str)+Start-1, '%');
- IF PAmp = NIL THEN BREAK;
- PSemi := StrScan (PAmp+2, ';');
- IF PSemi = NIL THEN BREAK;
- PosAmp := PAmp - PChar (Str) + 1;
- Len := PSemi-PAmp+1;
- Entity := TEntityDef (ParEntities.Node (Copy (Str, PosAmp+1, Len-2)));
- IF Entity <> NIL THEN BEGIN
- Repl := Entity.Value;
- ReplaceEntities (Repl); // Recursion
- END
- ELSE
- Repl := Copy (Str, PosAmp, Len);
- Delete (Str, PosAmp, Len);
- Insert (Repl, Str, PosAmp);
- Start := PosAmp + Length (Repl);
- UNTIL FALSE;
- END;
-BEGIN
- ReplaceEntities (Str);
-END;
-
-
-PROCEDURE TXmlParser.ReplaceGeneralEntities (VAR Str : STRING);
- // Recursively replaces General Entity References in the String
- PROCEDURE ReplaceEntities (VAR Str : STRING);
- VAR
- Start : INTEGER;
- PAmp : PChar;
- PSemi : PChar;
- PosAmp : INTEGER;
- Len : INTEGER;
- EntityDef : TEntityDef;
- EntName : STRING;
- Repl : STRING; // Replacement
- ExternalEntity : TXmlParser;
- BEGIN
- IF Str = '' THEN EXIT;
- Start := 1;
- REPEAT
- PAmp := StrPos (PChar (Str)+Start-1, '&');
- IF PAmp = NIL THEN BREAK;
- PSemi := StrScan (PAmp+2, ';');
- IF PSemi = NIL THEN BREAK;
- PosAmp := PAmp - PChar (Str) + 1;
- Len := PSemi-PAmp+1;
- EntName := Copy (Str, PosAmp+1, Len-2);
- IF EntName = 'lt' THEN Repl := '<'
- ELSE IF EntName = 'gt' THEN Repl := '>'
- ELSE IF EntName = 'amp' THEN Repl := '&'
- ELSE IF EntName = 'apos' THEN Repl := ''''
- ELSE IF EntName = 'quot' THEN Repl := '"'
- ELSE BEGIN
- EntityDef := TEntityDef (Entities.Node (EntName));
- IF EntityDef <> NIL THEN BEGIN
- IF EntityDef.Value <> '' THEN // Internal Entity
- Repl := EntityDef.Value
- ELSE BEGIN // External Entity
- ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
- Repl := StrPas (ExternalEntity.DocBuffer); // !!! What if it contains a Text Declaration?
- ExternalEntity.Free;
- END;
- ReplaceEntities (Repl); // Recursion
- END
- ELSE
- Repl := Copy (Str, PosAmp, Len);
- END;
- Delete (Str, PosAmp, Len);
- Insert (Repl, Str, PosAmp);
- Start := PosAmp + Length (Repl);
- UNTIL FALSE;
- END;
-BEGIN
- ReplaceEntities (Str);
-END;
-
-
-FUNCTION TXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
- // This will be called whenever there is a Parsed External Entity or
- // the DTD External Subset to be parsed.
- // It has to create a TXmlParser instance and load the desired Entity.
- // This instance of LoadExternalEntity assumes that "SystemId" is a valid
- // file name (relative to the Document source) and loads this file using
- // the LoadFromFile method.
-VAR
- Filename : STRING;
-BEGIN
- // --- Convert System ID to complete filename
- Filename := StringReplace (SystemId, '/', '\', [rfReplaceAll]);
- IF Copy (FSource, 1, 1) <> '<' THEN
- IF (Copy (Filename, 1, 2) = '\\') OR (Copy (Filename, 2, 1) = ':') THEN
- // Already has an absolute Path
- ELSE BEGIN
- Filename := ExtractFilePath (FSource) + Filename;
- END;
-
- // --- Load the File
- Result := TXmlParser.Create;
- Result.LoadFromFile (Filename);
-END;
-
-
-FUNCTION TXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
- // The member variable "CurEncoding" always holds the name of the current
- // encoding, e.g. 'UTF-8' or 'ISO-8859-1'.
- // This virtual method "TranslateEncoding" is responsible for translating
- // the content passed in the "Source" parameter to the Encoding which
- // is expected by the application.
- // This instance of "TranlateEncoding" assumes that the Application expects
- // Windows ANSI (Win1252) strings. It is able to transform UTF-8 or ISO-8859-1
- // encodings.
- // If you want your application to understand or create other encodings, you
- // override this function.
-BEGIN
- IF CurEncoding = 'UTF-8'
- THEN Result := Utf8ToAnsi (Source)
- ELSE Result := Source;
-END;
-
-
-PROCEDURE TXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
- // This method is called for every element which is found in the DTD
- // declaration. The variant record TDtdElementRec is passed which
- // holds informations about the element.
- // You can override this function to handle DTD declarations.
- // Note that when you parse the same Document instance a second time,
- // the DTD will not get parsed again.
-BEGIN
-END;
-
-
-FUNCTION TXmlParser.GetDocBuffer: PChar;
- // Returns FBuffer or a pointer to a NUL char if Buffer is empty
-BEGIN
- IF FBuffer = NIL
- THEN Result := #0
- ELSE Result := FBuffer;
-END;
-
-
-(*$IFNDEF HAS_CONTNRS_UNIT
-===============================================================================================
-TObjectList
-===============================================================================================
-*)
-
-DESTRUCTOR TObjectList.Destroy;
-BEGIN
- Clear;
- SetCapacity(0);
- INHERITED Destroy;
-END;
-
-
-PROCEDURE TObjectList.Delete (Index : INTEGER);
-BEGIN
- IF (Index < 0) OR (Index >= Count) THEN EXIT;
- TObject (Items [Index]).Free;
- INHERITED Delete (Index);
-END;
-
-
-PROCEDURE TObjectList.Clear;
-BEGIN
- WHILE Count > 0 DO
- Delete (Count-1);
-END;
-
-(*$ENDIF *)
-
-(*
-===============================================================================================
-TNvpNode
---------
-Node base class for the TNvpList
-===============================================================================================
-*)
-
-CONSTRUCTOR TNvpNode.Create (TheName, TheValue : STRING);
-BEGIN
- INHERITED Create;
- Name := TheName;
- Value := TheValue;
-END;
-
-
-(*
-===============================================================================================
-TNvpList
---------
-A generic List of Name-Value Pairs, based on the TObjectList introduced in Delphi 5
-===============================================================================================
-*)
-
-PROCEDURE TNvpList.Add (Node : TNvpNode);
-VAR
- I : INTEGER;
-BEGIN
- FOR I := Count-1 DOWNTO 0 DO
- IF Node.Name > TNvpNode (Items [I]).Name THEN BEGIN
- Insert (I+1, Node);
- EXIT;
- END;
- Insert (0, Node);
-END;
-
-
-
-FUNCTION TNvpList.Node (Name : STRING) : TNvpNode;
- // Binary search for Node
-VAR
- L, H : INTEGER; // Low, High Limit
- T, C : INTEGER; // Test Index, Comparison result
- Last : INTEGER; // Last Test Index
-BEGIN
- IF Count=0 THEN BEGIN
- Result := NIL;
- EXIT;
- END;
-
- L := 0;
- H := Count;
- Last := -1;
- REPEAT
- T := (L+H) DIV 2;
- IF T=Last THEN BREAK;
- Result := TNvpNode (Items [T]);
- C := CompareStr (Result.Name, Name);
- IF C = 0 THEN EXIT
- ELSE IF C < 0 THEN L := T
- ELSE H := T;
- Last := T;
- UNTIL FALSE;
- Result := NIL;
-END;
-
-
-FUNCTION TNvpList.Node (Index : INTEGER) : TNvpNode;
-BEGIN
- IF (Index < 0) OR (Index >= Count)
- THEN Result := NIL
- ELSE Result := TNvpNode (Items [Index]);
-END;
-
-
-FUNCTION TNvpList.Value (Name : STRING) : STRING;
-VAR
- Nvp : TNvpNode;
-BEGIN
- Nvp := TNvpNode (Node (Name));
- IF Nvp <> NIL
- THEN Result := Nvp.Value
- ELSE Result := '';
-END;
-
-
-FUNCTION TNvpList.Value (Index : INTEGER) : STRING;
-BEGIN
- IF (Index < 0) OR (Index >= Count)
- THEN Result := ''
- ELSE Result := TNvpNode (Items [Index]).Value;
-END;
-
-
-FUNCTION TNvpList.Name (Index : INTEGER) : STRING;
-BEGIN
- IF (Index < 0) OR (Index >= Count)
- THEN Result := ''
- ELSE Result := TNvpNode (Items [Index]).Name;
-END;
-
-
-(*
-===============================================================================================
-TAttrList
-List of Attributes. The "Analyze" method extracts the Attributes from the given Buffer.
-Is used for extraction of Attributes in Start-Tags, Empty-Element Tags and the "pseudo"
-attributes in XML Prologs, Text Declarations and PIs.
-===============================================================================================
-*)
-
-PROCEDURE TAttrList.Analyze (Start : PChar; VAR Final : PChar);
- // Analyze the Buffer for Attribute=Name pairs.
- // Terminates when there is a character which is not IN CNameStart
- // (e.g. '?>' or '>' or '/>')
-TYPE
- TPhase = (phName, phEq, phValue);
-VAR
- Phase : TPhase;
- F : PChar;
- Name : STRING;
- Value : STRING;
- Attr : TAttr;
-BEGIN
- Clear;
- Phase := phName;
- Final := Start;
- REPEAT
- IF (Final^ = #0) OR (Final^ = '>') THEN BREAK;
- IF NOT (Final^ IN CWhitespace) THEN
- CASE Phase OF
- phName : BEGIN
- IF NOT (Final^ IN CNameStart) THEN EXIT;
- ExtractName (Final, CWhitespace + ['=', '/'], F);
- SetStringSF (Name, Final, F);
- Final := F;
- Phase := phEq;
- END;
- phEq : BEGIN
- IF Final^ = '=' THEN
- Phase := phValue
- END;
- phValue : BEGIN
- IF Final^ IN CQuoteChar THEN BEGIN
- ExtractQuote (Final, Value, F);
- Attr := TAttr.Create;
- Attr.Name := Name;
- Attr.Value := Value;
- Attr.ValueType := vtNormal;
- Add (Attr);
- Final := F;
- Phase := phName;
- END;
- END;
- END;
- INC (Final);
- UNTIL FALSE;
-END;
-
-
-(*
-===============================================================================================
-TElemList
-List of TElemDef nodes.
-===============================================================================================
-*)
-
-FUNCTION TElemList.Node (Name : STRING) : TElemDef;
- // Binary search for the Node with the given Name
-VAR
- L, H : INTEGER; // Low, High Limit
- T, C : INTEGER; // Test Index, Comparison result
- Last : INTEGER; // Last Test Index
-BEGIN
- IF Count=0 THEN BEGIN
- Result := NIL;
- EXIT;
- END;
-
- L := 0;
- H := Count;
- Last := -1;
- REPEAT
- T := (L+H) DIV 2;
- IF T=Last THEN BREAK;
- Result := TElemDef (Items [T]);
- C := CompareStr (Result.Name, Name);
- IF C = 0 THEN EXIT
- ELSE IF C < 0 THEN L := T
- ELSE H := T;
- Last := T;
- UNTIL FALSE;
- Result := NIL;
-END;
-
-
-PROCEDURE TElemList.Add (Node : TElemDef);
-VAR
- I : INTEGER;
-BEGIN
- FOR I := Count-1 DOWNTO 0 DO
- IF Node.Name > TElemDef (Items [I]).Name THEN BEGIN
- Insert (I+1, Node);
- EXIT;
- END;
- Insert (0, Node);
-END;
-
-
-(*
-===============================================================================================
-TScannerXmlParser
-A TXmlParser descendant for the TCustomXmlScanner component
-===============================================================================================
-*)
-
-TYPE
- TScannerXmlParser = CLASS (TXmlParser)
- Scanner : TCustomXmlScanner;
- CONSTRUCTOR Create (TheScanner : TCustomXmlScanner);
- FUNCTION LoadExternalEntity (SystemId, PublicId,
- Notation : STRING) : TXmlParser; OVERRIDE;
- FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; OVERRIDE;
- PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); OVERRIDE;
- END;
-
-CONSTRUCTOR TScannerXmlParser.Create (TheScanner : TCustomXmlScanner);
-BEGIN
- INHERITED Create;
- Scanner := TheScanner;
-END;
-
-
-FUNCTION TScannerXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
-BEGIN
- IF Assigned (Scanner.FOnLoadExternal)
- THEN Scanner.FOnLoadExternal (Scanner, SystemId, PublicId, Notation, Result)
- ELSE Result := INHERITED LoadExternalEntity (SystemId, PublicId, Notation);
-END;
-
-
-FUNCTION TScannerXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
-BEGIN
- IF Assigned (Scanner.FOnTranslateEncoding)
- THEN Result := Scanner.FOnTranslateEncoding (Scanner, CurEncoding, Source)
- ELSE Result := INHERITED TranslateEncoding (Source);
-END;
-
-
-PROCEDURE TScannerXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
-BEGIN
- WITH DtdElementRec DO
- CASE ElementType OF
- deElement : Scanner.WhenElement (ElemDef);
- deAttList : Scanner.WhenAttList (ElemDef);
- deEntity : Scanner.WhenEntity (EntityDef);
- deNotation : Scanner.WhenNotation (NotationDef);
- dePI : Scanner.WhenPI (STRING (Target), STRING (Content), AttrList);
- deComment : Scanner.WhenComment (StrSFPas (Start, Final));
- deError : Scanner.WhenDtdError (Pos);
- END;
-END;
-
-
-(*
-===============================================================================================
-TCustomXmlScanner
-===============================================================================================
-*)
-
-CONSTRUCTOR TCustomXmlScanner.Create (AOwner: TComponent);
-BEGIN
- INHERITED;
- FXmlParser := TScannerXmlParser.Create (Self);
-END;
-
-
-DESTRUCTOR TCustomXmlScanner.Destroy;
-BEGIN
- FXmlParser.Free;
- INHERITED;
-END;
-
-
-PROCEDURE TCustomXmlScanner.LoadFromFile (Filename : TFilename);
- // Load XML Document from file
-BEGIN
- FXmlParser.LoadFromFile (Filename);
-END;
-
-
-PROCEDURE TCustomXmlScanner.LoadFromBuffer (Buffer : PChar);
- // Load XML Document from buffer
-BEGIN
- FXmlParser.LoadFromBuffer (Buffer);
-END;
-
-
-PROCEDURE TCustomXmlScanner.SetBuffer (Buffer : PChar);
- // Refer to Buffer
-BEGIN
- FXmlParser.SetBuffer (Buffer);
-END;
-
-
-FUNCTION TCustomXmlScanner.GetFilename : TFilename;
-BEGIN
- Result := FXmlParser.Source;
-END;
-
-
-FUNCTION TCustomXmlScanner.GetNormalize : BOOLEAN;
-BEGIN
- Result := FXmlParser.Normalize;
-END;
-
-
-PROCEDURE TCustomXmlScanner.SetNormalize (Value : BOOLEAN);
-BEGIN
- FXmlParser.Normalize := Value;
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN);
- // Is called when the parser has parsed the xml ?> declaration of the prolog
-BEGIN
- IF Assigned (FOnXmlProlog) THEN FOnXmlProlog (Self, XmlVersion, Encoding, Standalone);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenComment (Comment : STRING);
- // Is called when the parser has parsed a
-BEGIN
- IF Assigned (FOnComment) THEN FOnComment (Self, Comment);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenPI (Target, Content: STRING; Attributes : TAttrList);
- // Is called when the parser has parsed a
-BEGIN
- IF Assigned (FOnPI) THEN FOnPI (Self, Target, Content, Attributes);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenDtdRead (RootElementName : STRING);
- // Is called when the parser has completely parsed the DTD
-BEGIN
- IF Assigned (FOnDtdRead) THEN FOnDtdRead (Self, RootElementName);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenStartTag (TagName : STRING; Attributes : TAttrList);
- // Is called when the parser has parsed a start tag like
-BEGIN
- IF Assigned (FOnStartTag) THEN FOnStartTag (Self, TagName, Attributes);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenEmptyTag (TagName : STRING; Attributes : TAttrList);
- // Is called when the parser has parsed an Empty Element Tag like
-BEGIN
- IF Assigned (FOnEmptyTag) THEN FOnEmptyTag (Self, TagName, Attributes);
-END;
-
-
-PROCEDURE TCustomXmlScanner.WhenEndTag (TagName : STRING);
- // Is called when the parser has parsed an End Tag like
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-*}
-function Pa_GetDefaultOutputDevice(): TPaDeviceIndex; cdecl; external LibName;
-
-
-{** The type used to represent monotonic time in seconds that can be used
- for syncronisation. The type is used for the outTime argument to the
- PaStreamCallback and as the result of Pa_GetStreamTime().
-
- @see PaStreamCallback, Pa_GetStreamTime
-*}
-type TPaTime = cdouble;
-
-
-{** A type used to specify one or more sample formats. Each value indicates
- a possible format for sound data passed to and from the stream callback,
- Pa_ReadStream and Pa_WriteStream.
-
- The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
- and aUInt8 are usually implemented by all implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
- The paNonInterleaved flag indicates that a multichannel buffer is passed
- as a set of non-interleaved pointers.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
- @see paFloat32, paInt16, paInt32, paInt24, paInt8
- @see paUInt8, paCustomFormat, paNonInterleaved
-*}
-type TPaSampleFormat = culong;
-const
- paFloat32 = TPaSampleFormat($00000001); {**< @see PaSampleFormat *}
- paInt32 = TPaSampleFormat($00000002); {**< @see PaSampleFormat *}
- paInt24 = TPaSampleFormat($00000004); {**< Packed 24 bit format. @see PaSampleFormat *}
- paInt16 = TPaSampleFormat($00000008); {**< @see PaSampleFormat *}
- paInt8 = TPaSampleFormat($00000010); {**< @see PaSampleFormat *}
- paUInt8 = TPaSampleFormat($00000020); {**< @see PaSampleFormat *}
- paCustomFormat = TPaSampleFormat($00010000); {**< @see PaSampleFormat *}
- paNonInterleaved = TPaSampleFormat($80000000);
-
-{** A structure providing information and capabilities of PortAudio devices.
- Devices may support input, output or both input and output.
-*}
-type
- PPaDeviceInfo = ^TPaDeviceInfo;
- TPaDeviceInfo = record
- structVersion: cint; {* this is struct version 2 *}
- name: PChar;
- hostApi: TPaHostApiIndex; {* note this is a host API index, not a type id*}
-
- maxInputChannels: cint;
- maxOutputChannels: cint;
-
- {* Default latency values for interactive performance. *}
- defaultLowInputLatency: TPaTime;
- defaultLowOutputLatency: TPaTime;
- {* Default latency values for robust non-interactive applications (eg. playing sound files). *}
- defaultHighInputLatency: TPaTime;
- defaultHighOutputLatency: TPaTime;
-
- defaultSampleRate: cdouble;
- end;
-
-
-{** Retrieve a pointer to a PaDeviceInfo structure containing information
- about the specified device.
- @return A pointer to an immutable PaDeviceInfo structure. If the device
- parameter is out of range the function returns NULL.
-
- @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
-
- @note PortAudio manages the memory referenced by the returned pointer,
- the client must not manipulate or free the memory. The pointer is only
- guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
-
- @see PaDeviceInfo, PaDeviceIndex
-*}
-function Pa_GetDeviceInfo( device: TPaDeviceIndex ): PPaDeviceInfo; cdecl; external LibName;
-
-
-{** Parameters for one direction (input or output) of a stream.
-*}
-type
- PPaStreamParameters = ^TPaStreamParameters;
- TPaStreamParameters = record
- {** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
- specifying the device to be used or the special constant
- paUseHostApiSpecificDeviceSpecification which indicates that the actual
- device(s) to use are specified in hostApiSpecificStreamInfo.
- This field must not be set to paNoDevice.
- *}
- device: TPaDeviceIndex;
-
- {** The number of channels of sound to be delivered to the
- stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
- It can range from 1 to the value of maxInputChannels in the
- PaDeviceInfo record for the device specified by the device parameter.
- *}
- channelCount: cint;
-
- {** The sample format of the buffer provided to the stream callback,
- a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
- by the PaSampleFormat enumeration.
- *}
- sampleFormat: TPaSampleFormat;
-
- {** The desired latency in seconds. Where practical, implementations should
- configure their latency based on these parameters, otherwise they may
- choose the closest viable latency instead. Unless the suggested latency
- is greater than the absolute upper limit for the device implementations
- should round the suggestedLatency up to the next practial value - ie to
- provide an equal or higher latency than suggestedLatency wherever possibe.
- Actual latency values for an open stream may be retrieved using the
- inputLatency and outputLatency fields of the PaStreamInfo structure
- returned by Pa_GetStreamInfo().
- @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
- *}
- suggestedLatency: TPaTime;
-
- {** An optional pointer to a host api specific data structure
- containing additional information for device setup and/or stream processing.
- hostApiSpecificStreamInfo is never required for correct operation,
- if not used it should be set to NULL.
- *}
- hostApiSpecificStreamInfo: Pointer;
- end;
-
-
-{** Return code for Pa_IsFormatSupported indicating success. *}
-const paFormatIsSupported = (0);
-
-{** Determine whether it would be possible to open a stream with the specified
- parameters.
-
- @param inputParameters A structure that describes the input parameters used to
- open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. inputParameters must be NULL for
- output-only streams.
-
- @param outputParameters A structure that describes the output parameters used
- to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. outputParameters must be NULL for
- input-only streams.
-
- @param sampleRate The required sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- @return Returns 0 if the format is supported, and an error code indicating why
- the format is not supported otherwise. The constant paFormatIsSupported is
- provided to compare with the return value for success.
-
- @see paFormatIsSupported, PaStreamParameters
-*}
-function Pa_IsFormatSupported( inputParameters: PPaStreamParameters;
- outputParameters: PPaStreamParameters;
- sampleRate: cdouble ): TPaError; cdecl; external LibName;
-
-
-
-{* Streaming types and functions *}
-
-
-{**
- A single PaStream can provide multiple channels of real-time
- streaming audio input and output to a client application. A stream
- provides access to audio hardware represented by one or more
- PaDevices. Depending on the underlying Host API, it may be possible
- to open multiple streams using the same device, however this behavior
- is implementation defined. Portable applications should assume that
- a PaDevice may be simultaneously used by at most one PaStream.
-
- Pointers to PaStream objects are passed between PortAudio functions that
- operate on streams.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
- Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
- Pa_GetStreamTime, Pa_GetStreamCpuLoad
-
-*}
-type
- PPaStream = Pointer;
-
-{** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
- or Pa_OpenDefaultStream() to indicate that the stream callback will
- accept buffers of any size.
-*}
-const paFramesPerBufferUnspecified = (0);
-
-
-{** Flags used to control the behavior of a stream. They are passed as
- parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
- ORed together.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
- @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
- paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
-*}
-type TPaStreamFlags = culong;
-
-{** @see PaStreamFlags *}
-const paNoFlag = TPaStreamFlags(0);
-
-{** Disable default clipping of out of range samples.
- @see PaStreamFlags
-*}
-const paClipOff = TPaStreamFlags($00000001);
-
-{** Disable default dithering.
- @see PaStreamFlags
-*}
-const paDitherOff = TPaStreamFlags($00000002);
-
-{** Flag requests that where possible a full duplex stream will not discard
- overflowed input samples without calling the stream callback. This flag is
- only valid for full duplex callback streams and only when used in combination
- with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
- this flag incorrectly results in a paInvalidFlag error being returned from
- Pa_OpenStream and Pa_OpenDefaultStream.
-
- @see PaStreamFlags, paFramesPerBufferUnspecified
-*}
-const paNeverDropInput = TPaStreamFlags($00000004);
-
-{** Call the stream callback to fill initial output buffers, rather than the
- default behavior of priming the buffers with zeros (silence). This flag has
- no effect for input-only and blocking read/write streams.
-
- @see PaStreamFlags
-*}
-const paPrimeOutputBuffersUsingStreamCallback = TPaStreamFlags($00000008);
-
-{** A mask specifying the platform specific bits.
- @see PaStreamFlags
-*}
-const paPlatformSpecificFlags = TPaStreamFlags($FFFF0000);
-
-{**
- Timing information for the buffers passed to the stream callback.
-*}
-type
- PPaStreamCallbackTimeInfo = ^TPaStreamCallbackTimeInfo;
- TPaStreamCallbackTimeInfo = record
- inputBufferAdcTime: TPaTime;
- currentTime: TPaTime;
- outputBufferDacTime: TPaTime;
- end;
-
-
-{**
- Flag bit constants for the statusFlags to PaStreamCallback.
-
- @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
- paPrimingOutput
-*}
-type TPaStreamCallbackFlags = culong;
-
-{** In a stream opened with paFramesPerBufferUnspecified, indicates that
- input data is all silence (zeros) because no real data is available. In a
- stream opened without paFramesPerBufferUnspecified, it indicates that one or
- more zero samples have been inserted into the input buffer to compensate
- for an input underflow.
- @see PaStreamCallbackFlags
-*}
-const paInputUnderflow = TPaStreamCallbackFlags($00000001);
-
-{** In a stream opened with paFramesPerBufferUnspecified, indicates that data
- prior to the first sample of the input buffer was discarded due to an
- overflow, possibly because the stream callback is using too much CPU time.
- Otherwise indicates that data prior to one or more samples in the
- input buffer was discarded.
- @see PaStreamCallbackFlags
-*}
-const paInputOverflow = TPaStreamCallbackFlags($00000002);
-
-{** Indicates that output data (or a gap) was inserted, possibly because the
- stream callback is using too much CPU time.
- @see PaStreamCallbackFlags
-*}
-const paOutputUnderflow = TPaStreamCallbackFlags($00000004);
-
-{** Indicates that output data will be discarded because no room is available.
- @see PaStreamCallbackFlags
-*}
-const paOutputOverflow = TPaStreamCallbackFlags($00000008);
-
-{** Some of all of the output data will be used to prime the stream, input
- data may be zero.
- @see PaStreamCallbackFlags
-*}
-const paPrimingOutput = TPaStreamCallbackFlags($00000010);
-
-{**
- Allowable return values for the PaStreamCallback.
- @see PaStreamCallback
-*}
-type TPaStreamCallbackResult = {enum}cint; const
-{enum_begin PaStreamCallbackResult}
- paContinue=0;
- paComplete=1;
- paAbort=2;
-{enum_end PaStreamCallbackResult}
-
-{**
- Functions of type PaStreamCallback are implemented by PortAudio clients.
- They consume, process or generate audio in response to requests from an
- active PortAudio stream.
-
- @param input and @param output are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream().
-
- @param frameCount The number of sample frames to be processed by
- the stream callback.
-
- @param timeInfo The time in seconds when the first sample of the input
- buffer was received at the audio input, the time in seconds when the first
- sample of the output buffer will begin being played at the audio output, and
- the time in seconds when the stream callback was called.
- See also Pa_GetStreamTime()
-
- @param statusFlags Flags indicating whether input and/or output buffers
- have been inserted or will be dropped to overcome underflow or overflow
- conditions.
-
- @param userData The value of a user supplied pointer passed to
- Pa_OpenStream() intended for storing synthesis data etc.
-
- @return
- The stream callback should return one of the values in the
- PaStreamCallbackResult enumeration. To ensure that the callback continues
- to be called, it should return paContinue (0). Either paComplete or paAbort
- can be returned to finish stream processing, after either of these values is
- returned the callback will not be called again. If paAbort is returned the
- stream will finish as soon as possible. If paComplete is returned, the stream
- will continue until all buffers generated by the callback have been played.
- This may be useful in applications such as soundfile players where a specific
- duration of output is required. However, it is not necessary to utilise this
- mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
- be used to stop the stream. The callback must always fill the entire output
- buffer irrespective of its return value.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
-
- @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
- PortAudio API functions from within the stream callback.
-*}
-type
- PPaStreamCallback = ^TPaStreamCallback;
- TPaStreamCallback = function(
- input: Pointer; output: Pointer;
- frameCount: culong;
- timeInfo: PPaStreamCallbackTimeInfo;
- statusFlags: TPaStreamCallbackFlags;
- userData: Pointer ): cint; cdecl;
-
-
-{** Opens a stream for either input, output or both.
-
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
-
- @param inputParameters A structure that describes the input parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- inputParameters must be NULL for output-only streams.
-
- @param outputParameters A structure that describes the output parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- outputParameters must be NULL for input-only streams.
-
- @param sampleRate The desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- @param framesPerBuffer The number of frames passed to the stream callback
- function, or the preferred block granularity for a blocking read/write stream.
- The special value paFramesPerBufferUnspecified (0) may be used to request that
- the stream callback will recieve an optimal (and possibly varying) number of
- frames based on host requirements and the requested latency settings.
- Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
- stream may introduce an additional layer of buffering which could introduce
- additional latency. PortAudio guarantees that the additional latency
- will be kept to the theoretical minimum however, it is strongly recommended
- that a non-zero framesPerBuffer value only be used when your algorithm
- requires a fixed number of frames per stream callback.
-
- @param streamFlags Flags which modify the behaviour of the streaming process.
- This parameter may contain a combination of flags ORed together. Some flags may
- only be relevant to certain buffer formats.
-
- @param streamCallback A pointer to a client supplied function that is responsible
- for processing and filling input and output buffers. If this parameter is NULL
- the stream will be opened in 'blocking read/write' mode. In blocking mode,
- the client can receive sample data using Pa_ReadStream and write sample data
- using Pa_WriteStream, the number of samples that may be read or written
- without blocking is returned by Pa_GetStreamReadAvailable and
- Pa_GetStreamWriteAvailable respectively.
-
- @param userData A client supplied pointer which is passed to the stream callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers. This parameter is ignored if streamCallback
- is NULL.
-
- @return
- Upon success Pa_OpenStream() returns paNoError and places a pointer to a
- valid PaStream in the stream argument. The stream is inactive (stopped).
- If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
- PaError for possible error codes) and the value of stream is invalid.
-
- @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
- Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
-*}
-function Pa_OpenStream( var stream: PPaStream;
- inputParameters: PPaStreamParameters;
- outputParameters: PPaStreamParameters;
- sampleRate: cdouble;
- framesPerBuffer: culong;
- streamFlags: TPaStreamFlags;
- streamCallback: PPaStreamCallback;
- userData: Pointer ): TPaError; cdecl; external LibName;
-
-
-{** A simplified version of Pa_OpenStream() that opens the default input
- and/or output devices.
-
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
-
- @param numInputChannels The number of channels of sound that will be supplied
- to the stream callback or returned by Pa_ReadStream. It can range from 1 to
- the value of maxInputChannels in the PaDeviceInfo record for the default input
- device. If 0 the stream is opened as an output-only stream.
-
- @param numOutputChannels The number of channels of sound to be delivered to the
- stream callback or passed to Pa_WriteStream. It can range from 1 to the value
- of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
- If 0 the stream is opened as an output-only stream.
-
- @param sampleFormat The sample format of both the input and output buffers
- provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
- sampleFormat may be any of the formats described by the PaSampleFormat
- enumeration.
-
- @param sampleRate Same as Pa_OpenStream parameter of the same name.
- @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
- @param streamCallback Same as Pa_OpenStream parameter of the same name.
- @param userData Same as Pa_OpenStream parameter of the same name.
-
- @return As for Pa_OpenStream
-
- @see Pa_OpenStream, PaStreamCallback
-*}
-function Pa_OpenDefaultStream( var stream: PPaStream;
- numInputChannels: cint;
- numOutputChannels: cint;
- sampleFormat: TPaSampleFormat;
- sampleRate: cdouble;
- framesPerBuffer: culong;
- streamCallback: PPaStreamCallback;
- userData: Pointer ): TPaError; cdecl; external LibName;
-
-
-{** Closes an audio stream. If the audio stream is active it
- discards any pending buffers as if Pa_AbortStream() had been called.
-*}
-function Pa_CloseStream( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-{** Functions of type PaStreamFinishedCallback are implemented by PortAudio
- clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
- function. Once registered they are called when the stream becomes inactive
- (ie once a call to Pa_StopStream() will not block).
- A stream will become inactive after the stream callback returns non-zero,
- or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
- output, if the stream callback returns paComplete, or Pa_StopStream is called,
- the stream finished callback will not be called until all generated sample data
- has been played.
-
- @param userData The userData parameter supplied to Pa_OpenStream()
-
- @see Pa_SetStreamFinishedCallback
-*}
-type
- PPaStreamFinishedCallback = ^TPaStreamFinishedCallback;
- TPaStreamFinishedCallback = procedure( userData: Pointer ); cdecl;
-
-
-{** Register a stream finished callback function which will be called when the
- stream becomes inactive. See the description of PaStreamFinishedCallback for
- further details about when the callback will be called.
-
- @param stream a pointer to a PaStream that is in the stopped state - if the
- stream is not stopped, the stream's finished callback will remain unchanged
- and an error code will be returned.
-
- @param streamFinishedCallback a pointer to a function with the same signature
- as PaStreamFinishedCallback, that will be called when the stream becomes
- inactive. Passing NULL for this parameter will un-register a previously
- registered stream finished callback function.
-
- @return on success returns paNoError, otherwise an error code indicating the cause
- of the error.
-
- @see PaStreamFinishedCallback
-*}
-function Pa_SetStreamFinishedCallback( stream: PPaStream;
- streamFinishedCallback: PPaStreamFinishedCallback ): TPaError; cdecl; external LibName;
-
-
-{** Commences audio processing.
-*}
-function Pa_StartStream( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-{** Terminates audio processing. It waits until all pending
- audio buffers have been played before it returns.
-*}
-function Pa_StopStream( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-{** Terminates audio processing immediately without waiting for pending
- buffers to complete.
-*}
-function Pa_AbortStream( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-{** Determine whether the stream is stopped.
- A stream is considered to be stopped prior to a successful call to
- Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
- If a stream callback returns a value other than paContinue the stream is NOT
- considered to be stopped.
-
- @return Returns one (1) when the stream is stopped, zero (0) when
- the stream is running or, a PaErrorCode (which are always negative) if
- PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
-*}
-function Pa_IsStreamStopped( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-{** Determine whether the stream is active.
- A stream is active after a successful call to Pa_StartStream(), until it
- becomes inactive either as a result of a call to Pa_StopStream() or
- Pa_AbortStream(), or as a result of a return value other than paContinue from
- the stream callback. In the latter case, the stream is considered inactive
- after the last buffer has finished playing.
-
- @return Returns one (1) when the stream is active (ie playing or recording
- audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
- if PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
-*}
-function Pa_IsStreamActive( stream: PPaStream ): TPaError; cdecl; external LibName;
-
-
-
-{** A structure containing unchanging information about an open stream.
- @see Pa_GetStreamInfo
-*}
-type
- PPaStreamInfo = ^TPaStreamInfo;
- TPaStreamInfo = record
- {** this is struct version 1 *}
- structVersion: cint;
-
- {** The input latency of the stream in seconds. This value provides the most
- accurate estimate of input latency available to the implementation. It may
- differ significantly from the suggestedLatency value passed to Pa_OpenStream().
- The value of this field will be zero (0.) for output-only streams.
- @see PaTime
- *}
- inputLatency: TPaTime;
-
- {** The output latency of the stream in seconds. This value provides the most
- accurate estimate of output latency available to the implementation. It may
- differ significantly from the suggestedLatency value passed to Pa_OpenStream().
- The value of this field will be zero (0.) for input-only streams.
- @see PaTime
- *}
- outputLatency: TPaTime;
-
- {** The sample rate of the stream in Hertz (samples per second). In cases
- where the hardware sample rate is inaccurate and PortAudio is aware of it,
- the value of this field may be different from the sampleRate parameter
- passed to Pa_OpenStream(). If information about the actual hardware sample
- rate is not available, this field will have the same value as the sampleRate
- parameter passed to Pa_OpenStream().
- *}
- sampleRate: cdouble;
- end;
-
-
-{** Retrieve a pointer to a PaStreamInfo structure containing information
- about the specified stream.
- @return A pointer to an immutable PaStreamInfo structure. If the stream
- parameter invalid, or an error is encountered, the function returns NULL.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @note PortAudio manages the memory referenced by the returned pointer,
- the client must not manipulate or free the memory. The pointer is only
- guaranteed to be valid until the specified stream is closed.
-
- @see PaStreamInfo
-*}
-function Pa_GetStreamInfo( stream: PPaStream ): PPaStreamInfo; cdecl; external LibName;
-
-
-{** Determine the current time for the stream according to the same clock used
- to generate buffer timestamps. This time may be used for syncronising other
- events to the audio stream, for example synchronizing audio to MIDI.
-
- @return The stream's current time in seconds, or 0 if an error occurred.
-
- @see PaTime, PaStreamCallback
-*}
-function Pa_GetStreamTime( stream: PPaStream ): TPaTime; cdecl; external LibName;
-
-
-{** Retrieve CPU usage information for the specified stream.
- The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
- audio processing routines including, but not limited to the client supplied
- stream callback. This function does not work with blocking read/write streams.
-
- This function may be called from the stream callback function or the
- application.
-
- @return
- A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
- that the stream callback is consuming the maximum number of CPU cycles possible
- to maintain real-time operation. A value of 0.5 would imply that PortAudio and
- the stream callback was consuming roughly 50% of the available CPU time. The
- return value may exceed 1.0. A value of 0.0 will always be returned for a
- blocking read/write stream, or if an error occurrs.
-*}
-function Pa_GetStreamCpuLoad( stream: PPaStream ): cdouble; cdecl; external LibName;
-
-
-{** Read samples from an input stream. The function doesn't return until
- the entire buffer has been filled - this may involve waiting for the operating
- system to supply the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the inputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- inputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be read into buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or PaInputOverflowed if input
- data was discarded by PortAudio after the previous call and before this call.
-*}
-function Pa_ReadStream( stream: PPaStream;
- buffer: Pointer;
- frames: culong ): TPaError; cdecl; external LibName;
-
-
-{** Write samples to an output stream. This function doesn't return until the
- entire buffer has been consumed - this may involve waiting for the operating
- system to consume the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the outputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- outputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be written from buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or paOutputUnderflowed if
- additional output data was inserted after the previous call and before this
- call.
-*}
-function Pa_WriteStream( stream: PPaStream;
- buffer: Pointer;
- frames: culong ): TPaError; cdecl; external LibName;
-
-
-{** Retrieve the number of frames that can be read from the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be read from the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*}
-function Pa_GetStreamReadAvailable( stream: PPaStream ): cslong; cdecl; external LibName;
-
-
-{** Retrieve the number of frames that can be written to the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be written to the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*}
-function Pa_GetStreamWriteAvailable( stream: PPaStream ): cslong; cdecl; external LibName;
-
-
-{** Retrieve the host type handling an open stream.
-
- @return Returns a non-negative value representing the host API type
- handling an open stream or, a PaErrorCode (which are always negative)
- if PortAudio is not initialized or an error is encountered.
-*}
-function Pa_GetStreamHostApiType( stream: PPaStream ): TPaHostApiTypeId; cdecl; external LibName;
-
-
-{* Miscellaneous utilities *}
-
-
-{** Retrieve the size of a given sample format in bytes.
-
- @return The size in bytes of a single sample in the specified format,
- or paSampleFormatNotSupported if the format is not supported.
-*}
-function Pa_GetSampleSize( format: TPaSampleFormat ): TPaError; cdecl; external LibName;
-
-
-{** Put the caller to sleep for at least 'msec' milliseconds. This function is
- provided only as a convenience for authors of portable code (such as the tests
- and examples in the PortAudio distribution.)
-
- The function may sleep longer than requested so don't rely on this for accurate
- musical timing.
-*}
-procedure Pa_Sleep( msec: clong ); cdecl; external LibName;
-
-implementation
-
-end.
diff --git a/Game/Code/lib/portmixer/delphi/portmixer.pas b/Game/Code/lib/portmixer/delphi/portmixer.pas
deleted file mode 100644
index d657cf85..00000000
--- a/Game/Code/lib/portmixer/delphi/portmixer.pas
+++ /dev/null
@@ -1,151 +0,0 @@
-{*
- * PortMixer
- * PortMixer API Header File
- *
- * Copyright (c) 2002, 2006
- *
- * Written by Dominic Mazzoni
- * and Leland Lucius
- *
- * PortMixer is intended to work side-by-side with PortAudio,
- * the Portable Real-Time Audio Library by Ross Bencina and
- * Phil Burk.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *}
-unit portmixer;
-
-{$IFDEF FPC}
- {$PACKRECORDS C} (* GCC/Visual C/C++ compatible record packing *)
- {$MODE DELPHI }
-{$ENDIF}
-
-interface
-
-uses
- ctypes,
- portaudio;
-
-const
-{$IFDEF MSWINDOWS}
- LibName = 'portmixer.dll';
-{$ENDIF}
-{$IFDEF LINUX}
- LibName = 'libportmixer.so';
-{$ENDIF}
-{$IFDEF DARWIN}
-// LibName = 'libportmixer.dylib';
-// {$LINKLIB libportaudio}
-{$ENDIF}
-
-type
- PPxMixer = Pointer;
- TPxVolume = cfloat; {* 0.0 (min) --> 1.0 (max) *}
- TPxBalance = cfloat; {* -1.0 (left) --> 1.0 (right) *}
-
-{*
- Px_OpenMixer() returns a mixer which will work with the given PortAudio
- audio device. Pass 0 as the index for the first (default) mixer.
-*}
-
-function Px_OpenMixer( pa_stream: Pointer; i: cint ): PPxMixer; cdecl; external LibName;
-
-{*
- Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
- memory associated with it.
-*}
-
-procedure Px_CloseMixer( mixer: PPxMixer ); cdecl; external LibName;
-
-{*
- Px_GetNumMixers returns the number of mixers which could be
- used with the given PortAudio device. On most systems, there
- will be only one mixer for each device; however there may be
- multiple mixers for each device, or possibly multiple mixers
- which are independent of any particular PortAudio device.
-*}
-
-function Px_GetNumMixers( mixer: PPxMixer ): cint; cdecl; external LibName;
-function Px_GetMixerName( mixer: PPxMixer; i: cint ): PChar; cdecl; external LibName;
-
-{*
- Master (output) volume
-*}
-
-function Px_GetMasterVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
-procedure Px_SetMasterVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
-
-{*
- Main output volume
-*}
-
-function Px_GetPCMOutputVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
-procedure Px_SetPCMOutputVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
-function Px_SupportsPCMOutputVolume( mixer: PPxMixer ): cint; cdecl; external LibName;
-
-{*
- All output volumes
-*}
-
-function Px_GetNumOutputVolumes( mixer: PPxMixer ): cint; cdecl; external LibName;
-function Px_GetOutputVolumeName( mixer: PPxMixer; i: cint ): PChar; cdecl; external LibName;
-function Px_GetOutputVolume( mixer: PPxMixer; i: cint ): TPxVolume; cdecl; external LibName;
-procedure Px_SetOutputVolume( mixer: PPxMixer; i: cint; volume: TPxVolume ); cdecl; external LibName;
-
-{*
- Input source
-*}
-
-function Px_GetNumInputSources( mixer: PPxMixer ): cint; cdecl; external LibName;
-function Px_GetInputSourceName( mixer: PPxMixer; i: cint): PChar; cdecl; external LibName;
-function Px_GetCurrentInputSource( mixer: PPxMixer ): cint; cdecl; external LibName; {* may return -1 == none *}
-procedure Px_SetCurrentInputSource( mixer: PPxMixer; i: cint ); cdecl; external LibName;
-
-{*
- Input volume
-*}
-
-function Px_GetInputVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
-procedure Px_SetInputVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
-
-{*
- Balance
-*}
-
-function Px_SupportsOutputBalance( mixer: PPxMixer ): cint; cdecl; external LibName;
-function Px_GetOutputBalance( mixer: PPxMixer ): TPxBalance; cdecl; external LibName;
-procedure Px_SetOutputBalance( mixer: PPxMixer; balance: TPxBalance ); cdecl; external LibName;
-
-{*
- Playthrough
-*}
-
-function Px_SupportsPlaythrough( mixer: PPxMixer ): cint; cdecl; external LibName;
-function Px_GetPlaythrough( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
-procedure Px_SetPlaythrough( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
-
-implementation
-
-end.
diff --git a/Game/Code/lib/projectM/cwrapper/Makefile.in b/Game/Code/lib/projectM/cwrapper/Makefile.in
deleted file mode 100644
index d2be8613..00000000
--- a/Game/Code/lib/projectM/cwrapper/Makefile.in
+++ /dev/null
@@ -1,30 +0,0 @@
-OBJECTS = projectM-cwrapper.o
-LIBRARY = libprojectM-cwrapper.a
-
-CXX = @CXX@
-CXXFLAGS += @CXXFLAGS@
-INCLUDES = -I@libprojectM_INCLUDEDIR@/libprojectM
-DEFINES = -DPROJECTM_VERSION_INT=@libprojectM_VERSION_INT@
-RANLIB = @RANLIB@
-
-.PHONY: all clean distclean strip
-
-all : $(LIBRARY)
-
-$(LIBRARY): $(OBJECTS)
- ar ruv $(LIBRARY) $(OBJECTS)
- $(RANLIB) $(LIBRARY)
-
-%.o : %.cpp
- $(CXX) $(CXXFLAGS) $(DEFINES) $(INCLUDES) -c $(<) -o $@
-
-clean :
- rm -f $(LIBRARY)
- rm -f $(OBJECTS)
-
-distclean: clean
- rm -rf Makefile
-
-strip :
- strip $(LIBRARY)
- $(RANLIB) $(LIBRARY)
diff --git a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.cpp b/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.cpp
deleted file mode 100644
index ebf43554..00000000
--- a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "projectM-cwrapper.h"
-
-#define PM_CLASS(pm) ((projectM*)pm)
-
-#if (PROJECTM_VERSION_INT > 1000000)
-#define PM_PCM(pm) (PM_CLASS(pm)->pcm())
-#else
-#define PM_PCM(pm) (PM_CLASS(pm)->pcm)
-#endif
-
-projectM_ptr projectM_create1(char* config_file)
-{
- return projectM_ptr(new projectM(config_file));
-}
-
-#if (PROJECTM_VERSION_INT < 1000000)
-projectM_ptr projectM_create2(int gx, int gy, int fps, int texsize,
- int width, int height, char* preset_url,
- char* title_fonturl, char* title_menuurl)
-{
- return projectM_ptr(new projectM(gx, gy, fps, texsize, width, height,
- preset_url, title_fonturl, title_menuurl));}
-#endif
-
-void projectM_resetGL(projectM_ptr pm, int width, int height)
-{
- PM_CLASS(pm)->projectM_resetGL(width, height);
-}
-
-void projectM_setTitle(projectM_ptr pm, char* title)
-{
- PM_CLASS(pm)->projectM_setTitle(title);
-}
-
-void projectM_renderFrame(projectM_ptr pm)
-{
- PM_CLASS(pm)->renderFrame();
-}
-
-unsigned projectM_initRenderToTexture(projectM_ptr pm)
-{
- return PM_CLASS(pm)->initRenderToTexture();
-}
-
-void projectM_key_handler(projectM_ptr pm, projectMEvent event,
- projectMKeycode keycode, projectMModifier modifier)
-{
- PM_CLASS(pm)->key_handler(event, keycode, modifier);
-}
-
-void projectM_free(projectM_ptr pm)
-{
- delete PM_CLASS(pm);
-}
-
-void PCM_addPCMfloat(projectM_ptr pm, float *PCMdata, int samples)
-{
- PM_PCM(pm)->addPCMfloat(PCMdata, samples);
-}
-
-void PCM_addPCM16(projectM_ptr pm, short pcm_data[2][512])
-{
- PM_PCM(pm)->addPCM16(pcm_data);
-}
-
-void PCM_addPCM16Data(projectM_ptr pm, const short* pcm_data, short samples)
-{
- PM_PCM(pm)->addPCM16Data(pcm_data, samples);
-}
-
-void PCM_addPCM8(projectM_ptr pm, unsigned char pcm_data[2][1024])
-{
- PM_PCM(pm)->addPCM8(pcm_data);
-}
-
-void PCM_addPCM8_512(projectM_ptr pm, const unsigned char pcm_data[2][512])
-{
- PM_PCM(pm)->addPCM8_512(pcm_data);
-}
-
-#define COPY_FIELD(c_ptr, s, fld) (c_ptr->fld = s.fld)
-
-#if (PROJECTM_VERSION_INT > 1000000)
-void projectM_settings(projectM_ptr pm, Settings* settings)
-{
- const projectM::Settings& pmSettings = PM_CLASS(pm)->settings();
-
- COPY_FIELD(settings, pmSettings, meshX);
- COPY_FIELD(settings, pmSettings, meshY);
- COPY_FIELD(settings, pmSettings, fps);
- COPY_FIELD(settings, pmSettings, textureSize);
- COPY_FIELD(settings, pmSettings, windowWidth);
- COPY_FIELD(settings, pmSettings, windowHeight);
- settings->presetURL = pmSettings.presetURL.c_str();
- settings->titleFontURL = pmSettings.titleFontURL.c_str();
- settings->menuFontURL = pmSettings.menuFontURL.c_str();
- COPY_FIELD(settings, pmSettings, smoothPresetDuration);
- COPY_FIELD(settings, pmSettings, presetDuration);
- COPY_FIELD(settings, pmSettings, beatSensitivity);
- COPY_FIELD(settings, pmSettings, aspectCorrection);
- COPY_FIELD(settings, pmSettings, easterEgg);
- COPY_FIELD(settings, pmSettings, shuffleEnabled);
-}
-#endif
diff --git a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.h b/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.h
deleted file mode 100644
index 43f36ef4..00000000
--- a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef __PROJECTM_CWRAPPER_H__
-#define __PROJECTM_CWRAPPER_H__
-
-#include "projectM.hpp"
-
-// PROJECTM_VERSION define is not very helpful, lets create our own
-#define PROJECTM_VERSION_1_00_00 1000000 // 1.00.00 = 1.0 or 1.01 (same version number for 1.0 and 1.01)
-#define PROJECTM_VERSION_1_10_00 1010000 // 1.10.00 = 1.1 (bigger than 1.2 due to strange versioning)
-#define PROJECTM_VERSION_1_02_00 1002000 // 1.02.00 = 1.2
-
-// version of projectM to wrap (see PROJECTM_VERSION)
-#ifndef PROJECTM_VERSION_INT
-#define PROJECTM_VERSION_INT PROJECTM_VERSION_1_02_00
-#endif
-
-extern "C" {
-
- #if (PROJECTM_VERSION_INT > 1000000)
- struct Settings {
- int meshX;
- int meshY;
- int fps;
- int textureSize;
- int windowWidth;
- int windowHeight;
- const char* presetURL;
- const char* titleFontURL;
- const char* menuFontURL;
- int smoothPresetDuration;
- int presetDuration;
- float beatSensitivity;
- char aspectCorrection;
- float easterEgg;
- char shuffleEnabled;
- };
- #endif
-
- typedef void* projectM_ptr;
-
- DLLEXPORT projectM_ptr projectM_create1(char* config_file);
- #if (PROJECTM_VERSION_INT < 1000000)
- DLLEXPORT projectM_ptr projectM_create2(int gx, int gy, int fps, int texsize,
- int width, int height, char* preset_url,
- char* title_fonturl, char* title_menuurl);
- #endif
-
- DLLEXPORT void projectM_resetGL(projectM_ptr pm, int width, int height);
- DLLEXPORT void projectM_setTitle(projectM_ptr pm, char* title);
- DLLEXPORT void projectM_renderFrame(projectM_ptr pm);
- DLLEXPORT unsigned projectM_initRenderToTexture(projectM_ptr pm);
- DLLEXPORT void projectM_key_handler(projectM_ptr pm, projectMEvent event,
- projectMKeycode keycode, projectMModifier modifier);
-
- DLLEXPORT void projectM_free(projectM_ptr pm);
-
- DLLEXPORT void PCM_addPCMfloat(projectM_ptr pm, float *PCMdata, int samples);
- DLLEXPORT void PCM_addPCM16(projectM_ptr pm, short [2][512]);
- DLLEXPORT void PCM_addPCM16Data(projectM_ptr pm, const short* pcm_data, short samples);
- DLLEXPORT void PCM_addPCM8(projectM_ptr pm, unsigned char [2][1024]);
- DLLEXPORT void PCM_addPCM8_512(projectM_ptr pm, const unsigned char [2][512]);
-
- #if (PROJECTM_VERSION_INT > 1000000)
- DLLEXPORT void projectM_settings(projectM_ptr pm, Settings* settings);
- #endif
-}
-
-#endif
diff --git a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.sln b/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.sln
deleted file mode 100644
index e05f79a3..00000000
--- a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "projectM-cwrapper", "projectM-cwrapper.vcproj", "{8E653284-12F3-4A90-9D0D-4195557051F7}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {8E653284-12F3-4A90-9D0D-4195557051F7}.Debug|Win32.ActiveCfg = Debug|Win32
- {8E653284-12F3-4A90-9D0D-4195557051F7}.Debug|Win32.Build.0 = Debug|Win32
- {8E653284-12F3-4A90-9D0D-4195557051F7}.Release|Win32.ActiveCfg = Release|Win32
- {8E653284-12F3-4A90-9D0D-4195557051F7}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.vcproj b/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.vcproj
deleted file mode 100644
index c0902099..00000000
--- a/Game/Code/lib/projectM/cwrapper/projectM-cwrapper.vcproj
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Game/Code/lib/projectM/projectM-0_9.inc b/Game/Code/lib/projectM/projectM-0_9.inc
deleted file mode 100644
index a3908c77..00000000
--- a/Game/Code/lib/projectM/projectM-0_9.inc
+++ /dev/null
@@ -1,427 +0,0 @@
-{$IFDEF Unix}
-uses
- baseunix;
-{$ENDIF}
-
-const
-{$IFDEF MSWINDOWS}
- libprojectM = 'libprojectM.dll';
-{$ELSE}
- libprojectM = 'libprojectM.so';
-{$ENDIF}
-
-{**************** INTERNAL SECTION ****************}
-
-
-type
- PPCfloat = ^PCfloat;
-
-type
- _TContextType = cint;
-const
- AGL_CONTEXT = 0;
- CGL_CONTEXT = 1;
- NSGL_CONTEXT = 2;
- GLX_CONTEXT = 3;
- WGL_CONTEXT = 4;
-
-type
- _PRenderTarget = ^_TRenderTarget;
- _TRenderTarget = record
- { Texture size }
- texsize: cint;
-
- { Application context }
- origContextType: _TContextType;
-
- usePbuffers: cint;
-
- {$ifdef LINUX}
- lock_func: procedure(); cdecl;
- unlock_func: procedure(); cdecl;
- {$endif}
-
- { Opaque pbuffer context and pbuffer }
- {$ifdef DARWIN}
- origContext: Pointer;
- pbufferContext: Pointer;
- pbuffer: Pointer;
- {$endif}
-
- { Render target texture ID for non-pbuffer systems }
- textureID: array[0..2] of GLuint;
- end;
-
- _PProjectM = ^_TProjectM;
- _TProjectM = record
- presetURL: PChar;
- presetName: PChar;
- fontURL: PChar;
-
- hasInit: cint;
-
- noSwitch: cint;
- pcmframes: cint;
- freqframes: cint;
- totalframes: cint;
-
- showfps: cint;
- showtitle: cint;
- showpreset: cint;
- showhelp: cint;
- showstats: cint;
-
- studio: cint;
-
- fbuffer: PGLubyte;
-
- {$IFNDEF MSWINDOWS}
- { The first ticks value of the application }
- startTime: timeval;
- {$ELSE}
- startTime: clong;
- {$ENDIF}
- Time: cfloat;
-
- { Render target texture ID }
- renderTarget: _PRenderTarget;
-
- disp: array[0..79] of Char;
-
- wave_o: cfloat;
-
- //int texsize=1024; //size of texture to do actual graphics
- fvw: cint; //fullscreen dimensions
- fvh: cint;
- wvw: cint; //windowed dimensions
- wvh: cint;
- vw: cint; //runtime dimensions
- vh: cint;
- fullscreen: cint;
-
- maxsamples: cint; //size of PCM buffer
- numsamples: cint; //size of new PCM info
- pcmdataL: PCfloat; //holder for most recent pcm data
- pcmdataR: PCfloat; //holder for most recent pcm data
-
- avgtime: cint; //# frames per preset
-
- title: PChar;
- drawtitle: cint;
-
- correction: cint;
-
- vol: cfloat;
-
- //per pixel equation variables
- gridx: PPCfloat; //grid containing interpolated mesh
- gridy: PPCfloat;
- origtheta: PPCfloat; //grid containing interpolated mesh reference values
- origrad: PPCfloat;
- origx: PPCfloat; //original mesh
- origy: PPCfloat;
- origx2: PPCfloat; //original mesh
- origy2: PPCfloat;
-
- { Timing information }
- mspf: cint;
- timed: cint;
- timestart: cint;
- nohard: cint;
- count: cint;
- realfps,
- fpsstart: cfloat;
-
- { PCM data }
- vdataL: array[0..511] of cfloat; //holders for FFT data (spectrum)
- vdataR: array[0..511] of cfloat;
-
- { Various toggles }
- doPerPixelEffects: cint;
- doIterative: cint;
-
- { ENGINE VARIABLES }
- { From engine_vars.h }
- preset_name: array[0..255] of Char;
-
- { PER FRAME CONSTANTS BEGIN }
- zoom: cfloat;
- zoomexp: cfloat;
- rot: cfloat;
- warp: cfloat;
-
- sx: cfloat;
- sy: cfloat;
- dx: cfloat;
- dy: cfloat;
- cx: cfloat;
- cy: cfloat;
-
- gy: cint;
- gx: cint;
-
- decay: cfloat;
-
- wave_r: cfloat;
- wave_g: cfloat;
- wave_b: cfloat;
- wave_x: cfloat;
- wave_y: cfloat;
- wave_mystery: cfloat;
-
- ob_size: cfloat;
- ob_r: cfloat;
- ob_g: cfloat;
- ob_b: cfloat;
- ob_a: cfloat;
-
- ib_size: cfloat;
- ib_r: cfloat;
- ib_g: cfloat;
- ib_b: cfloat;
- ib_a: cfloat;
-
- meshx: cint;
- meshy: cint;
-
- mv_a: cfloat;
- mv_r: cfloat;
- mv_g: cfloat;
- mv_b: cfloat;
- mv_l: cfloat;
- mv_x: cfloat;
- mv_y: cfloat;
- mv_dy: cfloat;
- mv_dx: cfloat;
-
- treb: cfloat;
- mid: cfloat;
- bass: cfloat;
- bass_old: cfloat;
- beat_sensitivity: cfloat;
- treb_att: cfloat;
- mid_att: cfloat;
- bass_att: cfloat;
- progress: cfloat;
- frame: cint;
-
- { PER_FRAME CONSTANTS END }
-
- { PER_PIXEL CONSTANTS BEGIN }
-
- x_per_pixel: cfloat;
- y_per_pixel: cfloat;
- rad_per_pixel: cfloat;
- ang_per_pixel: cfloat;
-
- { PER_PIXEL CONSTANT END }
-
-
- fRating: cfloat;
- fGammaAdj: cfloat;
- fVideoEchoZoom: cfloat;
- fVideoEchoAlpha: cfloat;
-
- nVideoEchoOrientation: cint;
- nWaveMode: cint;
- bAdditiveWaves: cint;
- bWaveDots: cint;
- bWaveThick: cint;
- bModWaveAlphaByVolume: cint;
- bMaximizeWaveColor: cint;
- bTexWrap: cint;
- bDarkenCenter: cint;
- bRedBlueStereo: cint;
- bBrighten: cint;
- bDarken: cint;
- bSolarize: cint;
- bInvert: cint;
- bMotionVectorsOn: cint;
- fps: cint;
-
- fWaveAlpha: cfloat;
- fWaveScale: cfloat;
- fWaveSmoothing: cfloat;
- fWaveParam: cfloat;
- fModWaveAlphaStart: cfloat;
- fModWaveAlphaEnd: cfloat;
- fWarpAnimSpeed: cfloat;
- fWarpScale: cfloat;
- fShader: cfloat;
-
-
- { Q VARIABLES START }
-
- q1: cfloat;
- q2: cfloat;
- q3: cfloat;
- q4: cfloat;
- q5: cfloat;
- q6: cfloat;
- q7: cfloat;
- q8: cfloat;
-
-
- { Q VARIABLES END }
-
- zoom_mesh: PPCfloat;
- zoomexp_mesh: PPCfloat;
- rot_mesh: PPCfloat;
-
- sx_mesh: PPCfloat;
- sy_mesh: PPCfloat;
- dx_mesh: PPCfloat;
- dy_mesh: PPCfloat;
- cx_mesh: PPCfloat;
- cy_mesh: PPCfloat;
-
- x_mesh: PPCfloat;
- y_mesh: PPCfloat;
- rad_mesh: PPCfloat;
- theta_mesh: PPCfloat;
- end;
-
- PProjectMState = ^TProjectMState;
- TProjectMState = record
- fontURLStr: string;
- presetURLStr: string;
- titleStr: string;
- pm: _TProjectM;
- end;
-
-{ projectM.h declarations }
-procedure _projectM_init(pm: _PProjectM); cdecl; external libprojectM name 'projectM_init';
-procedure _projectM_reset(pm: _PProjectM); cdecl; external libprojectM name 'projectM_reset';
-procedure _projectM_resetGL(pm: _PProjectM; width: cint; height: cint); cdecl; external libprojectM name 'projectM_resetGL';
-procedure _projectM_setTitle(pm: _PProjectM; title: PChar); cdecl; external libprojectM name 'projectM_setTitle';
-procedure _renderFrame(pm: _PProjectM); cdecl; external libprojectM name 'renderFrame';
-
-{ PCM.h declarations }
-procedure _addPCMfloat(pcm_data: PCfloat; samples: cint); cdecl; external libprojectM name 'addPCMfloat';
-procedure _addPCM16(pcm_data: PPCM16); cdecl; external libprojectM name 'addPCM16';
-procedure _addPCM16Data(pcm_data: PCshort; samples: cshort); cdecl; external libprojectM name 'addPCM16Data';
-procedure _addPCM8_512(pcm_data: PPCM8_512); cdecl; external libprojectM name 'addPCM8';
-
-{ console_interface.h declarations }
-procedure _key_handler(pm: _PProjectM;
- event: TProjectMEvent;
- keycode: TProjectMKeycode;
- modifier: TProjectMModifier); cdecl; external libprojectM name 'key_handler';
-
-
-
-
-{**************** EXTERNAL SECTION ****************}
-
-
-constructor TProjectM.Create(gx, gy: cint; fps: integer;
- texsize: integer; width, height: integer;
- const presetsDir, fontsDir: string;
- const titleFont, menuFont: string);
-var
- state: PProjectMState;
-begin
- inherited Create();
-
- New(state);
- data := state;
-
- with state^ do
- begin
- // copy strings (Note: do not use e.g. PChar(presetsDir) directly, it might
- // be a pointer to local stack data that is invalid after the calling function returns)
- fontURLStr := fontsDir;
- presetURLStr := presetsDir;
-
- _projectM_reset(@pm);
-
- pm.fullscreen := 0;
- pm.renderTarget^.texsize := texsize;
- pm.gx := gx;
- pm.gy := gy;
- pm.fps := fps;
- pm.renderTarget^.usePbuffers := 0;
- pm.fontURL := PChar(fontURLStr);
- pm.presetURL := PChar(presetURLStr);
-
- _projectM_init(@pm);
- end;
-end;
-
-procedure TProjectM.ResetGL(width, height: integer);
-begin
- _projectM_resetGL(@PProjectMState(data).pm, width, height);
-end;
-
-procedure TProjectM.SetTitle(const title: string);
-var
- state: PProjectMState;
-begin
- state := PProjectMState(data);
- with state^ do
- begin
- titleStr := title;
- pm.title := PChar(titleStr);
- pm.showtitle := 1;
- end;
-end;
-
-procedure TProjectM.RenderFrame();
-begin
- _renderFrame(@PProjectMState(data).pm);
-end;
-
-procedure TProjectM.AddPCMfloat(pcmData: PSingle; samples: integer);
-begin
- _addPCMfloat(PCfloat(pcmData), samples);
-end;
-
-procedure TProjectM.AddPCM16(pcmData: PPCM16);
-begin
- _addPCM16(pcmData);
-end;
-
-procedure TProjectM.AddPCM16Data(pcmData: PSmallint; samples: Smallint);
-begin
- _addPCM16Data(PCshort(pcmData), samples);
-end;
-
-procedure TProjectM.AddPCM8_512(pcmData: PPCM8_512);
-begin
- _addPCM8_512(pcmData);
-end;
-
-procedure TProjectM.KeyHandler(event: TProjectMEvent;
- keycode: TProjectMKeycode;
- modifier: TProjectMModifier);
-begin
- _key_handler(@PProjectMState(data).pm, event, keycode, modifier);
-end;
-
-procedure TProjectM.RandomPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_r_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.PreviousPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_p_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.NextPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_n_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.ToggleShowPresetNames();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_F3, PROJECTM_KMOD_LSHIFT);
-end;
-
-destructor TProjectM.Destroy();
-begin
- Dispose(PProjectMState(data));
- data := nil;
- inherited;
-end;
-
diff --git a/Game/Code/lib/projectM/projectM-1_0.inc b/Game/Code/lib/projectM/projectM-1_0.inc
deleted file mode 100644
index 8e84894d..00000000
--- a/Game/Code/lib/projectM/projectM-1_0.inc
+++ /dev/null
@@ -1,188 +0,0 @@
-//uses
-
-(**
- * Note: be careful with ProjectM's versioning scheme.
- *
- * Version | Version in pkg-config .pc file
- * ---------+--------------------------------------------
- * 1.00 | 1.00
- * 1.01 | 1.00
- * 1.1 | 1.10
- * 1.2 | 1.2 (= 1.02)
- *
- * So the version number of 1.1 is bigger than that of 1.2.
- *)
-
-const
-{$IFDEF MSWINDOWS}
- // Note: static linking is not possible with delphi because it does neither
- // accept gcc nor MSVC object files (only Intel-style ones).
- libprojectM_cwrapper = 'projectM-cwrapper.dll';
-{$ELSE}
- // static libs are not supported in the "external"-clause
- libprojectM_cwrapper = '';
- // statically link the cwrapper and dynamically link projectM
- {$L 'cwrapper/libprojectM-cwrapper.a'}
- {$LINKLIB projectM}
-{$ENDIF}
-
-{**************** INTERNAL SECTION ****************}
-
-
-type
- _PProjectM = Pointer;
-
-{ projectM.hpp declarations }
-function _projectM_create1(config_file: PChar): _PProjectM; cdecl; external libprojectM_cwrapper name 'projectM_create1';
-{$IF PROJECTM_VERSION < 1000000} // 0.9x
-function _projectM_create2(gx: cint; gy: cint; fps: cint;
- texsize: cint; width: cint; height: cint;
- preset_url: PChar; title_fonturl: PChar; title_menuurl: PChar): _PProjectM; cdecl; external libprojectM_cwrapper name 'projectM_create2';
-{$IFEND}
-
-procedure _projectM_resetGL(pm: _PProjectM; width: cint; height: cint); cdecl; external libprojectM_cwrapper name 'projectM_resetGL';
-procedure _projectM_setTitle(pm: _PProjectM; title: PChar); cdecl; external libprojectM_cwrapper name 'projectM_setTitle';
-procedure _projectM_renderFrame(pm: _PProjectM); cdecl; external libprojectM_cwrapper name 'projectM_renderFrame';
-function _projectM_initRenderToTexture(pm: _PProjectM): cuint; cdecl; external libprojectM_cwrapper name 'projectM_initRenderToTexture';
-
-procedure _projectM_free(pm: _PProjectM); cdecl; external libprojectM_cwrapper name 'projectM_free';
-
-procedure _projectM_key_handler(pm: _PProjectM; event: TProjectMEvent;
- keycode: TProjectMKeycode; modifier: TProjectMModifier); cdecl; external libprojectM_cwrapper name 'projectM_key_handler';
-
-{$IF PROJECTM_VERSION > 1000000} // > 1.01
-procedure _projectM_settings(pm: _PProjectM; settings: PSettings); cdecl; external libprojectM_cwrapper name 'projectM_settings';
-{$IFEND}
-
-{ PCM.hpp declarations }
-procedure _PCM_addPCMfloat(pm: _PProjectM; pcm_data: PSingle; samples: cint); cdecl; external libprojectM_cwrapper name 'PCM_addPCMfloat';
-procedure _PCM_addPCM16(pm: _PProjectM; pcm_data: PPCM16); cdecl; external libprojectM_cwrapper name 'PCM_addPCM16';
-procedure _PCM_addPCM16Data(pm: _PProjectM; pcm_data: PCshort; samples: cshort); cdecl; external libprojectM_cwrapper name 'PCM_addPCM16Data';
-procedure _PCM_addPCM8_512(pm: _PProjectM; pcm_data: PPCM8_512); cdecl; external libprojectM_cwrapper name 'PCM_addPCM8_512';
-procedure _PCM_addPCM8_1024(pm: _PProjectM; pcm_data: PPCM8_1024); cdecl; external libprojectM_cwrapper name 'PCM_addPCM8';
-
-
-{**************** EXTERNAL SECTION ****************}
-
-// This constructor is present in projectM 1.0(1) but does not work with
-// linux because of a bug.
-(*
-constructor TProjectM.Create(gx, gy: integer; fps: integer;
- texsize: integer; width, height: integer;
- const presetsDir, fontsDir: string;
- const titleFont, menuFont: string);
-begin
- data := _projectM_create2(gx, gy, fps, texsize, width, height,
- PChar(presetsDir),
- PChar(fontsDir + PathDelim + titleFont),
- PChar(fontsDir + PathDelim + menuFont));
-end;
-*)
-
-constructor TProjectM.Create(const configFile: string);
-begin
- inherited Create();
-
- // we cannot catch C++ exceptions in delphi, so we have to check
- // if configFile is valid first
- if (not FileExists(configFile)) then
- raise Exception.Create('Invalid file: ' + configFile);
-
- data := _projectM_create1(PChar(configFile));
- if (data = nil) then
- raise Exception.Create('Creation of projectM object failed');
-end;
-
-procedure TProjectM.ResetGL(width, height: Integer);
-begin
- _projectM_resetGL(data, width, height);
-end;
-
-procedure TProjectM.SetTitle(const title: string);
-begin
- _projectM_setTitle(data, PChar(title));
-end;
-
-procedure TProjectM.RenderFrame();
-begin
- _projectM_renderFrame(data);
-end;
-
-procedure TProjectM.AddPCMfloat(pcmData: PSingle; samples: integer);
-begin
- _PCM_addPCMfloat(data, pcmData, samples);
-end;
-
-procedure TProjectM.AddPCM16(pcmData: PPCM16);
-begin
- _PCM_addPCM16(data, pcmData);
-end;
-
-{**
- * Passes interleaved stereo PCM-samples to projectM.
- *}
-procedure TProjectM.AddPCM16Data(pcmData: PSmallint; samples: Smallint);
-begin
- _PCM_addPCM16Data(data, PCshort(pcmData), samples);
-end;
-
-procedure TProjectM.AddPCM8_512(pcmData: PPCM8_512);
-begin
- _PCM_addPCM8_512(data, pcmData);
-end;
-
-procedure TProjectM.AddPCM8_1024(pcmData: PPCM8_1024);
-begin
- _PCM_addPCM8_1024(data, pcmData);
-end;
-
-{**
- * If the result is > -1 projectM will render to a texture.
- * The texture-ID is the return-value.
- *}
-function TProjectM.InitRenderToTexture(): GLuint;
-begin
- result := _projectM_initRenderToTexture(data);
-end;
-
-procedure TProjectM.KeyHandler(event: TProjectMEvent;
- keycode: TProjectMKeycode;
- modifier: TProjectMModifier);
-begin
- _projectM_key_handler(data, event, keycode, modifier);
-end;
-
-procedure TProjectM.RandomPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_r_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.PreviousPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_p_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.NextPreset();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_n_LOWERCASE, PROJECTM_KMOD_LSHIFT);
-end;
-
-procedure TProjectM.ToggleShowPresetNames();
-begin
- KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_F3, PROJECTM_KMOD_LSHIFT);
-end;
-
-{$IF PROJECTM_VERSION > 1000000} // > 1.01
-procedure TProjectM.Settings(var settings: TSettings);
-begin
- _projectM_settings(data, @settings);
-end;
-{$IFEND}
-
-destructor TProjectM.Destroy();
-begin
- _projectM_free(data);
- data := nil;
- inherited;
-end;
-
diff --git a/Game/Code/lib/projectM/projectM.pas b/Game/Code/lib/projectM/projectM.pas
deleted file mode 100644
index 4adba17d..00000000
--- a/Game/Code/lib/projectM/projectM.pas
+++ /dev/null
@@ -1,232 +0,0 @@
-unit projectM;
-
-{$IFDEF FPC}
- {$MODE DELPHI}
- {$H+} (* use AnsiString *)
- {$PACKENUM 4} (* use 4-byte enums *)
- {$PACKRECORDS C} (* C/C++-compatible record packing *)
-{$ELSE}
- {$MINENUMSIZE 4} (* use 4-byte enums *)
-{$ENDIF}
-
-interface
-
-uses
- SysUtils,
- ctypes,
- gl,
- UConfig;
-
-type
- // 16bit non-interleaved data
- TPCM16 = array[0..1, 0..511] of Smallint;
- PPCM16 = ^TPCM16;
- // 8bit non-interleaved data (512 samples)
- TPCM8_512 = array[0..1, 0..511] of byte;
- PPCM8_512 = ^TPCM8_512;
- // 8bit non-interleaved data (1024 samples)
- TPCM8_1024 = array[0..1, 0..1023] of byte;
- PPCM8_1024 = ^TPCM8_512;
-
-{ Event types }
-type
- TProjectMEvent = cint;
-const
- PROJECTM_KEYUP = 0;
- PROJECTM_KEYDOWN = 1;
- PROJECTM_VIDEORESIZE = 2;
- PROJECTM_VIDEOQUIT = 3;
- PROJECTM_NONE = 4;
-
-{ Keycodes }
-type
- TProjectMKeycode = cint;
-const
- PROJECTM_K_RETURN = 0;
- PROJECTM_K_RIGHT = 1;
- PROJECTM_K_LEFT = 2;
- PROJECTM_K_UP = 3;
- PROJECTM_K_DOWN = 4;
- PROJECTM_K_PAGEUP = 5;
- PROJECTM_K_PAGEDOWN = 6;
- PROJECTM_K_INSERT = 7;
- PROJECTM_K_DELETE = 8;
- PROJECTM_K_ESCAPE = 9;
- PROJECTM_K_LSHIFT = 10;
- PROJECTM_K_RSHIFT = 11;
- PROJECTM_K_CAPSLOCK = 12;
- PROJECTM_K_LCTRL = 13;
- PROJECTM_K_HOME = 14;
- PROJECTM_K_END = 15;
- PROJECTM_K_BACKSPACE = 16;
-
- PROJECTM_K_F1 = 17;
- PROJECTM_K_F2 = (PROJECTM_K_F1 + 1);
- PROJECTM_K_F3 = (PROJECTM_K_F1 + 2);
- PROJECTM_K_F4 = (PROJECTM_K_F1 + 3);
- PROJECTM_K_F5 = (PROJECTM_K_F1 + 4);
- PROJECTM_K_F6 = (PROJECTM_K_F1 + 5);
- PROJECTM_K_F7 = (PROJECTM_K_F1 + 6);
- PROJECTM_K_F8 = (PROJECTM_K_F1 + 7);
- PROJECTM_K_F9 = (PROJECTM_K_F1 + 8);
- PROJECTM_K_F10 = (PROJECTM_K_F1 + 9);
- PROJECTM_K_F11 = (PROJECTM_K_F1 + 10);
- PROJECTM_K_F12 = (PROJECTM_K_F1 + 11);
-
- PROJECTM_K_0 = 48;
- PROJECTM_K_1 = (PROJECTM_K_0 + 1);
- PROJECTM_K_2 = (PROJECTM_K_0 + 2);
- PROJECTM_K_3 = (PROJECTM_K_0 + 3);
- PROJECTM_K_4 = (PROJECTM_K_0 + 4);
- PROJECTM_K_5 = (PROJECTM_K_0 + 5);
- PROJECTM_K_6 = (PROJECTM_K_0 + 6);
- PROJECTM_K_7 = (PROJECTM_K_0 + 7);
- PROJECTM_K_8 = (PROJECTM_K_0 + 8);
- PROJECTM_K_9 = (PROJECTM_K_0 + 9);
-
- { Upper case }
- PROJECTM_K_A_UPPERCASE = 65;
- PROJECTM_K_B_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 1);
- PROJECTM_K_C_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 2);
- PROJECTM_K_D_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 3);
- PROJECTM_K_E_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 4);
- PROJECTM_K_F_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 5);
- PROJECTM_K_G_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 6);
- PROJECTM_K_H_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 7);
- PROJECTM_K_I_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 8);
- PROJECTM_K_J_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 9);
- PROJECTM_K_K_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 10);
- PROJECTM_K_L_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 11);
- PROJECTM_K_M_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 12);
- PROJECTM_K_N_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 13);
- PROJECTM_K_O_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 14);
- PROJECTM_K_P_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 15);
- PROJECTM_K_Q_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 16);
- PROJECTM_K_R_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 17);
- PROJECTM_K_S_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 18);
- PROJECTM_K_T_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 19);
- PROJECTM_K_U_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 20);
- PROJECTM_K_V_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 21);
- PROJECTM_K_W_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 22);
- PROJECTM_K_X_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 23);
- PROJECTM_K_Y_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 24);
- PROJECTM_K_Z_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 25);
-
- { Lower case }
- PROJECTM_K_a_LOWERCASE = 97;
- PROJECTM_K_b_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 1);
- PROJECTM_K_c_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 2);
- PROJECTM_K_d_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 3);
- PROJECTM_K_e_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 4);
- PROJECTM_K_f_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 5);
- PROJECTM_K_g_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 6);
- PROJECTM_K_h_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 7);
- PROJECTM_K_i_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 8);
- PROJECTM_K_j_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 9);
- PROJECTM_K_k_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 10);
- PROJECTM_K_l_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 11);
- PROJECTM_K_m_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 12);
- PROJECTM_K_n_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 13);
- PROJECTM_K_o_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 14);
- PROJECTM_K_p_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 15);
- PROJECTM_K_q_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 16);
- PROJECTM_K_r_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 17);
- PROJECTM_K_s_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 18);
- PROJECTM_K_t_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 19);
- PROJECTM_K_u_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 20);
- PROJECTM_K_v_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 21);
- PROJECTM_K_w_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 22);
- PROJECTM_K_x_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 23);
- PROJECTM_K_y_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 24);
- PROJECTM_K_z_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 25);
-
- PROJECTM_K_NONE = (PROJECTM_K_z_LOWERCASE + 1);
-
-{ Modifiers }
-type
- TProjectMModifier = cint;
-const
- PROJECTM_KMOD_LSHIFT = 0;
- PROJECTM_KMOD_RSHIFT = 1;
- PROJECTM_KMOD_CAPS = 2;
- PROJECTM_KMOD_LCTRL = 3;
- PROJECTM_KMOD_RCTRL = 4;
-
-type
- PSettings = ^TSettings;
- TSettings = record
- meshX: cint;
- meshY: cint;
- fps: cint;
- textureSize: cint;
- windowWidth: cint;
- windowHeight: cint;
- presetURL: PChar;
- titleFontURL: PChar;
- menuFontURL: PChar;
- smoothPresetDuration: cint;
- presetDuration: cint;
- beatSensitivity: cfloat;
- aspectCorrection: byte;
- easterEgg: cfloat;
- shuffleEnabled: byte;
- end;
-
-type
- PProjectM = ^TProjectM;
- TProjectM = class(TObject)
- private
- data: Pointer;
- public
- {$IF PROJECTM_VERSION < 1000000} // 0.9x
- constructor Create(gx, gy: integer; fps: integer;
- texsize: integer; width, height: integer;
- const presetsDir, fontsDir: string;
- const titleFont: string = 'Vera.ttf';
- const menuFont: string = 'Vera.ttf'); overload;
- {$IFEND}
- {$IF PROJECTM_VERSION >= 1000000}
- constructor Create(const configFile: string); overload;
- {$IFEND}
-
- procedure ResetGL(width, height: Integer);
- procedure SetTitle(const title: string);
- procedure RenderFrame();
-
- procedure AddPCMfloat(pcmData: PSingle; samples: integer);
- procedure AddPCM16(pcmData: PPCM16);
- procedure AddPCM16Data(pcmData: PSmallint; samples: Smallint);
- procedure AddPCM8_512(pcmData: PPCM8_512);
- {$IF PROJECTM_VERSION >= 1000000}
- procedure AddPCM8_1024(pcmData: PPCM8_1024);
- {$IFEND}
-
- procedure RandomPreset();
- procedure PreviousPreset();
- procedure NextPreset();
- procedure ToggleShowPresetNames();
-
- {$IF PROJECTM_VERSION >= 1000000}
- function InitRenderToTexture(): GLuint;
- {$IFEND}
-
- procedure KeyHandler(event: TProjectMEvent;
- keycode: TProjectMKeycode;
- modifier: TProjectMModifier);
-
- {$IF PROJECTM_VERSION > 1000000} // > 1.01
- procedure Settings(var settings: TSettings);
- {$IFEND}
-
- destructor Destroy(); override;
- end;
-
-implementation
-
-{$IF PROJECTM_VERSION >= 1000000}
- {$I projectM-1_0.inc}
-{$ELSE}
- {$I projectM-0_9.inc}
-{$IFEND}
-
-end.
diff --git a/Game/Code/lib/requirements.txt b/Game/Code/lib/requirements.txt
deleted file mode 100644
index a5af1ac4..00000000
--- a/Game/Code/lib/requirements.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Included in SVN ..
----------------------------------------------------------------------------
-
-
-Jedi-sdl
- http://sourceforge.net/projects/jedi-sdl
-
-pngImage
- http://pngdelphi.sourceforge.net/
-
-BASS.pas
- http://www.un4seen.com/download.php?bass23
-
-zlportio
- http://www.specosoft.com/en/download.html
-
-ffmpeg
- http://www.iversenit.dk/dev/ffmpeg-headers/
-
-SQLLite Wrapper
- http://www.itwriting.com/sqlitesimple.php
-
-======================================
-For LINUX build
-======================================
-On top of the above pas files, you will need development libraries for them.
-
-here are the instructions needed to compile on ubunty ( 7.04 )
-
- sudo apt-get install libavcodec-dev libavformat-dev libsqlite3-dev libsdl-ttf2.0-dev libsdl-image1.2-dev portaudio19-dev
-
-in order to build the configure file ( with autogen.sh )
-
- sudo apt-get install automake autoconf
-
-
-for Fedora 8 ( contributed by kdub )
-
- yum install ffmpeg-devel portaudio-devel SDL_ttf-devel SDL_image-devel sqlite-devel
diff --git a/Game/Code/lib/samplerate/samplerate.pas b/Game/Code/lib/samplerate/samplerate.pas
deleted file mode 100644
index 784b87da..00000000
--- a/Game/Code/lib/samplerate/samplerate.pas
+++ /dev/null
@@ -1,199 +0,0 @@
-{*
-** Copyright (C) 2002-2004 Erik de Castro Lopo
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-*}
-
-{*
-** API documentation is available here:
-** http://www.mega-nerd.com/SRC/api.html
-*}
-
-unit samplerate;
-
-{$IFDEF FPC}
- {$MODE DELPHI}
- {$PACKENUM 4} (* use 4-byte enums *)
- {$PACKRECORDS C} (* GCC/Visual C/C++ compatible record packing *)
-{$ELSE}
- {$MINENUMSIZE 4} (* use 4-byte enums *)
-{$ENDIF}
-
-
-interface
-
-uses
- ctypes,
- UConfig;
-
-const
-{$IFDEF MSWINDOWS}
- LibName = 'libsamplerate-0.dll';
-{$ENDIF}
-{$IFDEF UNIX}
- LibName = 'samplerate';
- {$IFDEF DARWIN}
- {$LINKLIB libsamplerate}
- {$ENDIF}
-{$ENDIF}
-
-{ Opaque data type SRC_STATE. }
-type
- PSRC_STATE = ^SRC_STATE;
- SRC_STATE = record
- // opaque
- end;
-
-{ SRC_DATA is used to pass data to src_simple() and src_process(). }
-type
- PSRC_DATA = ^SRC_DATA;
- SRC_DATA = record
- data_in, data_out: PCfloat;
- input_frames, output_frames: clong;
- input_frames_used, output_frames_gen: clong;
- end_of_input: cint;
- src_ratio: cdouble;
- end;
-
-{ SRC_CB_DATA is used with callback based API. }
-type
- SRC_CB_DATA = record
- frames: clong;
- data_in: PCfloat;
- end;
-
-{*
-** User supplied callback function type for use with src_callback_new()
-** and src_callback_read(). First parameter is the same pointer that was
-** passed into src_callback_new(). Second parameter is pointer to a
-** pointer. The user supplied callback function must modify *data to
-** point to the start of the user supplied float array. The user supplied
-** function must return the number of frames that **data points to.
-*}
-src_callback_t = function (cb_data: pointer; var data: PCfloat): clong; cdecl;
-
-{*
-** Standard initialisation function : return an anonymous pointer to the
-** internal state of the converter. Choose a converter from the enums below.
-** Error returned in *error.
-*}
-function src_new(converter_type: cint; channels: cint; error: PCint): PSRC_STATE; cdecl; external LibName;
-
-{*
-** Initilisation for callback based API : return an anonymous pointer to the
-** internal state of the converter. Choose a converter from the enums below.
-** The cb_data pointer can point to any data or be set to NULL. Whatever the
-** value, when processing, user supplied function "func" gets called with
-** cb_data as first parameter.
-*}
-function src_callback_new(func: src_callback_t; converter_type: cint; channels: cint;
- error: Pinteger; cb_data: pointer): PSRC_STATE; cdecl; external LibName;
-
-{*
-** Cleanup all internal allocations.
-** Always returns NULL.
-*}
-function src_delete(state: PSRC_STATE): PSRC_STATE; cdecl; external LibName;
-
-{*
-** Standard processing function.
-** Returns non zero on error.
-*}
-function src_process(state: PSRC_STATE; data: PSRC_DATA): cint; cdecl; external LibName;
-
-{*
-** Callback based processing function. Read up to frames worth of data from
-** the converter int *data and return frames read or -1 on error.
-*}
-function src_callback_read(state: PSRC_STATE; src_ratio: cdouble;
- frames: clong; data: PCfloat): clong; cdecl; external LibName;
-
-{*
-** Simple interface for performing a single conversion from input buffer to
-** output buffer at a fixed conversion ratio.
-** Simple interface does not require initialisation as it can only operate on
-** a single buffer worth of audio.
-*}
-function src_simple(data: PSRC_DATA; converter_type: cint; channels: cint): cint; cdecl; external LibName;
-
-{*
-** This library contains a number of different sample rate converters,
-** numbered 0 through N.
-**
-** Return a string giving either a name or a more full description of each
-** sample rate converter or NULL if no sample rate converter exists for
-** the given value. The converters are sequentially numbered from 0 to N.
-*}
-function src_get_name(converter_type: cint): {const} Pchar; cdecl; external LibName;
-function src_get_description(converter_type: cint): {const} Pchar; cdecl; external LibName;
-function src_get_version(): {const} Pchar; cdecl; external LibName;
-
-{*
-** Set a new SRC ratio. This allows step responses
-** in the conversion ratio.
-** Returns non zero on error.
-*}
-function src_set_ratio(state: PSRC_STATE; new_ratio: cdouble): cint; cdecl; external LibName;
-
-{*
-** Reset the internal SRC state.
-** Does not modify the quality settings.
-** Does not free any memory allocations.
-** Returns non zero on error.
-*}
-function src_reset(state: PSRC_STATE): cint; cdecl; external LibName;
-
-{*
-** Return TRUE if ratio is a valid conversion ratio, FALSE
-** otherwise.
-*}
-function src_is_valid_ratio(ratio: cdouble): cint; cdecl; external LibName;
-
-{*
-** Return an error number.
-*}
-function src_error(state: PSRC_STATE): cint; cdecl; external LibName;
-
-{*
-** Convert the error number into a string.
-*}
-function src_strerror(error: cint): {const} Pchar; cdecl; external LibName;
-
-{*
-** The following enums can be used to set the interpolator type
-** using the function src_set_converter().
-*}
-const
- SRC_SINC_BEST_QUALITY = 0;
- SRC_SINC_MEDIUM_QUALITY = 1;
- SRC_SINC_FASTEST = 2;
- SRC_ZERO_ORDER_HOLD = 3;
- SRC_LINEAR = 4;
-
-{*
-** Extra helper functions for converting from short to float and
-** back again.
-*}
-procedure src_short_to_float_array(input: {const} PCshort; output: PCfloat; len: cint); cdecl; external LibName;
-procedure src_float_to_short_array(input: {const} PCfloat; output: PCshort; len: cint); cdecl; external LibName;
-
-{$IF LIBSAMPLERATE_VERSION >= 1003} // 0.1.3
-procedure src_int_to_float_array(input: {const} PCint; output: PCfloat; len: cint); cdecl; external LibName;
-procedure src_float_to_int_array(input: {const} PCfloat; output: PCint; len: cint); cdecl; external LibName;
-{$IFEND}
-
-implementation
-
-end.
diff --git a/Game/Code/lib/zlib/zlib.pas b/Game/Code/lib/zlib/zlib.pas
deleted file mode 100644
index 31d6a68b..00000000
--- a/Game/Code/lib/zlib/zlib.pas
+++ /dev/null
@@ -1,215 +0,0 @@
-(*
- * zlib pascal headers
- * This file is part of Free Pascal, released under the LGPL.
- *)
-
-{$ifdef FPC}
- {$ifndef NO_SMART_LINK}
- {$smartlink on}
- {$endif}
-{$endif}
-unit zlib;
-
-interface
-
-{$ifdef FPC}
- {$mode objfpc} // Needed for array of const
- {$H+} // use AnsiString
- {$PACKRECORDS C}
-{$endif}
-
-uses
- ctypes;
-
-const
- ZLIB_VERSION = '1.2.3';
-
-{$ifdef MSWINDOWS}
- libz = 'zlib1';
-{$else}
- libz = 'z';
- {$IFDEF DARWIN}
- {$linklib libz}
- {$ENDIF}
-{$endif}
-
-type
- { Compatible with paszlib }
- uInt = cuint;
- uLong = culong;
- uLongf = uLong; {FAR}
- PuLongf = ^uLongf;
- z_off_t = clong;
- pbyte = ^byte;
- bytef = byte; {FAR}
- pbytef = ^byte;
- voidpf = pointer;
-
- TAllocfunc = function (opaque: voidpf; items: uInt; size: uInt): voidpf; cdecl;
- TFreeFunc = procedure (opaque: voidpf; address: voidpf); cdecl;
-
- TInternalState = record
- end;
- PInternalState = ^TInternalstate;
-
- TZStream = record
- next_in: pbytef;
- avail_in: uInt;
- total_in: uLong;
- next_out: pbytef;
- avail_out: uInt;
- total_out: uLong;
- msg: pchar;
- state: PInternalState;
- zalloc: TAllocFunc;
- zfree: TFreeFunc;
- opaque: voidpf;
- data_type: cint;
- adler: uLong;
- reserved: uLong;
- end;
- TZStreamRec = TZStream;
- PZstream = ^TZStream;
- gzFile = pointer;
-
-
-const
- Z_NO_FLUSH = 0;
- Z_PARTIAL_FLUSH = 1;
- Z_SYNC_FLUSH = 2;
- Z_FULL_FLUSH = 3;
- Z_FINISH = 4;
- Z_BLOCK = 5;
-
- Z_OK = 0;
- Z_STREAM_END = 1;
- Z_NEED_DICT = 2;
- Z_ERRNO = -(1);
- Z_STREAM_ERROR = -(2);
- Z_DATA_ERROR = -(3);
- Z_MEM_ERROR = -(4);
- Z_BUF_ERROR = -(5);
- Z_VERSION_ERROR = -(6);
-
- Z_NO_COMPRESSION = 0;
- Z_BEST_SPEED = 1;
- Z_BEST_COMPRESSION = 9;
- Z_DEFAULT_COMPRESSION = -(1);
-
- Z_FILTERED = 1;
- Z_HUFFMAN_ONLY = 2;
- Z_RLE = 3;
- Z_FIXED = 4;
- Z_DEFAULT_STRATEGY = 0;
-
- Z_BINARY = 0;
- Z_TEXT = 1;
- Z_ASCII = Z_TEXT;
- Z_UNKNOWN = 2;
-
- Z_DEFLATED = 8;
-
- Z_NULL = 0;
-
-function zlibVersionpchar(): pchar; cdecl; external libz name 'zlibVersion';
-function zlibVersion(): string;
-
-function deflate(var strm: TZStream; flush: integer): integer; cdecl; external libz name 'deflate';
-function deflateEnd(var strm: TZStream): integer; cdecl; external libz name 'deflateEnd';
-function inflate(var strm: TZStream; flush: integer): integer; cdecl; external libz name 'inflate';
-function inflateEnd(var strm: TZStream): integer; cdecl; external libz name 'inflateEnd';
-function deflateSetDictionary(var strm: TZStream; dictionary: pbytef; dictLength: uInt): integer; cdecl; external libz name 'deflateSetDictionary';
-function deflateCopy(var dest, source: TZstream): integer; cdecl; external libz name 'deflateCopy';
-function deflateReset(var strm: TZStream): integer; cdecl; external libz name 'deflateReset';
-function deflateParams(var strm: TZStream; level: integer; strategy: integer): integer; cdecl; external libz name 'deflateParams';
-//...
-function inflateSetDictionary(var strm: TZStream; dictionary: pbytef; dictLength: uInt): integer; cdecl; external libz name 'inflateSetDictionary';
-function inflateSync(var strm: TZStream): integer; cdecl; external libz name 'inflateSync';
-//...
-function inflateReset(var strm: TZStream): integer; cdecl; external libz name 'inflateReset';
-
-function compress(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong): integer; cdecl; external libz name 'compress';
-function compress2(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong; level: integer): integer; cdecl; external libz name 'compress2';
-function uncompress(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong): integer; cdecl; external libz name 'uncompress';
-
-function gzopen(path: pchar; mode: pchar): gzFile; cdecl; external libz name 'gzopen';
-function gzdopen(fd: integer; mode: pchar): gzFile; cdecl; external libz name 'gzdopen';
-function gzsetparams(thefile: gzFile; level: integer; strategy: integer): integer; cdecl; external libz name 'gzsetparams';
-function gzread(thefile: gzFile; buf: pointer; len: cardinal): integer; cdecl; external libz name 'gzread';
-function gzwrite(thefile: gzFile; buf: pointer; len: cardinal): integer; cdecl; external libz name 'gzwrite';
-function gzprintf(thefile: gzFile; format: pbytef; args: array of const): integer; cdecl; external libz name 'gzprintf';
-function gzputs(thefile: gzFile; s: pbytef): integer; cdecl; external libz name 'gzputs';
-function gzgets(thefile: gzFile; buf: pbytef; len: integer): pchar; cdecl; external libz name 'gzgets';
-function gzputc(thefile: gzFile; c: integer): integer; cdecl; external libz name 'gzputc';
-function gzgetc(thefile: gzFile): integer; cdecl; external libz name 'gzgetc';
-function gzflush(thefile: gzFile; flush: integer): integer; cdecl; external libz name 'gzflush';
-function gzseek(thefile: gzFile; offset: z_off_t; whence: integer): z_off_t; cdecl; external libz name 'gzseek';
-function gzrewind(thefile: gzFile): integer; cdecl; external libz name 'gzrewind';
-function gztell(thefile: gzFile): z_off_t; cdecl; external libz name 'gztell';
-function gzeof(thefile: gzFile): integer; cdecl; external libz name 'gzeof';
-function gzclose(thefile: gzFile): integer; cdecl; external libz name 'gzclose';
-function gzerror(thefile: gzFile; var errnum: integer): pchar; cdecl; external libz name 'gzerror';
-
-function adler32(adler: uLong; buf: pbytef; len: uInt): uLong; cdecl; external libz name 'adler32';
-function crc32(crc: uLong; buf: pbytef; len: uInt): uLong; cdecl; external libz name 'crc32';
-
-function deflateInit_(var strm: TZStream; level: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'deflateInit_';
-function deflateInit(var strm: TZStream; level : integer) : integer;
-function inflateInit_(var strm: TZStream; version: pchar; stream_size: integer): integer; cdecl; external libz name 'inflateInit_';
-function inflateInit(var strm:TZStream) : integer;
-function deflateInit2_(var strm: TZStream; level: integer; method: integer; windowBits: integer; memLevel: integer; strategy: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'deflateInit2_';
-function deflateInit2(var strm: TZStream; level, method, windowBits, memLevel, strategy: integer): integer;
-function inflateInit2_(var strm: TZStream; windowBits: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'inflateInit2_';
-function inflateInit2(var strm: TZStream; windowBits: integer): integer;
-
-function zErrorpchar(err: integer): pchar; cdecl; external libz name 'zError';
-function zError(err: integer): string;
-function inflateSyncPoint(z: PZstream): integer; cdecl; external libz name 'inflateSyncPoint';
-function get_crc_table(): pointer; cdecl; external libz name 'get_crc_table';
-
-function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
-procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
-
-implementation
-
-function zlibversion(): string;
-begin
- zlibversion := string(zlibversionpchar);
-end;
-
-function deflateInit(var strm: TZStream; level: integer) : integer;
-begin
- deflateInit := deflateInit_(strm, level, ZLIB_VERSION, sizeof(TZStream));
-end;
-
-function inflateInit(var strm: TZStream): integer;
-begin
- inflateInit := inflateInit_(strm, ZLIB_VERSION, sizeof(TZStream));
-end;
-
-function deflateInit2(var strm: TZStream; level, method, windowBits, memLevel, strategy: integer) : integer;
-begin
- deflateInit2 := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, sizeof(TZStream));
-end;
-
-function inflateInit2(var strm: TZStream; windowBits: integer): integer;
-begin
- inflateInit2 := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(TZStream));
-end;
-
-function zError(err: integer): string;
-begin
- zerror := string(zErrorpchar(err));
-end;
-
-function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
-begin
- Result := GetMemory(Items * Size);
-end;
-
-procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
-begin
- FreeMem(Block);
-end;
-
-end.
diff --git a/Game/Code/m4/ac_define_dir.m4 b/Game/Code/m4/ac_define_dir.m4
deleted file mode 100644
index f3d8734f..00000000
--- a/Game/Code/m4/ac_define_dir.m4
+++ /dev/null
@@ -1,47 +0,0 @@
-##### http://autoconf-archive.cryp.to/ac_define_dir.html
-#
-# SYNOPSIS
-#
-# AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
-#
-# DESCRIPTION
-#
-# This macro sets VARNAME to the expansion of the DIR variable,
-# taking care of fixing up ${prefix} and such.
-#
-# VARNAME is then offered as both an output variable and a C
-# preprocessor symbol.
-#
-# Example:
-#
-# AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
-#
-# LAST MODIFICATION
-#
-# 2006-10-13
-#
-# COPYLEFT
-#
-# Copyright (c) 2006 Stepan Kasal
-# Copyright (c) 2006 Andreas Schwab
-# Copyright (c) 2006 Guido U. Draheim
-# Copyright (c) 2006 Alexandre Oliva
-#
-# Copying and distribution of this file, with or without
-# modification, are permitted in any medium without royalty provided
-# the copyright notice and this notice are preserved.
-
-AC_DEFUN([AC_DEFINE_DIR], [
- prefix_NONE=
- exec_prefix_NONE=
- test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
-dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
-dnl refers to ${prefix}. Thus we have to use `eval' twice.
- eval ac_define_dir="\"[$]$2\""
- eval ac_define_dir="\"$ac_define_dir\""
- AC_SUBST($1, "$ac_define_dir")
- AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3])
- test "$prefix_NONE" && prefix=NONE
- test "$exec_prefix_NONE" && exec_prefix=NONE
-])
diff --git a/Game/Code/m4/fpc.m4 b/Game/Code/m4/fpc.m4
deleted file mode 100644
index 896c53d2..00000000
--- a/Game/Code/m4/fpc.m4
+++ /dev/null
@@ -1,176 +0,0 @@
-dnl ** Version 1.1 of file is part of the LGPLed
-dnl ** J Sound System (http://jss.sourceforge.net)
-dnl **
-dnl ** Checks for Free Pascal Compiler by Matti "ccr/TNSP" Hamalainen
-dnl ** (C) Copyright 2000-2001 Tecnic Software productions (TNSP)
-dnl **
-dnl ** Versions
-dnl ** --------
-dnl ** 1.0 - Created
-dnl **
-dnl ** 1.1 - Added stuff to enable unix -> win32
-dnl ** cross compilation.
-dnl **
-dnl ** 1.x - A few fixes (by the UltraStar Deluxe Team)
-dnl **
-
-AC_DEFUN([AC_PROG_FPC], [
-
-AC_ARG_VAR(PFLAGS, [Free Pascal Compiler flags (replaces all other flags)])
-AC_ARG_VAR(PFLAGS_DEBUG, [Free Pascal Compiler debug flags @<:@-gl -Coi -Xs- -vew -dDEBUG_MODE@:>@])
-AC_ARG_VAR(PFLAGS_RELEASE, [Free Pascal Compiler release flags @<:@-O2 -Xs -vew@:>@])
-AC_ARG_VAR(PFLAGS_EXTRA, [Free Pascal Compiler additional flags])
-
-dnl set DEBUG/RELEASE flags to default-values if unset
-
-dnl - Do not use -dDEBUG because this will enable range-checks that will fail with USDX.
-dnl - Disable -Xs which is defined in fpc.cfg (TODO: is this necessary?).
-dnl - For FPC we have to use DEBUG_MODE instead of DEBUG to enable the apps debug-mode
-dnl because DEBUG enables some additional compiler-flags in fpc.cfg too
-PFLAGS_DEBUG=${PFLAGS_DEBUG-"-gl -Xs- -vew -dDEBUG_MODE"}
-dnl -dRELEASE works too but we define our own settings
-PFLAGS_RELEASE=${PFLAGS_RELEASE-"-O2 -Xs -vew"}
-
-
-AC_ARG_ENABLE(dummy_fpc1,[
-Free Pascal Compiler specific options:])
-
-AC_ARG_WITH(fpc,
- [AS_HELP_STRING([--with-fpc=DIR],
- [Directory of the FPC executable @<:@PATH@:>@])],
- [PPC_PATH=$withval], [])
-
-FPC_DEBUG="no"
-
-AC_ARG_ENABLE(release,
- [AS_HELP_STRING([--enable-release],
- [Enable FPC release options @<:@default=yes@:>@])],
- [test $enableval = "no" && FPC_DEBUG="yes"], [])
-
-AC_ARG_ENABLE(debug,
- [AS_HELP_STRING([--enable-debug],
- [Enable FPC debug options (= --disable-release) @<:@default=no@:>@])],
- [test $enableval = "yes" && FPC_DEBUG="yes"], [])
-
-AC_ARG_ENABLE(profile,
- [AS_HELP_STRING([--enable-profile],
- [Enable FPC profiling options @<:@default=no@:>@])],
- [PFLAGS_EXTRA="$PFLAGS_EXTRA -pg"], [])
-
-
-dnl ** set PFLAGS depending on whether it is already set by the user
-dnl Note: the user's PFLAGS must *follow* this script's flags
-dnl to enable the user to overwrite the settings.
-if test x${PFLAGS+assigned} = x; then
-dnl PFLAGS not set by the user
- if test x$FPC_DEBUG = xyes; then
- PFLAGS="$PFLAGS_DEBUG"
- PFLAGS_MAKE="[\$](PFLAGS_DEBUG)"
- else
- PFLAGS="$PFLAGS_RELEASE"
- PFLAGS_MAKE="[\$](PFLAGS_RELEASE)"
- fi
-else
-dnl PFLAGS set by the user, just add additional flags
- PFLAGS="$PFLAGS"
- PFLAGS_MAKE="$PFLAGS"
-fi
-
-dnl ** find compiler executable
-
-PPC_CHECK_PROGS="fpc FPC ppc386 ppc PPC386 ppos2"
-
-if test -z "$PPC_PATH"; then
- PPC_PATH=$PATH
- AC_CHECK_PROGS(PPC, $PPC_CHECK_PROGS)
- AC_CHECK_PROGS(FPCMAKE, [fpcmake])
-else
- AC_PATH_PROGS(PPC, $PPC_CHECK_PROGS, [], $PPC_PATH)
- AC_PATH_PROGS(FPCMAKE, [fpcmake], [], $PPC_PATH)
-fi
-if test -z "$PPC"; then
- AC_MSG_ERROR([no Free Pascal Compiler found in $PPC_PATH])
-fi
-if test -z "$FPCMAKE"; then
- AC_MSG_ERROR([fpcmake not found in $PPC_PATH])
-fi
-
-AC_PROG_FPC_WORKS
-AC_PROG_FPC_LINKS
-
-dnl *** Get the FPC version and some paths
-FPC_VERSION=`${PPC} -iV`
-FPC_PLATFORM=`${PPC} -iTO`
-FPC_PROCESSOR=`${PPC} -iTP`
-
-if test "x$prefix" != xNONE; then
- FPC_PREFIX=$prefix
-else
- FPC_PREFIX=$ac_default_prefix
-fi
-FPC_BASE_PATH="${FPC_PREFIX}/lib/fpc/${FPC_VERSION}"
-FPC_UNIT_PATH="${FPC_BASE_PATH}/units/${FPC_PLATFORM}"
-
-AC_SUBST(PFLAGS)
-AC_SUBST(PFLAGS_MAKE)
-AC_SUBST(PFLAGS_EXTRA)
-AC_SUBST(PFLAGS_DEBUG)
-AC_SUBST(PFLAGS_RELEASE)
-
-AC_SUBST(FPC_VERSION)
-AC_SUBST(FPC_PLATFORM)
-AC_SUBST(FPC_PROCESSOR)
-
-AC_SUBST(FPC_PREFIX)
-AC_SUBST(FPC_BASE_PATH)
-AC_SUBST(FPC_UNIT_PATH)
-])
-
-PFLAGS_TEST="$PFLAGS $PFLAGS_EXTRA"
-
-dnl ***
-dnl *** Check if FPC works and can compile a program
-dnl ***
-AC_DEFUN([AC_PROG_FPC_WORKS],
-[AC_CACHE_CHECK([whether the Free Pascal Compiler ($PPC $PFLAGS_TEST) works], ac_cv_prog_ppc_works,
-[
-rm -f conftest*
-echo "program foo; begin writeln; end." > conftest.pp
-${PPC} ${PFLAGS_TEST} conftest.pp >> config.log
-
-if test -f conftest || test -f conftest.exe; then
-dnl *** It works!
- ac_cv_prog_ppc_works="yes"
-
-else
- ac_cv_prog_ppc_works="no"
-fi
-rm -f conftest*
-dnl AC_MSG_RESULT($ac_cv_prog_ppc_works)
-if test x$ac_cv_prog_ppc_works = xno; then
- AC_MSG_ERROR([installation or configuration problem: Cannot create executables.])
-fi
-])])
-
-
-dnl ***
-dnl *** Check if FPC can link with standard libraries
-dnl ***
-AC_DEFUN([AC_PROG_FPC_LINKS],
-[AC_CACHE_CHECK([whether the Free Pascal Compiler ($PPC $PFLAGS_TEST) can link], ac_cv_prog_ppc_works,
-[
-rm -f conftest*
-echo "program foo; uses crt; begin writeln; end." > conftest.pp
-${PPC} ${PFLAGS_TEST} conftest.pp >> config.log
-if test -f conftest || test -f conftest.exe; then
- ac_cv_prog_ppc_links="yes"
-else
- ac_cv_prog_ppc_links="no"
-fi
-rm -f conftest*
-AC_MSG_RESULT($ac_cv_prog_ppc_links)
-if test x$ac_cv_prog_ppc_links = xno; then
- AC_MSG_ERROR([installation or configuration problem: Cannot link with some standard libraries.])
-fi
-])])
-
diff --git a/Game/Code/package_debian.sh b/Game/Code/package_debian.sh
deleted file mode 100644
index bdb341a2..00000000
--- a/Game/Code/package_debian.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-# This script should be run post-compile
-# and i should move files to the correct location for packaging ... ( for DEB package )
-
-rm -fr ../../../deb-package
-rm -fr ../../../packages
-clear
-
-mkdir ../../../packages
-
-mkdir ../../../deb-package
-mkdir ../../../deb-package/DEBIAN
-mkdir ../../../deb-package/usr
-mkdir ../../../deb-package/usr/local
-mkdir ../../../deb-package/usr/local/share
-mkdir ../../../deb-package/usr/local/share/UltraStarDeluxe
-mkdir ../../../deb-package/usr/bin
-
-cp ../../UltraStar ../../../deb-package/usr/bin/UltraStarDeluxe
-
-cp -a ../../Themes/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
-cp -a ../../Sounds/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
-cp -a ../../Skins/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
-cp -a ../../Languages/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
-
-cp UltraStarDeluxe.control ../../../deb-package/DEBIAN/control
-
-cd ../../../
-
-dpkg-deb --build ./deb-package
-mv deb-package.deb ./packages/UltraStarDeluxe_1.1_i386.deb
-
-rm -fr ../../../deb-package
diff --git a/Game/Code/rccompile-delphi.bat b/Game/Code/rccompile-delphi.bat
deleted file mode 100644
index 7f0e2f0e..00000000
--- a/Game/Code/rccompile-delphi.bat
+++ /dev/null
@@ -1 +0,0 @@
-BRC32 -r -foUltraStar.res UltraStar.rc
diff --git a/Game/Code/rccompile-fpc.bat b/Game/Code/rccompile-fpc.bat
deleted file mode 100644
index ed8d57aa..00000000
--- a/Game/Code/rccompile-fpc.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@set PATH=C:\Programme\lazarus\fpc\2.2.0\bin\i386-win32\;%PATH%
-windres.exe -i UltraStar.rc -o UltraStar.res
-
diff --git a/Game/Code/switches.inc b/Game/Code/switches.inc
deleted file mode 100644
index eb67e72c..00000000
--- a/Game/Code/switches.inc
+++ /dev/null
@@ -1,111 +0,0 @@
-// compiler/IDE dependent config
-{$IFDEF FPC}
- {$H+} // use AnsiString instead of ShortString as String-type (default in Delphi)
-
- {$IFDEF DARWIN}
- {$R-} // disable range-checks (eddie: please test if this is still necessary)
- {$ENDIF}
-
- // if -dDEBUG is specified on the command-line, FPC uses some default
- // compiler-flags specified in fpc.cfg -> use -dDEBUG_MODE instead
- {$IFDEF DEBUG_MODE}
- {$DEFINE DEBUG}
- {$ENDIF}
-
- {$DEFINE HasInline}
-{$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}
-{$ENDIF}
-
-
-// platform dependent config
-{$IF Defined(MSWINDOWS)}
- // include defines but no constants
- {$I config-win.inc}
-
- // enable debug-mode. For development only!
- {.$DEFINE DEBUG}
- {$IFDEF DEBUG}
- // windows apps are either GUI- or console-apps. Console-apps will open
- // an additional console-window for output. For development only!
- {$DEFINE CONSOLE}
- {$ENDIF}
-
- {$DEFINE HaveBASS}
- {$UNDEF UseSerialPort}
- {$DEFINE UseMIDIPort}
-{$ELSEIF Defined(LINUX)}
- // include defines but no constants
- {$I config-linux.inc}
-
- // use "configure --enable-debug", "make debug" or
- // the command-line parameter "-debug" instead of defining DEBUG directly
- {.$DEFINE DEBUG}
- // linux apps are always console-apps so leave this defined.
- {$DEFINE CONSOLE}
-{$ELSEIF Defined(DARWIN)}
- // include defines but no constants
- {$I config-darwin.inc}
-
- // enable debug-mode. For development only!
- {.$DEFINE DEBUG}
- {$DEFINE CONSOLE}
- {.$DEFINE HaveBASS}
- {$DEFINE UTF8_FILENAMES}
-{$IFEND}
-
-// audio config
-{$IF Defined(HaveBASS)}
- {$DEFINE UseBASSPlayback}
- {$DEFINE UseBASSDecoder}
- {$DEFINE UseBASSInput}
-{$ELSEIF Defined(HavePortaudio)}
- {$DEFINE UseSDLPlayback}
- {.$DEFINE UsePortaudioPlayback}
- {$DEFINE UsePortaudioInput}
- {$IFDEF HavePortmixer}
- {$DEFINE UsePortmixer}
- {$ENDIF}
-{$IFEND}
-
-// ffmpeg config
-{$IFDEF HaveFFmpeg}
- {$DEFINE UseFFmpegDecoder}
- {$DEFINE UseFFmpegResample}
- {$DEFINE UseFFmpegVideo}
- {$IFDEF HaveSWScale}
- {$DEFINE UseSWScale}
- {$ENDIF}
-{$ENDIF}
-
-{$IFDEF HaveLibsamplerate}
- {$DEFINE UseSRCResample}
-{$ENDIF}
-
-// projectM config
-{$IF Defined(HaveProjectM)}
- {$DEFINE UseProjectM}
-{$IFEND}
-
-// specify some useful defines
-
-{$IF Defined(UseFFmpegVideo) or Defined(UseFFmpegDecoder)}
- {$DEFINE UseFFmpeg}
-{$IFEND}
-
-{$IF Defined(UseBASSInput) or Defined(UseBASSPlayback) or Defined(UseBASSDecoder)}
- {$DEFINE UseBASS}
-{$IFEND}
-
-{$IF Defined(UsePortaudioInput) or Defined(UsePortaudioPlayback)}
- {$DEFINE UsePortaudio}
-{$IFEND}
diff --git a/Game/Code/ultrastardx.control b/Game/Code/ultrastardx.control
deleted file mode 100644
index a1bb17f0..00000000
--- a/Game/Code/ultrastardx.control
+++ /dev/null
@@ -1,19 +0,0 @@
-Package: ultrastardx
-Priority: optional
-Section: games
-Installed-Size: 18400
-Maintainer: Jay Binks
-Architecture: i386
-Version: 1.1.1
-Depends: libc6 (>= 2.1), libsdl1.2debian-alsa, libportaudio2, libavcodec1d, libavformat1d, libsqlite3-0, libsdl-ttf2.0-0, libsdl-image1.2
-Description:
- Karaoke Software for PC like Singstar for PS2.
- It evaluates your singing by analyzing your voice pitch.
- Songs can be created with integrated Editor.
- .
- This is a Fork of the UltraStar Project with many massive improvements.
- .
- http://www.ultrastardeluxe.org/
-
-
-
diff --git a/Game/Code/ultrastardx.desktop b/Game/Code/ultrastardx.desktop
deleted file mode 100644
index d49f05ef..00000000
--- a/Game/Code/ultrastardx.desktop
+++ /dev/null
@@ -1,17 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0
-
-Name=UltraStar Deluxe
-Comment=Karaoke program that evaluates your performance
-Comment[de]=Singe Karaoke und messe dich mit anderen Spielern
-
-Icon=ultrastardx
-
-TryExec=ultrastardx
-Exec=ultrastardx
-StartupNotify=false
-Terminal=false
-
-Type=Application
-Categories=Application;Game;ArcadeGame;
diff --git a/src/Classes/TextGL.pas b/src/Classes/TextGL.pas
new file mode 100644
index 00000000..f7b3ac95
--- /dev/null
+++ b/src/Classes/TextGL.pas
@@ -0,0 +1,462 @@
+unit TextGL;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ gl,
+ SDL,
+ UTexture,
+ Classes,
+// SDL_ttf,
+ ULog;
+
+procedure BuildFont; // build our bitmap font
+procedure KillFont; // delete the font
+function glTextWidth(text: PChar): real; // returns text width
+procedure glPrintLetter(letter: char);
+procedure glPrint(text: pchar); // custom GL "Print" routine
+procedure SetFontPos(X, Y: real); // sets X and Y
+procedure SetFontZ(Z: real); // sets Z
+procedure SetFontSize(Size: real);
+procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc)
+procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts)
+procedure SetFontAspectW(Aspect: real);
+procedure SetFontReflection(Enable:boolean;Spacing: real); // enables/disables text reflection
+procedure SetFontBlend(Enable: boolean); // enables/disables blending
+
+//function NextPowerOfTwo(Value: integer): integer;
+// Checks if the ttf exists, if yes then a SDL_ttf is returned
+//function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
+// Does the renderstuff, color is in $ffeecc style
+//function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal):PSDL_Surface;
+
+type
+ TTextGL = record
+ X: real;
+ Y: real;
+ Z: real;
+ Text: string;
+ Size: real;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ end;
+
+ PFont = ^TFont;
+ TFont = record
+ Tex: TTexture;
+ Width: array[0..255] of byte;
+ AspectW: real;
+ Centered: boolean;
+ Outline: real;
+ Italic: boolean;
+ Reflection: boolean;
+ ReflectionSpacing: real;
+ Blend: boolean;
+ end;
+
+
+var
+ Fonts: array of TFont;
+ ActFont: integer;
+
+
+implementation
+
+uses
+ UMain,
+ UCommon,
+ SysUtils,
+ UGraphic;
+
+var
+ // Colours for the reflection
+ TempColor: array[0..3] of GLfloat;
+
+procedure LoadBitmapFontInfo(aID : integer; const aType, aResourceName: string);
+var
+ stream: TStream;
+begin
+ stream := GetResourceStream(aResourceName, aType);
+ if (not assigned(stream)) then
+ begin
+ Log.LogError('Unknown font['+ inttostr(aID) +': '+aType+']', 'loadfont');
+ Exit;
+ end;
+ try
+ stream.Read(Fonts[ aID ].Width, 256);
+ except
+ Log.LogError('Error while reading font['+ inttostr(aID) +': '+aType+']', 'loadfont');
+ end;
+ stream.Free;
+end;
+
+// Builds bitmap fonts
+procedure BuildFont;
+var
+ Count: integer;
+begin
+ ActFont := 0;
+
+ SetLength(Fonts, 5);
+ Fonts[0].Tex := Texture.LoadTexture(true, 'Font', TEXTURE_TYPE_TRANSPARENT, 0);
+ Fonts[0].Tex.H := 30;
+ Fonts[0].AspectW := 0.9;
+ Fonts[0].Outline := 0;
+
+ Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', TEXTURE_TYPE_TRANSPARENT, 0);
+ Fonts[1].Tex.H := 30;
+ Fonts[1].AspectW := 1;
+ Fonts[1].Outline := 0;
+
+ Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', TEXTURE_TYPE_TRANSPARENT, 0);
+ Fonts[2].Tex.H := 30;
+ Fonts[2].AspectW := 0.95;
+ Fonts[2].Outline := 5;
+
+ Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', TEXTURE_TYPE_TRANSPARENT, 0);
+ Fonts[3].Tex.H := 30;
+ Fonts[3].AspectW := 0.95;
+ Fonts[3].Outline := 4;
+
+{ Fonts[4].Tex := Texture.LoadTexture('FontO', TEXTURE_TYPE_TRANSPARENT, 0); // for score screen
+ Fonts[4].Tex.H := 30;
+ Fonts[4].AspectW := 0.95;
+ Fonts[4].Done := -1;
+ Fonts[4].Outline := 5;}
+
+ // load font info
+ LoadBitmapFontInfo( 0, 'FNT', 'Font');
+ LoadBitmapFontInfo( 1, 'FNT', 'FontB');
+ LoadBitmapFontInfo( 2, 'FNT', 'FontO');
+ LoadBitmapFontInfo( 3, 'FNT', 'FontO2');
+
+ for Count := 0 to 255 do
+ Fonts[1].Width[Count] := Fonts[1].Width[Count] div 2;
+
+ for Count := 0 to 255 do
+ Fonts[2].Width[Count] := Fonts[2].Width[Count] div 2 + 2;
+
+ for Count := 0 to 255 do
+ Fonts[3].Width[Count] := Fonts[3].Width[Count] + 1;
+
+{ for Count := 0 to 255 do
+ Fonts[4].Width[Count] := Fonts[4].Width[Count] div 2 + 2;}
+
+ // enable blending by default
+ for Count := 0 to High(Fonts) do
+ Fonts[Count].Blend := true;
+end;
+
+// Deletes the font
+procedure KillFont;
+begin
+ // delete all characters
+ //glDeleteLists(..., 256);
+end;
+
+function glTextWidth(text: pchar): real;
+var
+ Letter: char;
+ i: integer;
+begin
+ Result := 0;
+ for i := 0 to Length(text) -1 do
+ begin
+ Letter := Text[i];
+ Result := Result + Fonts[ActFont].Width[Ord(Letter)] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ end;
+end;
+
+procedure glPrintLetter(Letter: char);
+var
+ TexX, TexY: real;
+ TexR, TexB: real;
+ TexHeight: real;
+ FWidth: real;
+ PL, PT: real;
+ PR, PB: real;
+ XItal: real; // X shift for italic type letter
+ ReflectionSpacing: real; // Distance of the reflection
+ Font: PFont;
+ Tex: PTexture;
+begin
+ Font := @Fonts[ActFont];
+ Tex := @Font.Tex;
+
+ FWidth := Font.Width[Ord(Letter)];
+
+ Tex.W := FWidth * (Tex.H/30) * Font.AspectW;
+
+ // set texture positions
+ TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Font.Outline/1024;
+ TexY := (ord(Letter) div 16) * 1/16 + 2/1024;
+ TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Font.Outline/1024;
+ TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
+
+ TexHeight := TexB - TexY;
+
+ // set vector positions
+ PL := Tex.X - Font.Outline * (Tex.H/30) * Font.AspectW /2;
+ PT := Tex.Y;
+ PR := PL + Tex.W + Font.Outline * (Tex.H/30) * Font.AspectW;
+ PB := PT + Tex.H;
+
+ if (not Font.Italic) then
+ XItal := 0
+ else
+ XItal := 12;
+
+ if (Font.Blend) then
+ begin
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ end;
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, Tex.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
+ glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
+ glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
+ glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT);
+ glEnd;
+
+ // Reflection
+ // Yes it would make sense to put this in an extra procedure,
+ // but this works, doesn't take much lines, and is almost lightweight
+ if Font.Reflection then
+ begin
+ ReflectionSpacing := Font.ReflectionSpacing + Tex.H/2;
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBegin(GL_QUADS);
+ glColor4f(TempColor[0], TempColor[1], TempColor[2], 0);
+ glTexCoord2f(TexX, TexY + TexHeight/2);
+ glVertex3f(PL, PB + ReflectionSpacing - Tex.H/2, Tex.z);
+
+ glColor4f(TempColor[0], TempColor[1], TempColor[2], Tex.Alpha-0.3);
+ glTexCoord2f(TexX, TexB );
+ glVertex3f(PL + XItal, PT + ReflectionSpacing, Tex.z);
+
+ glTexCoord2f(TexR, TexB );
+ glVertex3f(PR + XItal, PT + ReflectionSpacing, Tex.z);
+
+ glColor4f(TempColor[0], TempColor[1], TempColor[2], 0);
+ glTexCoord2f(TexR, TexY + TexHeight/2);
+ glVertex3f(PR, PB + ReflectionSpacing - Tex.H/2, Tex.z);
+ glEnd;
+
+ glDisable(GL_DEPTH_TEST);
+ end; // reflection
+
+ glDisable(GL_TEXTURE_2D);
+ if (Font.Blend) then
+ glDisable(GL_BLEND);
+
+ Tex.X := Tex.X + Tex.W;
+
+ //write the colour back
+ glColor4fv(@TempColor);
+end;
+
+// Custom GL "Print" Routine
+procedure glPrint(Text: PChar);
+var
+ Pos: integer;
+begin
+ // if there is no text do nothing
+ if ((Text = nil) or (Text = '')) then
+ Exit;
+
+ //Save the actual color and alpha (for reflection)
+ glGetFloatv(GL_CURRENT_COLOR, @TempColor);
+
+ for Pos := 0 to Length(Text) - 1 do
+ begin
+ glPrintLetter(Text[Pos]);
+ end;
+end;
+
+procedure SetFontPos(X, Y: real);
+begin
+ Fonts[ActFont].Tex.X := X;
+ Fonts[ActFont].Tex.Y := Y;
+end;
+
+procedure SetFontZ(Z: real);
+begin
+ Fonts[ActFont].Tex.Z := Z;
+end;
+
+procedure SetFontSize(Size: real);
+begin
+ Fonts[ActFont].Tex.H := 30 * (Size/10);
+end;
+
+procedure SetFontStyle(Style: integer);
+begin
+ ActFont := Style;
+end;
+
+procedure SetFontItalic(Enable: boolean);
+begin
+ Fonts[ActFont].Italic := Enable;
+end;
+
+procedure SetFontAspectW(Aspect: real);
+begin
+ Fonts[ActFont].AspectW := Aspect;
+end;
+
+procedure SetFontReflection(Enable: boolean; Spacing: real);
+begin
+ Fonts[ActFont].Reflection := Enable;
+ Fonts[ActFont].ReflectionSpacing := Spacing;
+end;
+
+procedure SetFontBlend(Enable: boolean);
+begin
+ Fonts[ActFont].Blend := Enable;
+end;
+
+
+
+
+(*
+ I uncommented this, because it was some kind of after hour hack together with blindy
+it's actually just a prove of concept, as it's having some flaws
+- instead nice and clean ttf code should be placed here :)
+
+{$IFDEF FPC}
+ {$ASMMODE Intel}
+{$ENDIF}
+
+function NextPowerOfTwo(Value: integer): integer;
+begin
+ Result:= 1;
+{$IF Defined(CPUX86_64)}
+ asm
+ mov rcx, -1
+ bsr rcx, Value
+ inc rcx
+ shl Result, cl
+ end;
+{$ELSEIF Defined(CPU386) or Defined(CPUI386)}
+ asm
+ mov ecx, -1
+ bsr ecx, Value
+ inc ecx
+ shl Result, cl
+ end;
+{$ELSE}
+ while (Result <= Value) do
+ Result := 2 * Result;
+{$IFEND}
+end;
+
+function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
+begin
+ if (FileExists(FileName)) then
+ begin
+ Result := TTF_OpenFont( FileName, PointSize );
+ end
+ else
+ begin
+ Log.LogStatus('ERROR Could not find font in ' + FileName , '');
+ ShowMessage( 'ERROR Could not find font in ' + FileName );
+ Result := nil;
+ end;
+end;
+
+function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal): PSDL_Surface;
+var
+ clr : TSDL_color;
+begin
+ clr.r := ((Color and $ff0000) shr 16 ) div 255;
+ clr.g := ((Color and $ff00 ) shr 8 ) div 255;
+ clr.b := ( Color and $ff ) div 255 ;
+
+ result := TTF_RenderText_Blended( font, text, cLr);
+end;
+
+procedure printrandomtext();
+var
+ stext,intermediary : PSDL_surface;
+ clrFg, clrBG : TSDL_color;
+ texture : Gluint;
+ font : PTTF_Font;
+ w,h : integer;
+begin
+
+ font := LoadFont('fonts\comicbd.ttf', 42);
+
+ clrFg.r := 255;
+ clrFg.g := 255;
+ clrFg.b := 255;
+ clrFg.unused := 255;
+
+ clrBg.r := 255;
+ clrbg.g := 0;
+ clrbg.b := 255;
+ clrbg.unused := 0;
+
+ sText := RenderText(font, 'katzeeeeeee', $fe198e);
+ //sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG);
+
+ // Convert the rendered text to a known format
+ w := nextpoweroftwo(sText.w);
+ h := nextpoweroftwo(sText.h);
+
+ intermediary := SDL_CreateRGBSurface(0, w, h, 32,
+ $000000ff, $0000ff00, $00ff0000, $ff000000);
+
+ SDL_SetAlpha(intermediary, 0, 255);
+ SDL_SetAlpha(sText, 0, 255);
+ SDL_BlitSurface(sText, nil, intermediary, nil);
+
+ glGenTextures(1, @texture);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary.pixels);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glColor4f(1, 0, 1, 1);
+
+ glbegin(gl_quads);
+ glTexCoord2f(0, 0); glVertex2f(200 , 300 );
+ glTexCoord2f(0, sText.h/h); glVertex2f(200 , 300 + sText.h);
+ glTexCoord2f(sText.w/w, sText.h/h); glVertex2f(200 + sText.w, 300 + sText.h);
+ glTexCoord2f(sText.w/w, 0); glVertex2f(200 + sText.w, 300 );
+ glEnd;
+ glfinish();
+ glDisable(GL_BLEND);
+ gldisable(gl_texture_2d);
+
+ SDL_FreeSurface(sText);
+ SDL_FreeSurface(intermediary);
+ glDeleteTextures(1, @texture);
+ TTF_CloseFont(font);
+
+end;
+*)
+
+
+end.
diff --git a/src/Classes/UAudioConverter.pas b/src/Classes/UAudioConverter.pas
new file mode 100644
index 00000000..5647f27b
--- /dev/null
+++ b/src/Classes/UAudioConverter.pas
@@ -0,0 +1,458 @@
+unit UAudioConverter;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMusic,
+ ULog,
+ ctypes,
+ {$IFDEF UseSRCResample}
+ samplerate,
+ {$ENDIF}
+ {$IFDEF UseFFmpegResample}
+ avcodec,
+ {$ENDIF}
+ UMediaCore_SDL,
+ sdl,
+ SysUtils,
+ Math;
+
+type
+ {*
+ * Notes:
+ * - 44.1kHz to 48kHz conversion or vice versa is not supported
+ * by SDL 1.2 (will be introduced in 1.3).
+ * No conversion takes place in this cases.
+ * This is because SDL just converts differences in powers of 2.
+ * So the result might not be that accurate.
+ * This IS audible (voice to high/low) and it needs good synchronization
+ * with the video or the lyrics timer.
+ * - float<->int16 conversion is not supported (will be part of 1.3) and
+ * SDL (<1.3) is not capable of handling floats at all.
+ * -> Using FFmpeg or libsamplerate for resampling is preferred.
+ * Use SDL for channel and format conversion only.
+ *}
+ TAudioConverter_SDL = class(TAudioConverter)
+ private
+ cvt: TSDL_AudioCVT;
+ public
+ function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
+ destructor Destroy(); override;
+
+ function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function GetOutputBufferSize(InputSize: integer): integer; override;
+ function GetRatio(): double; override;
+ end;
+
+ {$IFDEF UseFFmpegResample}
+ // Note: FFmpeg seems to be using "kaiser windowed sinc" for resampling, so
+ // the quality should be good.
+ TAudioConverter_FFmpeg = class(TAudioConverter)
+ private
+ // TODO: use SDL for multi-channel->stereo and format conversion
+ ResampleContext: PReSampleContext;
+ Ratio: double;
+ public
+ function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
+ destructor Destroy(); override;
+
+ function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function GetOutputBufferSize(InputSize: integer): integer; override;
+ function GetRatio(): double; override;
+ end;
+ {$ENDIF}
+
+ {$IFDEF UseSRCResample}
+ TAudioConverter_SRC = class(TAudioConverter)
+ private
+ ConverterState: PSRC_STATE;
+ ConversionData: SRC_DATA;
+ FormatConverter: TAudioConverter;
+ public
+ function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
+ destructor Destroy(); override;
+
+ function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function GetOutputBufferSize(InputSize: integer): integer; override;
+ function GetRatio(): double; override;
+ end;
+
+ // Note: SRC (=libsamplerate) provides several converters with different quality
+ // speed trade-offs. The SINC-types are slow but offer best quality.
+ // The SRC_SINC_* converters are too slow for realtime conversion,
+ // (SRC_SINC_FASTEST is approx. ten times slower than SRC_LINEAR) resulting
+ // in audible clicks and pops.
+ // SRC_LINEAR is very fast and should have a better quality than SRC_ZERO_ORDER_HOLD
+ // because it interpolates the samples. Normal "non-audiophile" users should not
+ // be able to hear a difference between the SINC_* ones and LINEAR. Especially
+ // if people sing along with the song.
+ // But FFmpeg might offer a better quality/speed ratio than SRC_LINEAR.
+ const
+ SRC_CONVERTER_TYPE = SRC_LINEAR;
+ {$ENDIF}
+
+implementation
+
+function TAudioConverter_SDL.Init(srcFormatInfo: TAudioFormatInfo; dstFormatInfo: TAudioFormatInfo): boolean;
+var
+ srcFormat: UInt16;
+ dstFormat: UInt16;
+begin
+ inherited Init(SrcFormatInfo, DstFormatInfo);
+
+ Result := false;
+
+ if (not ConvertAudioFormatToSDL(srcFormatInfo.Format, srcFormat) or
+ not ConvertAudioFormatToSDL(dstFormatInfo.Format, dstFormat)) then
+ begin
+ Log.LogError('Audio-format not supported by SDL', 'TSoftMixerPlaybackStream.InitFormatConversion');
+ Exit;
+ end;
+
+ if (SDL_BuildAudioCVT(@cvt,
+ srcFormat, srcFormatInfo.Channels, Round(srcFormatInfo.SampleRate),
+ dstFormat, dstFormatInfo.Channels, Round(dstFormatInfo.SampleRate)) = -1) then
+ begin
+ Log.LogError(SDL_GetError(), 'TSoftMixerPlaybackStream.InitFormatConversion');
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+destructor TAudioConverter_SDL.Destroy();
+begin
+ // nothing to be done here
+ inherited;
+end;
+
+(*
+ * Returns the size of the output buffer. This might be bigger than the actual
+ * size of resampled audio data.
+ *)
+function TAudioConverter_SDL.GetOutputBufferSize(InputSize: integer): integer;
+begin
+ // Note: len_ratio must not be used here. Even if the len_ratio is 1.0, len_mult might be 2.
+ // Example: 44.1kHz/mono to 22.05kHz/stereo -> len_ratio=1, len_mult=2
+ Result := InputSize * cvt.len_mult;
+end;
+
+function TAudioConverter_SDL.GetRatio(): double;
+begin
+ Result := cvt.len_ratio;
+end;
+
+function TAudioConverter_SDL.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+begin
+ Result := -1;
+
+ if (InputSize <= 0) then
+ begin
+ // avoid div-by-zero problems
+ if (InputSize = 0) then
+ Result := 0;
+ Exit;
+ end;
+
+ // OutputBuffer is always bigger than or equal to InputBuffer
+ Move(InputBuffer[0], OutputBuffer[0], InputSize);
+ cvt.buf := PUint8(OutputBuffer);
+ cvt.len := InputSize;
+ if (SDL_ConvertAudio(@cvt) = -1) then
+ Exit;
+
+ Result := cvt.len_cvt;
+end;
+
+
+{$IFDEF UseFFmpegResample}
+
+function TAudioConverter_FFmpeg.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
+begin
+ inherited Init(SrcFormatInfo, DstFormatInfo);
+
+ Result := false;
+
+ // Note: ffmpeg does not support resampling for more than 2 input channels
+
+ if (srcFormatInfo.Format <> asfS16) then
+ begin
+ Log.LogError('Unsupported format', 'TAudioConverter_FFmpeg.Init');
+ Exit;
+ end;
+
+ // TODO: use SDL here
+ if (srcFormatInfo.Format <> dstFormatInfo.Format) then
+ begin
+ Log.LogError('Incompatible formats', 'TAudioConverter_FFmpeg.Init');
+ Exit;
+ end;
+
+ ResampleContext := audio_resample_init(
+ dstFormatInfo.Channels, srcFormatInfo.Channels,
+ Round(dstFormatInfo.SampleRate), Round(srcFormatInfo.SampleRate));
+ if (ResampleContext = nil) then
+ begin
+ Log.LogError('audio_resample_init() failed', 'TAudioConverter_FFmpeg.Init');
+ Exit;
+ end;
+
+ // calculate ratio
+ Ratio := (dstFormatInfo.Channels / srcFormatInfo.Channels) *
+ (dstFormatInfo.SampleRate / srcFormatInfo.SampleRate);
+
+ Result := true;
+end;
+
+destructor TAudioConverter_FFmpeg.Destroy();
+begin
+ if (ResampleContext <> nil) then
+ audio_resample_close(ResampleContext);
+ inherited;
+end;
+
+function TAudioConverter_FFmpeg.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+var
+ InputSampleCount: integer;
+ OutputSampleCount: integer;
+begin
+ Result := -1;
+
+ if (InputSize <= 0) then
+ begin
+ // avoid div-by-zero in audio_resample()
+ if (InputSize = 0) then
+ Result := 0;
+ Exit;
+ end;
+
+ InputSampleCount := InputSize div SrcFormatInfo.FrameSize;
+ OutputSampleCount := audio_resample(
+ ResampleContext, PSmallInt(OutputBuffer), PSmallInt(InputBuffer),
+ InputSampleCount);
+ if (OutputSampleCount = -1) then
+ begin
+ Log.LogError('audio_resample() failed', 'TAudioConverter_FFmpeg.Convert');
+ Exit;
+ end;
+ Result := OutputSampleCount * DstFormatInfo.FrameSize;
+end;
+
+function TAudioConverter_FFmpeg.GetOutputBufferSize(InputSize: integer): integer;
+begin
+ Result := Ceil(InputSize * GetRatio());
+end;
+
+function TAudioConverter_FFmpeg.GetRatio(): double;
+begin
+ Result := Ratio;
+end;
+
+{$ENDIF}
+
+
+{$IFDEF UseSRCResample}
+
+function TAudioConverter_SRC.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
+var
+ error: integer;
+ TempSrcFormatInfo: TAudioFormatInfo;
+ TempDstFormatInfo: TAudioFormatInfo;
+begin
+ inherited Init(SrcFormatInfo, DstFormatInfo);
+
+ Result := false;
+
+ FormatConverter := nil;
+
+ // SRC does not handle channel or format conversion
+ if ((SrcFormatInfo.Channels <> DstFormatInfo.Channels) or
+ not (SrcFormatInfo.Format in [asfS16, asfFloat])) then
+ begin
+ // SDL can not convert to float, so we have to convert to SInt16 first
+ TempSrcFormatInfo := TAudioFormatInfo.Create(
+ SrcFormatInfo.Channels, SrcFormatInfo.SampleRate, SrcFormatInfo.Format);
+ TempDstFormatInfo := TAudioFormatInfo.Create(
+ DstFormatInfo.Channels, SrcFormatInfo.SampleRate, asfS16);
+
+ // init format/channel conversion
+ FormatConverter := TAudioConverter_SDL.Create();
+ if (not FormatConverter.Init(TempSrcFormatInfo, TempDstFormatInfo)) then
+ begin
+ Log.LogError('Unsupported input format', 'TAudioConverter_SRC.Init');
+ FormatConverter.Free;
+ // exit after the format-info is freed
+ end;
+
+ // this info was copied so we do not need it anymore
+ TempSrcFormatInfo.Free;
+ TempDstFormatInfo.Free;
+
+ // leave if the format is not supported
+ if (not assigned(FormatConverter)) then
+ Exit;
+
+ // adjust our copy of the input audio-format for SRC conversion
+ Self.SrcFormatInfo.Channels := DstFormatInfo.Channels;
+ Self.SrcFormatInfo.Format := asfS16;
+ end;
+
+ if ((DstFormatInfo.Format <> asfS16) and
+ (DstFormatInfo.Format <> asfFloat)) then
+ begin
+ Log.LogError('Unsupported output format', 'TAudioConverter_SRC.Init');
+ Exit;
+ end;
+
+ ConversionData.src_ratio := DstFormatInfo.SampleRate / SrcFormatInfo.SampleRate;
+ if (src_is_valid_ratio(ConversionData.src_ratio) = 0) then
+ begin
+ Log.LogError('Invalid samplerate ratio', 'TAudioConverter_SRC.Init');
+ Exit;
+ end;
+
+ ConverterState := src_new(SRC_CONVERTER_TYPE, DstFormatInfo.Channels, @error);
+ if (ConverterState = nil) then
+ begin
+ Log.LogError('src_new() failed: ' + src_strerror(error), 'TAudioConverter_SRC.Init');
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+destructor TAudioConverter_SRC.Destroy();
+begin
+ if (ConverterState <> nil) then
+ src_delete(ConverterState);
+ FormatConverter.Free;
+ inherited;
+end;
+
+function TAudioConverter_SRC.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+var
+ FloatInputBuffer: PSingle;
+ FloatOutputBuffer: PSingle;
+ TempBuffer: PChar;
+ TempSize: integer;
+ NumSamples: integer;
+ OutputSize: integer;
+ error: integer;
+begin
+ Result := -1;
+
+ TempBuffer := nil;
+
+ // format conversion with external converter (to correct number of channels and format)
+ if (assigned(FormatConverter)) then
+ begin
+ TempSize := FormatConverter.GetOutputBufferSize(InputSize);
+ GetMem(TempBuffer, TempSize);
+ InputSize := FormatConverter.Convert(InputBuffer, TempBuffer, InputSize);
+ InputBuffer := TempBuffer;
+ end;
+
+ if (InputSize <= 0) then
+ begin
+ // avoid div-by-zero problems
+ if (InputSize = 0) then
+ Result := 0;
+ if (TempBuffer <> nil) then
+ FreeMem(TempBuffer);
+ Exit;
+ end;
+
+ if (SrcFormatInfo.Format = asfFloat) then
+ begin
+ FloatInputBuffer := PSingle(InputBuffer);
+ end else begin
+ NumSamples := InputSize div AudioSampleSize[SrcFormatInfo.Format];
+ GetMem(FloatInputBuffer, NumSamples * SizeOf(Single));
+ src_short_to_float_array(PCshort(InputBuffer), PCfloat(FloatInputBuffer), NumSamples);
+ end;
+
+ // calculate approx. output size
+ OutputSize := Ceil(InputSize * ConversionData.src_ratio);
+
+ if (DstFormatInfo.Format = asfFloat) then
+ begin
+ FloatOutputBuffer := PSingle(OutputBuffer);
+ end else begin
+ NumSamples := OutputSize div AudioSampleSize[DstFormatInfo.Format];
+ GetMem(FloatOutputBuffer, NumSamples * SizeOf(Single));
+ end;
+
+ with ConversionData do
+ begin
+ data_in := PCFloat(FloatInputBuffer);
+ input_frames := InputSize div SrcFormatInfo.FrameSize;
+ data_out := PCFloat(FloatOutputBuffer);
+ output_frames := OutputSize div DstFormatInfo.FrameSize;
+ // TODO: set this to 1 at end of file-playback
+ end_of_input := 0;
+ end;
+
+ error := src_process(ConverterState, @ConversionData);
+ if (error <> 0) then
+ begin
+ Log.LogError(src_strerror(error), 'TAudioConverter_SRC.Convert');
+ if (SrcFormatInfo.Format <> asfFloat) then
+ FreeMem(FloatInputBuffer);
+ if (DstFormatInfo.Format <> asfFloat) then
+ FreeMem(FloatOutputBuffer);
+ if (TempBuffer <> nil) then
+ FreeMem(TempBuffer);
+ Exit;
+ end;
+
+ if (SrcFormatInfo.Format <> asfFloat) then
+ FreeMem(FloatInputBuffer);
+
+ if (DstFormatInfo.Format <> asfFloat) then
+ begin
+ NumSamples := ConversionData.output_frames_gen * DstFormatInfo.Channels;
+ src_float_to_short_array(PCfloat(FloatOutputBuffer), PCshort(OutputBuffer), NumSamples);
+ FreeMem(FloatOutputBuffer);
+ end;
+
+ // free format conversion buffer if used
+ if (TempBuffer <> nil) then
+ FreeMem(TempBuffer);
+
+ if (assigned(FormatConverter)) then
+ InputSize := ConversionData.input_frames_used * FormatConverter.SrcFormatInfo.FrameSize
+ else
+ InputSize := ConversionData.input_frames_used * SrcFormatInfo.FrameSize;
+
+ // set result to output size according to SRC
+ Result := ConversionData.output_frames_gen * DstFormatInfo.FrameSize;
+end;
+
+function TAudioConverter_SRC.GetOutputBufferSize(InputSize: integer): integer;
+begin
+ Result := Ceil(InputSize * GetRatio());
+end;
+
+function TAudioConverter_SRC.GetRatio(): double;
+begin
+ // if we need additional channel/format conversion, use this ratio
+ if (assigned(FormatConverter)) then
+ Result := FormatConverter.GetRatio()
+ else
+ Result := 1.0;
+
+ // now the SRC ratio (Note: the format might change from SInt16 to float)
+ Result := Result *
+ ConversionData.src_ratio *
+ (DstFormatInfo.FrameSize / SrcFormatInfo.FrameSize);
+end;
+
+{$ENDIF}
+
+end.
\ No newline at end of file
diff --git a/src/Classes/UAudioCore_Bass.pas b/src/Classes/UAudioCore_Bass.pas
new file mode 100644
index 00000000..beb2db16
--- /dev/null
+++ b/src/Classes/UAudioCore_Bass.pas
@@ -0,0 +1,123 @@
+unit UAudioCore_Bass;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes,
+ SysUtils,
+ UMusic,
+ bass; // (Note: DWORD is defined here)
+
+type
+ TAudioCore_Bass = class
+ public
+ constructor Create();
+ class function GetInstance(): TAudioCore_Bass;
+ function ErrorGetString(): string; overload;
+ function ErrorGetString(errCode: integer): string; overload;
+ function ConvertAudioFormatToBASSFlags(Format: TAudioSampleFormat; out Flags: DWORD): boolean;
+ function ConvertBASSFlagsToAudioFormat(Flags: DWORD; out Format: TAudioSampleFormat): boolean;
+ end;
+
+implementation
+
+uses
+ UMain,
+ ULog;
+
+var
+ Instance: TAudioCore_Bass;
+
+constructor TAudioCore_Bass.Create();
+begin
+ inherited;
+end;
+
+class function TAudioCore_Bass.GetInstance(): TAudioCore_Bass;
+begin
+ if (not Assigned(Instance)) then
+ Instance := TAudioCore_Bass.Create();
+ Result := Instance;
+end;
+
+function TAudioCore_Bass.ErrorGetString(): string;
+begin
+ Result := ErrorGetString(BASS_ErrorGetCode());
+end;
+
+function TAudioCore_Bass.ErrorGetString(errCode: integer): string;
+begin
+ case errCode of
+ BASS_OK: result := 'No error';
+ BASS_ERROR_MEM: result := 'Insufficient memory';
+ BASS_ERROR_FILEOPEN: result := 'File could not be opened';
+ BASS_ERROR_DRIVER: result := 'Device driver not available';
+ BASS_ERROR_BUFLOST: result := 'Buffer lost';
+ BASS_ERROR_HANDLE: result := 'Invalid Handle';
+ BASS_ERROR_FORMAT: result := 'Sample-Format not supported';
+ BASS_ERROR_POSITION: result := 'Illegal position';
+ BASS_ERROR_INIT: result := 'BASS_Init has not been successfully called';
+ BASS_ERROR_START: result := 'Paused/stopped';
+ BASS_ERROR_ALREADY: result := 'Already created/used';
+ BASS_ERROR_NOCHAN: result := 'No free channels';
+ BASS_ERROR_ILLTYPE: result := 'Type is invalid';
+ BASS_ERROR_ILLPARAM: result := 'Illegal parameter';
+ BASS_ERROR_NO3D: result := 'No 3D support';
+ BASS_ERROR_NOEAX: result := 'No EAX support';
+ BASS_ERROR_DEVICE: result := 'Invalid device number';
+ BASS_ERROR_NOPLAY: result := 'Channel not playing';
+ BASS_ERROR_FREQ: result := 'Freq out of range';
+ BASS_ERROR_NOTFILE: result := 'Not a file stream';
+ BASS_ERROR_NOHW: result := 'No hardware support';
+ BASS_ERROR_EMPTY: result := 'Is empty';
+ BASS_ERROR_NONET: result := 'Network unavailable';
+ BASS_ERROR_CREATE: result := 'Creation error';
+ BASS_ERROR_NOFX: result := 'DX8 effects unavailable';
+ BASS_ERROR_NOTAVAIL: result := 'Not available';
+ BASS_ERROR_DECODE: result := 'Is a decoding channel';
+ BASS_ERROR_DX: result := 'Insufficient version of DirectX';
+ BASS_ERROR_TIMEOUT: result := 'Timeout';
+ BASS_ERROR_FILEFORM: result := 'File-Format not recognised/supported';
+ BASS_ERROR_SPEAKER: result := 'Requested speaker(s) not support';
+ BASS_ERROR_VERSION: result := 'Version error';
+ BASS_ERROR_CODEC: result := 'Codec not available/supported';
+ BASS_ERROR_ENDED: result := 'The channel/file has ended';
+ BASS_ERROR_UNKNOWN: result := 'Unknown error';
+ else result := 'Unknown error';
+ end;
+end;
+
+function TAudioCore_Bass.ConvertAudioFormatToBASSFlags(Format: TAudioSampleFormat; out Flags: DWORD): boolean;
+begin
+ case Format of
+ asfS16: Flags := 0;
+ asfFloat: Flags := BASS_SAMPLE_FLOAT;
+ asfU8: Flags := BASS_SAMPLE_8BITS;
+ else begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ Result := true;
+end;
+
+function TAudioCore_Bass.ConvertBASSFlagsToAudioFormat(Flags: DWORD; out Format: TAudioSampleFormat): boolean;
+begin
+ if ((Flags and BASS_SAMPLE_FLOAT) <> 0) then
+ Format := asfFloat
+ else if ((Flags and BASS_SAMPLE_8BITS) <> 0) then
+ Format := asfU8
+ else
+ Format := asfS16;
+
+ Result := true;
+end;
+
+end.
diff --git a/src/Classes/UAudioCore_Portaudio.pas b/src/Classes/UAudioCore_Portaudio.pas
new file mode 100644
index 00000000..bcc8a001
--- /dev/null
+++ b/src/Classes/UAudioCore_Portaudio.pas
@@ -0,0 +1,257 @@
+unit UAudioCore_Portaudio;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I ../switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ portaudio;
+
+type
+ TAudioCore_Portaudio = class
+ public
+ constructor Create();
+ class function GetInstance(): TAudioCore_Portaudio;
+ function GetPreferredApiIndex(): TPaHostApiIndex;
+ function TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: Double): boolean;
+ end;
+
+implementation
+
+uses
+ ULog;
+
+{*
+ * The default API used by Portaudio is the least common denominator
+ * and might lack efficiency. In addition it might not even work.
+ * We use an array named ApiPreferenceOrder with which we define the order of
+ * preferred APIs to use. The first API-type in the list is tried first.
+ * If it is not available the next one is tried and so on ...
+ * If none of the preferred APIs was found the default API (detected by
+ * portaudio) is used.
+ *
+ * Pascal does not permit zero-length static arrays, so you must use paDefaultApi
+ * as an array's only member if you do not have any preferences.
+ * You can also append paDefaultApi to a non-zero length preferences array but
+ * this is optional because the default API is always used as a fallback.
+ *}
+const
+ paDefaultApi = -1;
+const
+ ApiPreferenceOrder:
+{$IF Defined(MSWINDOWS)}
+ // Note1: Portmixer has no mixer support for paASIO and paWASAPI at the moment
+ // Note2: Windows Default-API is MME, but DirectSound is faster
+ array[0..0] of TPaHostApiTypeId = ( paDirectSound );
+{$ELSEIF Defined(LINUX)}
+ // Note: Portmixer has no mixer support for JACK at the moment
+ array[0..2] of TPaHostApiTypeId = ( paALSA, paJACK, paOSS );
+{$ELSEIF Defined(DARWIN)}
+ array[0..0] of TPaHostApiTypeId = ( paDefaultApi ); // paCoreAudio
+{$ELSE}
+ array[0..0] of TPaHostApiTypeId = ( paDefaultApi );
+{$IFEND}
+
+
+{ TAudioInput_Portaudio }
+
+var
+ Instance: TAudioCore_Portaudio;
+
+constructor TAudioCore_Portaudio.Create();
+begin
+ inherited;
+end;
+
+class function TAudioCore_Portaudio.GetInstance(): TAudioCore_Portaudio;
+begin
+ if not assigned(Instance) then
+ Instance := TAudioCore_Portaudio.Create();
+ Result := Instance;
+end;
+
+function TAudioCore_Portaudio.GetPreferredApiIndex(): TPaHostApiIndex;
+var
+ i: integer;
+ apiIndex: TPaHostApiIndex;
+ apiInfo: PPaHostApiInfo;
+begin
+ result := -1;
+
+ // select preferred sound-API
+ for i:= 0 to High(ApiPreferenceOrder) do
+ begin
+ if(ApiPreferenceOrder[i] <> paDefaultApi) then
+ begin
+ // check if API is available
+ apiIndex := Pa_HostApiTypeIdToHostApiIndex(ApiPreferenceOrder[i]);
+ if(apiIndex >= 0) then
+ begin
+ // we found an API but we must check if it works
+ // (on linux portaudio might detect OSS but does not provide
+ // any devices if ALSA is enabled)
+ apiInfo := Pa_GetHostApiInfo(apiIndex);
+ if (apiInfo^.deviceCount > 0) then
+ begin
+ Result := apiIndex;
+ break;
+ end;
+ end;
+ end;
+ end;
+
+ // None of the preferred APIs is available -> use default
+ if(result < 0) then
+ begin
+ result := Pa_GetDefaultHostApi();
+ end;
+end;
+
+{*
+ * Portaudio test callback used by TestDevice().
+ *}
+function TestCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ inputDevice: Pointer): Integer; cdecl;
+begin
+ // this callback is called only once
+ result := paAbort;
+end;
+
+(*
+ * Tests if the callback works. Some devices can be opened without
+ * an error but the callback is never called. Calling Pa_StopStream() on such
+ * a stream freezes USDX then. Probably because the callback-thread is deadlocked
+ * due to some bug in portaudio. The blocking Pa_ReadStream() and Pa_WriteStream()
+ * block forever too and though can't be used for testing.
+ *
+ * To avoid freezing Pa_AbortStream (or Pa_CloseStream which calls Pa_AbortStream)
+ * can be used to force the stream to stop. But for some reason this stops debugging
+ * in gdb with a "no process found" message.
+ *
+ * Because freezing devices are non-working devices we test the devices here to
+ * be able to exclude them from the device-selection list.
+ *
+ * Portaudio does not provide any test to check this error case (probably because
+ * it should not even occur). So we have to open the device, start the stream and
+ * check if the callback is called (the stream is stopped if the callback is called
+ * for the first time, so we can poll until the stream is stopped).
+ *
+ * Another error that occurs is that some devices (even the default device) might
+ * work at the beginning but stop after a few calls (maybe 50) of the callback.
+ * For me this problem occurs with the default output-device. The "dmix" or "front"
+ * device must be selected instead. Another problem is that (due to a bug in
+ * portaudio or ALSA) the "front" device is not detected every time portaudio
+ * is started. Sometimes it needs two or more restarts.
+ *
+ * There is no reasonable way to test for these errors. For the first error-case
+ * we could test if the callback is called 50 times but this can take a second
+ * for each device and it can fail in the 51st or even 100th callback call then.
+ *
+ * The second error-case cannot be tested at all. How should we now that one
+ * device is missing if portaudio is not even able to detect it.
+ * We could start and terminate Portaudio for several times and see if the device
+ * count changes but this is ugly.
+ *
+ * Conclusion: We are not able to autodetect a working device with
+ * portaudio (at least not with the newest v19_20071207) at the moment.
+ * So we have to provide the possibility to manually select an output device
+ * in the UltraStar options if we want to use portaudio instead of SDL.
+ *)
+function TAudioCore_Portaudio.TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: Double): boolean;
+var
+ stream: PPaStream;
+ err: TPaError;
+ cbWorks: boolean;
+ cbPolls: integer;
+ i: integer;
+const
+ altSampleRates: array[0..1] of Double = (44100, 48000); // alternative sample-rates
+begin
+ Result := false;
+
+ if (sampleRate <= 0) then
+ sampleRate := 44100;
+
+ // check if device supports our input-format
+ err := Pa_IsFormatSupported(inParams, outParams, sampleRate);
+ if(err <> paNoError) then
+ begin
+ // we cannot fix the error -> exit
+ if (err <> paInvalidSampleRate) then
+ Exit;
+
+ // try alternative sample-rates to the detected one
+ sampleRate := 0;
+ for i := 0 to High(altSampleRates) do
+ begin
+ // do not check the detected sample-rate twice
+ if (altSampleRates[i] = sampleRate) then
+ continue;
+ // check alternative
+ err := Pa_IsFormatSupported(inParams, outParams, altSampleRates[i]);
+ if (err = paNoError) then
+ begin
+ // sample-rate works
+ sampleRate := altSampleRates[i];
+ break;
+ end;
+ end;
+ // no working sample-rate found
+ if (sampleRate = 0) then
+ Exit;
+ end;
+
+ // FIXME: for some reason gdb stops after a call of Pa_AbortStream()
+ // which is implicitely called by Pa_CloseStream().
+ // gdb's stops with the message: "ptrace: no process found".
+ // Probably because the callback-thread is killed what confuses gdb.
+ {$IF Defined(Debug) and Defined(Linux)}
+ cbWorks := true;
+ {$ELSE}
+ // open device for testing
+ err := Pa_OpenStream(stream, inParams, outParams, sampleRate,
+ paFramesPerBufferUnspecified,
+ paNoFlag, @TestCallback, nil);
+ if(err <> paNoError) then
+ begin
+ exit;
+ end;
+
+ // start the callback
+ err := Pa_StartStream(stream);
+ if(err <> paNoError) then
+ begin
+ Pa_CloseStream(stream);
+ exit;
+ end;
+
+ cbWorks := false;
+ // check if the callback was called (poll for max. 200ms)
+ for cbPolls := 1 to 20 do
+ begin
+ // if the test-callback was called it should be aborted now
+ if (Pa_IsStreamActive(stream) = 0) then
+ begin
+ cbWorks := true;
+ break;
+ end;
+ // not yet aborted, wait and try (poll) again
+ Pa_Sleep(10);
+ end;
+
+ // finally abort the stream
+ Pa_CloseStream(stream);
+ {$IFEND}
+
+ Result := cbWorks;
+end;
+
+end.
diff --git a/src/Classes/UAudioDecoder_Bass.pas b/src/Classes/UAudioDecoder_Bass.pas
new file mode 100644
index 00000000..dba1fde4
--- /dev/null
+++ b/src/Classes/UAudioDecoder_Bass.pas
@@ -0,0 +1,242 @@
+unit UAudioDecoder_Bass;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+implementation
+
+uses
+ Classes,
+ SysUtils,
+ UMain,
+ UMusic,
+ UAudioCore_Bass,
+ ULog,
+ bass;
+
+type
+ TBassDecodeStream = class(TAudioDecodeStream)
+ private
+ Handle: HSTREAM;
+ FormatInfo : TAudioFormatInfo;
+ Error: boolean;
+ public
+ constructor Create(Handle: HSTREAM);
+ destructor Destroy(); override;
+
+ procedure Close(); override;
+
+ function GetLength(): real; override;
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+ function GetPosition: real; override;
+ procedure SetPosition(Time: real); override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ function IsEOF(): boolean; override;
+ function IsError(): boolean; override;
+
+ function ReadData(Buffer: PChar; BufSize: integer): integer; override;
+ end;
+
+type
+ TAudioDecoder_Bass = class( TInterfacedObject, IAudioDecoder )
+ public
+ function GetName: string;
+
+ function InitializeDecoder(): boolean;
+ function FinalizeDecoder(): boolean;
+ function Open(const Filename: string): TAudioDecodeStream;
+ end;
+
+var
+ BassCore: TAudioCore_Bass;
+
+
+{ TBassDecodeStream }
+
+constructor TBassDecodeStream.Create(Handle: HSTREAM);
+var
+ ChannelInfo: BASS_CHANNELINFO;
+ Format: TAudioSampleFormat;
+begin
+ inherited Create();
+ Self.Handle := Handle;
+
+ // setup format info
+ if (not BASS_ChannelGetInfo(Handle, ChannelInfo)) then
+ begin
+ raise Exception.Create('Failed to open decode-stream');
+ end;
+ BassCore.ConvertBASSFlagsToAudioFormat(ChannelInfo.flags, Format);
+ FormatInfo := TAudioFormatInfo.Create(ChannelInfo.chans, ChannelInfo.freq, format);
+
+ Error := false;
+end;
+
+destructor TBassDecodeStream.Destroy();
+begin
+ Close();
+ inherited;
+end;
+
+procedure TBassDecodeStream.Close();
+begin
+ if (Handle <> 0) then
+ begin
+ BASS_StreamFree(Handle);
+ Handle := 0;
+ end;
+ PerformOnClose();
+ FreeAndNil(FormatInfo);
+ Error := false;
+end;
+
+function TBassDecodeStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := FormatInfo;
+end;
+
+function TBassDecodeStream.GetLength(): real;
+var
+ bytes: QWORD;
+begin
+ bytes := BASS_ChannelGetLength(Handle, BASS_POS_BYTE);
+ Result := BASS_ChannelBytes2Seconds(Handle, bytes);
+end;
+
+function TBassDecodeStream.GetPosition: real;
+var
+ bytes: QWORD;
+begin
+ bytes := BASS_ChannelGetPosition(Handle, BASS_POS_BYTE);
+ Result := BASS_ChannelBytes2Seconds(Handle, bytes);
+end;
+
+procedure TBassDecodeStream.SetPosition(Time: real);
+var
+ bytes: QWORD;
+begin
+ bytes := BASS_ChannelSeconds2Bytes(Handle, Time);
+ BASS_ChannelSetPosition(Handle, bytes, BASS_POS_BYTE);
+end;
+
+function TBassDecodeStream.GetLoop(): boolean;
+var
+ flags: DWORD;
+begin
+ // retrieve channel flags
+ flags := BASS_ChannelFlags(Handle, 0, 0);
+ if (flags = DWORD(-1)) then
+ begin
+ Log.LogError('BASS_ChannelFlags: ' + BassCore.ErrorGetString(), 'TBassDecodeStream.GetLoop');
+ Result := false;
+ Exit;
+ end;
+ Result := (flags and BASS_SAMPLE_LOOP) <> 0;
+end;
+
+procedure TBassDecodeStream.SetLoop(Enabled: boolean);
+var
+ flags: DWORD;
+begin
+ // set/unset loop-flag
+ if (Enabled) then
+ flags := BASS_SAMPLE_LOOP
+ else
+ flags := 0;
+
+ // set new flag-bits
+ if (BASS_ChannelFlags(Handle, flags, BASS_SAMPLE_LOOP) = DWORD(-1)) then
+ begin
+ Log.LogError('BASS_ChannelFlags: ' + BassCore.ErrorGetString(), 'TBassDecodeStream.SetLoop');
+ Exit;
+ end;
+end;
+
+function TBassDecodeStream.IsEOF(): boolean;
+begin
+ Result := (BASS_ChannelIsActive(Handle) = BASS_ACTIVE_STOPPED);
+end;
+
+function TBassDecodeStream.IsError(): boolean;
+begin
+ Result := Error;
+end;
+
+function TBassDecodeStream.ReadData(Buffer: PChar; BufSize: integer): integer;
+begin
+ Result := BASS_ChannelGetData(Handle, Buffer, BufSize);
+ // check error state (do not handle EOF as error)
+ if ((Result = -1) and (BASS_ErrorGetCode() <> BASS_ERROR_ENDED)) then
+ Error := true
+ else
+ Error := false;
+end;
+
+
+{ TAudioDecoder_Bass }
+
+function TAudioDecoder_Bass.GetName: String;
+begin
+ result := 'BASS_Decoder';
+end;
+
+function TAudioDecoder_Bass.InitializeDecoder(): boolean;
+begin
+ BassCore := TAudioCore_Bass.GetInstance();
+ Result := true;
+end;
+
+function TAudioDecoder_Bass.FinalizeDecoder(): boolean;
+begin
+ Result := true;
+end;
+
+function TAudioDecoder_Bass.Open(const Filename: string): TAudioDecodeStream;
+var
+ Stream: HSTREAM;
+ ChannelInfo: BASS_CHANNELINFO;
+ FileExt: string;
+begin
+ Result := nil;
+
+ // check if BASS was initialized
+ // in case the decoder is not used with BASS playback, init the NO_SOUND device
+ if ((integer(BASS_GetDevice) = -1) and (BASS_ErrorGetCode() = BASS_ERROR_INIT)) then
+ BASS_Init(0, 44100, 0, 0, nil);
+
+ // TODO: use BASS_STREAM_PRESCAN for accurate seeking in VBR-files?
+ // disadvantage: seeking will slow down.
+ Stream := BASS_StreamCreateFile(False, PChar(Filename), 0, 0, BASS_STREAM_DECODE);
+ if (Stream = 0) then
+ begin
+ //Log.LogError(BassCore.ErrorGetString(), 'TAudioDecoder_Bass.Open');
+ Exit;
+ end;
+
+ // check if BASS opened some erroneously recognized file-formats
+ if BASS_ChannelGetInfo(Stream, channelInfo) then
+ begin
+ fileExt := ExtractFileExt(Filename);
+ // BASS opens FLV-files (maybe others too) although it cannot handle them.
+ // Setting BASS_CONFIG_VERIFY to the max. value (100000) does not help.
+ if ((fileExt = '.flv') and (channelInfo.ctype = BASS_CTYPE_STREAM_MP1)) then
+ begin
+ BASS_StreamFree(Stream);
+ Exit;
+ end;
+ end;
+
+ Result := TBassDecodeStream.Create(Stream);
+end;
+
+
+initialization
+ MediaManager.Add(TAudioDecoder_Bass.Create);
+
+end.
diff --git a/src/Classes/UAudioDecoder_FFmpeg.pas b/src/Classes/UAudioDecoder_FFmpeg.pas
new file mode 100644
index 00000000..d9b4c93c
--- /dev/null
+++ b/src/Classes/UAudioDecoder_FFmpeg.pas
@@ -0,0 +1,1114 @@
+unit UAudioDecoder_FFmpeg;
+
+(*******************************************************************************
+ *
+ * This unit is primarily based upon -
+ * http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html
+ *
+ * and tutorial03.c
+ *
+ * http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
+ *
+ *******************************************************************************)
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+// show FFmpeg specific debug output
+{.$DEFINE DebugFFmpegDecode}
+
+// FFmpeg is very verbose and shows a bunch of errors.
+// Those errors (they can be considered as warnings by us) can be ignored
+// as they do not give any useful information.
+// There is no solution to fix this except for turning them off.
+{.$DEFINE EnableFFmpegErrorOutput}
+
+implementation
+
+uses
+ Classes,
+ SysUtils,
+ Math,
+ UMusic,
+ UIni,
+ UMain,
+ avcodec,
+ avformat,
+ avutil,
+ avio,
+ mathematics, // used for av_rescale_q
+ rational,
+ UMediaCore_FFmpeg,
+ SDL,
+ ULog,
+ UCommon,
+ UConfig;
+
+const
+ MAX_AUDIOQ_SIZE = (5 * 16 * 1024);
+
+const
+ // TODO: The factor 3/2 might not be necessary as we do not need extra
+ // space for synchronizing as in the tutorial.
+ AUDIO_BUFFER_SIZE = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) div 2;
+
+type
+ TFFmpegDecodeStream = class(TAudioDecodeStream)
+ private
+ StateLock: PSDL_Mutex;
+
+ EOFState: boolean; // end-of-stream flag (locked by StateLock)
+ ErrorState: boolean; // error flag (locked by StateLock)
+
+ QuitRequest: boolean; // (locked by StateLock)
+ ParserIdleCond: PSDL_Cond;
+
+ // parser pause/resume data
+ ParserLocked: boolean;
+ ParserPauseRequestCount: integer;
+ ParserUnlockedCond: PSDL_Cond;
+ ParserResumeCond: PSDL_Cond;
+
+ SeekRequest: boolean; // (locked by StateLock)
+ SeekFlags: integer; // (locked by StateLock)
+ SeekPos: double; // stream position to seek for (in secs) (locked by StateLock)
+ SeekFlush: boolean; // true if the buffers should be flushed after seeking (locked by StateLock)
+ SeekFinishedCond: PSDL_Cond;
+
+ Loop: boolean; // (locked by StateLock)
+
+ ParseThread: PSDL_Thread;
+ PacketQueue: TPacketQueue;
+
+ FormatInfo: TAudioFormatInfo;
+
+ // FFmpeg specific data
+ FormatCtx: PAVFormatContext;
+ CodecCtx: PAVCodecContext;
+ Codec: PAVCodec;
+
+ AudioStreamIndex: integer;
+ AudioStream: PAVStream;
+ AudioStreamPos: double; // stream position in seconds (locked by DecoderLock)
+
+ // decoder pause/resume data
+ DecoderLocked: boolean;
+ DecoderPauseRequestCount: integer;
+ DecoderUnlockedCond: PSDL_Cond;
+ DecoderResumeCond: PSDL_Cond;
+
+ // state-vars for DecodeFrame (locked by DecoderLock)
+ AudioPaket: TAVPacket;
+ AudioPaketData: PChar;
+ AudioPaketSize: integer;
+ AudioPaketSilence: integer; // number of bytes of silence to return
+
+ // state-vars for AudioCallback (locked by DecoderLock)
+ AudioBufferPos: integer;
+ AudioBufferSize: integer;
+ AudioBuffer: PChar;
+
+ Filename: string;
+
+ procedure SetPositionIntern(Time: real; Flush: boolean; Blocking: boolean);
+ procedure SetEOF(State: boolean); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure SetError(State: boolean); {$IFDEF HasInline}inline;{$ENDIF}
+ function IsSeeking(): boolean;
+ function IsQuit(): boolean;
+
+ procedure Reset();
+
+ procedure Parse();
+ function ParseLoop(): boolean;
+ procedure PauseParser();
+ procedure ResumeParser();
+
+ function DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
+ procedure FlushCodecBuffers();
+ procedure PauseDecoder();
+ procedure ResumeDecoder();
+ public
+ constructor Create();
+ destructor Destroy(); override;
+
+ function Open(const Filename: string): boolean;
+ procedure Close(); override;
+
+ function GetLength(): real; override;
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+ function GetPosition: real; override;
+ procedure SetPosition(Time: real); override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ function IsEOF(): boolean; override;
+ function IsError(): boolean; override;
+
+ function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ end;
+
+type
+ TAudioDecoder_FFmpeg = class( TInterfacedObject, IAudioDecoder )
+ public
+ function GetName: string;
+
+ function InitializeDecoder(): boolean;
+ function FinalizeDecoder(): boolean;
+ function Open(const Filename: string): TAudioDecodeStream;
+ end;
+
+var
+ FFmpegCore: TMediaCore_FFmpeg;
+
+function ParseThreadMain(Data: Pointer): integer; cdecl; forward;
+
+
+{ TFFmpegDecodeStream }
+
+constructor TFFmpegDecodeStream.Create();
+begin
+ inherited Create();
+
+ StateLock := SDL_CreateMutex();
+ ParserUnlockedCond := SDL_CreateCond();
+ ParserResumeCond := SDL_CreateCond();
+ ParserIdleCond := SDL_CreateCond();
+ SeekFinishedCond := SDL_CreateCond();
+ DecoderUnlockedCond := SDL_CreateCond();
+ DecoderResumeCond := SDL_CreateCond();
+
+ // according to the documentation of avcodec_decode_audio(2), sample-data
+ // should be aligned on a 16 byte boundary. Otherwise internal calls
+ // (e.g. to SSE or Altivec operations) might fail or lack performance on some
+ // CPUs. Although GetMem() in Delphi and FPC seems to use a 16 byte or higher
+ // alignment for buffers of this size (alignment depends on the size of the
+ // requested buffer), we will set the alignment explicitly as the minimum
+ // alignment used by Delphi and FPC is on an 8 byte boundary.
+ //
+ // Note: AudioBuffer was previously defined as a field of type TAudioBuffer
+ // (array[0..AUDIO_BUFFER_SIZE-1] of byte) and hence statically allocated.
+ // Fields of records are aligned different to memory allocated with GetMem(),
+ // aligning depending on the type but will be at least 2 bytes.
+ // AudioBuffer was not aligned to a 16 byte boundary. The {$ALIGN x} directive
+ // was not applicable as Delphi in contrast to FPC provides at most 8 byte
+ // alignment ({$ALIGN 16} is not supported) by this directive.
+ AudioBuffer := GetAlignedMem(AUDIO_BUFFER_SIZE, 16);
+
+ Reset();
+end;
+
+procedure TFFmpegDecodeStream.Reset();
+begin
+ ParseThread := nil;
+
+ EOFState := false;
+ ErrorState := false;
+ Loop := false;
+ QuitRequest := false;
+
+ AudioPaketData := nil;
+ AudioPaketSize := 0;
+ AudioPaketSilence := 0;
+
+ AudioBufferPos := 0;
+ AudioBufferSize := 0;
+
+ ParserLocked := false;
+ ParserPauseRequestCount := 0;
+ DecoderLocked := false;
+ DecoderPauseRequestCount := 0;
+
+ FillChar(AudioPaket, SizeOf(TAVPacket), 0);
+end;
+
+{*
+ * Frees the decode-stream data.
+ *}
+destructor TFFmpegDecodeStream.Destroy();
+begin
+ Close();
+
+ SDL_DestroyMutex(StateLock);
+ SDL_DestroyCond(ParserUnlockedCond);
+ SDL_DestroyCond(ParserResumeCond);
+ SDL_DestroyCond(ParserIdleCond);
+ SDL_DestroyCond(SeekFinishedCond);
+ SDL_DestroyCond(DecoderUnlockedCond);
+ SDL_DestroyCond(DecoderResumeCond);
+
+ FreeAlignedMem(AudioBuffer);
+
+ inherited;
+end;
+
+function TFFmpegDecodeStream.Open(const Filename: string): boolean;
+var
+ SampleFormat: TAudioSampleFormat;
+ AVResult: integer;
+begin
+ Result := false;
+
+ Close();
+ Reset();
+
+ if (not FileExists(Filename)) then
+ begin
+ Log.LogError('Audio-file does not exist: "' + Filename + '"', 'UAudio_FFmpeg');
+ Exit;
+ end;
+
+ Self.Filename := Filename;
+
+ // open audio file
+ if (av_open_input_file(FormatCtx, PChar(Filename), nil, 0, nil) <> 0) then
+ begin
+ Log.LogError('av_open_input_file failed: "' + Filename + '"', 'UAudio_FFmpeg');
+ Exit;
+ end;
+
+ // generate PTS values if they do not exist
+ FormatCtx^.flags := FormatCtx^.flags or AVFMT_FLAG_GENPTS;
+
+ // retrieve stream information
+ if (av_find_stream_info(FormatCtx) < 0) then
+ begin
+ Log.LogError('av_find_stream_info failed: "' + Filename + '"', 'UAudio_FFmpeg');
+ Close();
+ Exit;
+ end;
+
+ // FIXME: hack used by ffplay. Maybe should not use url_feof() to test for the end
+ FormatCtx^.pb.eof_reached := 0;
+
+ {$IFDEF DebugFFmpegDecode}
+ dump_format(FormatCtx, 0, pchar(Filename), 0);
+ {$ENDIF}
+
+ AudioStreamIndex := FFmpegCore.FindAudioStreamIndex(FormatCtx);
+ if (AudioStreamIndex < 0) then
+ begin
+ Log.LogError('FindAudioStreamIndex: No Audio-stream found "' + Filename + '"', 'UAudio_FFmpeg');
+ Close();
+ Exit;
+ end;
+
+ //Log.LogStatus('AudioStreamIndex is: '+ inttostr(ffmpegStreamID), 'UAudio_FFmpeg');
+
+ AudioStream := FormatCtx.streams[AudioStreamIndex];
+ CodecCtx := AudioStream^.codec;
+
+ // TODO: should we use this or not? Should we allow 5.1 channel audio?
+ (*
+ {$IF LIBAVCODEC_VERSION >= 51042000}
+ if (CodecCtx^.channels > 0) then
+ CodecCtx^.request_channels := Min(2, CodecCtx^.channels)
+ else
+ CodecCtx^.request_channels := 2;
+ {$IFEND}
+ *)
+
+ Codec := avcodec_find_decoder(CodecCtx^.codec_id);
+ if (Codec = nil) then
+ begin
+ Log.LogError('Unsupported codec!', 'UAudio_FFmpeg');
+ CodecCtx := nil;
+ Close();
+ Exit;
+ end;
+
+ // set debug options
+ CodecCtx^.debug_mv := 0;
+ CodecCtx^.debug := 0;
+
+ // detect bug-workarounds automatically
+ CodecCtx^.workaround_bugs := FF_BUG_AUTODETECT;
+ // error resilience strategy (careful/compliant/agressive/very_aggressive)
+ //CodecCtx^.error_resilience := FF_ER_CAREFUL; //FF_ER_COMPLIANT;
+ // allow non spec compliant speedup tricks.
+ //CodecCtx^.flags2 := CodecCtx^.flags2 or CODEC_FLAG2_FAST;
+
+ // Note: avcodec_open() and avcodec_close() are not thread-safe and will
+ // fail if called concurrently by different threads.
+ FFmpegCore.LockAVCodec();
+ try
+ AVResult := avcodec_open(CodecCtx, Codec);
+ finally
+ FFmpegCore.UnlockAVCodec();
+ end;
+ if (AVResult < 0) then
+ begin
+ Log.LogError('avcodec_open failed!', 'UAudio_FFmpeg');
+ Close();
+ Exit;
+ end;
+
+ // now initialize the audio-format
+
+ if (not FFmpegCore.ConvertFFmpegToAudioFormat(CodecCtx^.sample_fmt, SampleFormat)) then
+ begin
+ // try standard format
+ SampleFormat := asfS16;
+ end;
+
+ FormatInfo := TAudioFormatInfo.Create(
+ CodecCtx^.channels,
+ CodecCtx^.sample_rate,
+ SampleFormat
+ );
+
+
+ PacketQueue := TPacketQueue.Create();
+
+ // finally start the decode thread
+ ParseThread := SDL_CreateThread(@ParseThreadMain, Self);
+
+ Result := true;
+end;
+
+procedure TFFmpegDecodeStream.Close();
+var
+ ThreadResult: integer;
+begin
+ // wake threads waiting for packet-queue data
+ // Note: normally, there are no waiting threads. If there were waiting
+ // ones, they would block the audio-callback thread.
+ if (assigned(PacketQueue)) then
+ PacketQueue.Abort();
+
+ // send quit request (to parse-thread etc)
+ SDL_mutexP(StateLock);
+ QuitRequest := true;
+ SDL_CondBroadcast(ParserIdleCond);
+ SDL_mutexV(StateLock);
+
+ // abort parse-thread
+ if (ParseThread <> nil) then
+ begin
+ // and wait until it terminates
+ SDL_WaitThread(ParseThread, ThreadResult);
+ ParseThread := nil;
+ end;
+
+ // Close the codec
+ if (CodecCtx <> nil) then
+ begin
+ // avcodec_close() is not thread-safe
+ FFmpegCore.LockAVCodec();
+ try
+ avcodec_close(CodecCtx);
+ finally
+ FFmpegCore.UnlockAVCodec();
+ end;
+ CodecCtx := nil;
+ end;
+
+ // Close the video file
+ if (FormatCtx <> nil) then
+ begin
+ av_close_input_file(FormatCtx);
+ FormatCtx := nil;
+ end;
+
+ PerformOnClose();
+
+ FreeAndNil(PacketQueue);
+ FreeAndNil(FormatInfo);
+end;
+
+function TFFmpegDecodeStream.GetLength(): real;
+begin
+ // do not forget to consider the start_time value here
+ Result := (FormatCtx^.start_time + FormatCtx^.duration) / AV_TIME_BASE;
+end;
+
+function TFFmpegDecodeStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := FormatInfo;
+end;
+
+function TFFmpegDecodeStream.IsEOF(): boolean;
+begin
+ SDL_mutexP(StateLock);
+ Result := EOFState;
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.SetEOF(State: boolean);
+begin
+ SDL_mutexP(StateLock);
+ EOFState := State;
+ SDL_mutexV(StateLock);
+end;
+
+function TFFmpegDecodeStream.IsError(): boolean;
+begin
+ SDL_mutexP(StateLock);
+ Result := ErrorState;
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.SetError(State: boolean);
+begin
+ SDL_mutexP(StateLock);
+ ErrorState := State;
+ SDL_mutexV(StateLock);
+end;
+
+function TFFmpegDecodeStream.IsSeeking(): boolean;
+begin
+ SDL_mutexP(StateLock);
+ Result := SeekRequest;
+ SDL_mutexV(StateLock);
+end;
+
+function TFFmpegDecodeStream.IsQuit(): boolean;
+begin
+ SDL_mutexP(StateLock);
+ Result := QuitRequest;
+ SDL_mutexV(StateLock);
+end;
+
+function TFFmpegDecodeStream.GetPosition(): real;
+var
+ BufferSizeSec: double;
+begin
+ PauseDecoder();
+
+ // ReadData() does not return all of the buffer retrieved by DecodeFrame().
+ // Determine the size of the unused part of the decode-buffer.
+ BufferSizeSec := (AudioBufferSize - AudioBufferPos) /
+ FormatInfo.BytesPerSec;
+
+ // subtract the size of unused buffer-data from the audio clock.
+ Result := AudioStreamPos - BufferSizeSec;
+
+ ResumeDecoder();
+end;
+
+procedure TFFmpegDecodeStream.SetPosition(Time: real);
+begin
+ SetPositionIntern(Time, true, true);
+end;
+
+function TFFmpegDecodeStream.GetLoop(): boolean;
+begin
+ SDL_mutexP(StateLock);
+ Result := Loop;
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.SetLoop(Enabled: boolean);
+begin
+ SDL_mutexP(StateLock);
+ Loop := Enabled;
+ SDL_mutexV(StateLock);
+end;
+
+
+(********************************************
+ * Parser section
+ ********************************************)
+
+procedure TFFmpegDecodeStream.PauseParser();
+begin
+ if (SDL_ThreadID() = ParseThread.threadid) then
+ Exit;
+
+ SDL_mutexP(StateLock);
+ Inc(ParserPauseRequestCount);
+ while (ParserLocked) do
+ SDL_CondWait(ParserUnlockedCond, StateLock);
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.ResumeParser();
+begin
+ if (SDL_ThreadID() = ParseThread.threadid) then
+ Exit;
+
+ SDL_mutexP(StateLock);
+ Dec(ParserPauseRequestCount);
+ SDL_CondSignal(ParserResumeCond);
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.SetPositionIntern(Time: real; Flush: boolean; Blocking: boolean);
+begin
+ // - Pause the parser first to prevent it from putting obsolete packages
+ // into the queue after the queue was flushed and before seeking is done.
+ // Otherwise we will hear fragments of old data, if the stream was seeked
+ // in stopped mode and resumed afterwards (applies to non-blocking mode only).
+ // - Pause the decoder to avoid race-condition that might occur otherwise.
+ // - Last lock the state lock because we are manipulating some shared state-vars.
+ PauseParser();
+ PauseDecoder();
+ SDL_mutexP(StateLock);
+
+ // configure seek parameters
+ SeekPos := Time;
+ SeekFlush := Flush;
+ SeekFlags := AVSEEK_FLAG_ANY;
+ SeekRequest := true;
+
+ // Note: the BACKWARD-flag seeks to the first position <= the position
+ // searched for. Otherwise e.g. position 0 might not be seeked correct.
+ // For some reason ffmpeg sometimes doesn't use position 0 but the key-frame
+ // following. In streams with few key-frames (like many flv-files) the next
+ // key-frame after 0 might be 5secs ahead.
+ if (Time < AudioStreamPos) then
+ SeekFlags := SeekFlags or AVSEEK_FLAG_BACKWARD;
+
+ EOFState := false;
+ ErrorState := false;
+
+ // send a reuse signal in case the parser was stopped (e.g. because of an EOF)
+ SDL_CondSignal(ParserIdleCond);
+
+ SDL_mutexV(StateLock);
+ ResumeDecoder();
+ ResumeParser();
+
+ // in blocking mode, wait until seeking is done
+ if (Blocking) then
+ begin
+ SDL_mutexP(StateLock);
+ while (SeekRequest) do
+ SDL_CondWait(SeekFinishedCond, StateLock);
+ SDL_mutexV(StateLock);
+ end;
+end;
+
+function ParseThreadMain(Data: Pointer): integer; cdecl;
+var
+ Stream: TFFmpegDecodeStream;
+begin
+ Stream := TFFmpegDecodeStream(Data);
+ if (Stream <> nil) then
+ Stream.Parse();
+ Result := 0;
+end;
+
+procedure TFFmpegDecodeStream.Parse();
+begin
+ // reuse thread as long as the stream is not terminated
+ while (ParseLoop()) do
+ begin
+ // wait for reuse or destruction of stream
+ SDL_mutexP(StateLock);
+ while (not (SeekRequest or QuitRequest)) do
+ SDL_CondWait(ParserIdleCond, StateLock);
+ SDL_mutexV(StateLock);
+ end;
+end;
+
+(**
+ * Parser main loop.
+ * Will not return until parsing of the stream is finished.
+ * Reasons for the parser to return are:
+ * - the end-of-file is reached
+ * - an error occured
+ * - the stream was quited (received a quit-request)
+ * Returns true if the stream can be resumed or false if the stream has to
+ * be terminated.
+ *)
+function TFFmpegDecodeStream.ParseLoop(): boolean;
+var
+ Packet: TAVPacket;
+ StatusPacket: PAVPacket;
+ SeekTarget: int64;
+ ByteIOCtx: PByteIOContext;
+ ErrorCode: integer;
+ StartSilence: double; // duration of silence at start of stream
+ StartSilencePtr: PDouble; // pointer for the EMPTY status packet
+
+ // Note: pthreads wakes threads waiting on a mutex in the order of their
+ // priority and not in FIFO order. SDL does not provide any option to
+ // control priorities. This might (and already did) starve threads waiting
+ // on the mutex (e.g. SetPosition) making usdx look like it was froozen.
+ // Instead of simply locking the critical section we set a ParserLocked flag
+ // instead and give priority to the threads requesting the parser to pause.
+ procedure LockParser();
+ begin
+ SDL_mutexP(StateLock);
+ while (ParserPauseRequestCount > 0) do
+ SDL_CondWait(ParserResumeCond, StateLock);
+ ParserLocked := true;
+ SDL_mutexV(StateLock);
+ end;
+
+ procedure UnlockParser();
+ begin
+ SDL_mutexP(StateLock);
+ ParserLocked := false;
+ SDL_CondBroadcast(ParserUnlockedCond);
+ SDL_mutexV(StateLock);
+ end;
+
+begin
+ Result := true;
+
+ while (true) do
+ begin
+ LockParser();
+ try
+
+ if (IsQuit()) then
+ begin
+ Result := false;
+ Exit;
+ end;
+
+ // handle seek-request (Note: no need to lock SeekRequest here)
+ if (SeekRequest) then
+ begin
+ // first try: seek on the audio stream
+ SeekTarget := Round(SeekPos / av_q2d(AudioStream^.time_base));
+ StartSilence := 0;
+ if (SeekTarget < AudioStream^.start_time) then
+ StartSilence := (AudioStream^.start_time - SeekTarget) * av_q2d(AudioStream^.time_base);
+ ErrorCode := av_seek_frame(FormatCtx, AudioStreamIndex, SeekTarget, SeekFlags);
+
+ if (ErrorCode < 0) then
+ begin
+ // second try: seek on the default stream (necessary for flv-videos and some ogg-files)
+ SeekTarget := Round(SeekPos * AV_TIME_BASE);
+ StartSilence := 0;
+ if (SeekTarget < FormatCtx^.start_time) then
+ StartSilence := (FormatCtx^.start_time - SeekTarget) / AV_TIME_BASE;
+ ErrorCode := av_seek_frame(FormatCtx, -1, SeekTarget, SeekFlags);
+ end;
+
+ // pause decoder and lock state (keep the lock-order to avoid deadlocks).
+ // Note that the decoder does not block in the packet-queue in seeking state,
+ // so locking the decoder here does not cause a dead-lock.
+ PauseDecoder();
+ SDL_mutexP(StateLock);
+ try
+ if (ErrorCode < 0) then
+ begin
+ // seeking failed
+ ErrorState := true;
+ Log.LogStatus('Seek Error in "'+FormatCtx^.filename+'"', 'UAudioDecoder_FFmpeg');
+ end
+ else
+ begin
+ if (SeekFlush) then
+ begin
+ // flush queue (we will send a Flush-Packet when seeking is finished)
+ PacketQueue.Flush();
+
+ // flush the decode buffers
+ AudioBufferSize := 0;
+ AudioBufferPos := 0;
+ AudioPaketSize := 0;
+ AudioPaketSilence := 0;
+ FlushCodecBuffers();
+
+ // Set preliminary stream position. The position will be set to
+ // the correct value as soon as the first packet is decoded.
+ AudioStreamPos := SeekPos;
+ end
+ else
+ begin
+ // request avcodec buffer flush
+ PacketQueue.PutStatus(PKT_STATUS_FLAG_FLUSH, nil);
+ end;
+
+ // fill the gap between position 0 and start_time with silence
+ // but not if we are in loop mode
+ if ((StartSilence > 0) and (not Loop)) then
+ begin
+ GetMem(StartSilencePtr, SizeOf(StartSilence));
+ StartSilencePtr^ := StartSilence;
+ PacketQueue.PutStatus(PKT_STATUS_FLAG_EMPTY, StartSilencePtr);
+ end;
+ end;
+
+ SeekRequest := false;
+ SDL_CondBroadcast(SeekFinishedCond);
+ finally
+ SDL_mutexV(StateLock);
+ ResumeDecoder();
+ end;
+ end;
+
+ if (PacketQueue.GetSize() > MAX_AUDIOQ_SIZE) then
+ begin
+ SDL_Delay(10);
+ Continue;
+ end;
+
+ if (av_read_frame(FormatCtx, Packet) < 0) then
+ begin
+ // failed to read a frame, check reason
+ {$IF (LIBAVFORMAT_VERSION_MAJOR >= 52)}
+ ByteIOCtx := FormatCtx^.pb;
+ {$ELSE}
+ ByteIOCtx := @FormatCtx^.pb;
+ {$IFEND}
+
+ // check for end-of-file (eof is not an error)
+ if (url_feof(ByteIOCtx) <> 0) then
+ begin
+ if (GetLoop()) then
+ begin
+ // rewind stream (but do not flush)
+ SetPositionIntern(0, false, false);
+ Continue;
+ end
+ else
+ begin
+ // signal end-of-file
+ PacketQueue.PutStatus(PKT_STATUS_FLAG_EOF, nil);
+ Exit;
+ end;
+ end;
+
+ // check for errors
+ if (url_ferror(ByteIOCtx) <> 0) then
+ begin
+ // an error occured -> abort and wait for repositioning or termination
+ PacketQueue.PutStatus(PKT_STATUS_FLAG_ERROR, nil);
+ Exit;
+ end;
+
+ // no error -> wait for user input
+ SDL_Delay(100);
+ Continue;
+ end;
+
+ if (Packet.stream_index = AudioStreamIndex) then
+ PacketQueue.Put(@Packet)
+ else
+ av_free_packet(@Packet);
+
+ finally
+ UnlockParser();
+ end;
+ end;
+end;
+
+
+(********************************************
+ * Decoder section
+ ********************************************)
+
+procedure TFFmpegDecodeStream.PauseDecoder();
+begin
+ SDL_mutexP(StateLock);
+ Inc(DecoderPauseRequestCount);
+ while (DecoderLocked) do
+ SDL_CondWait(DecoderUnlockedCond, StateLock);
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.ResumeDecoder();
+begin
+ SDL_mutexP(StateLock);
+ Dec(DecoderPauseRequestCount);
+ SDL_CondSignal(DecoderResumeCond);
+ SDL_mutexV(StateLock);
+end;
+
+procedure TFFmpegDecodeStream.FlushCodecBuffers();
+begin
+ // if no flush operation is specified, avcodec_flush_buffers will not do anything.
+ if (@CodecCtx.codec.flush <> nil) then
+ begin
+ // flush buffers used by avcodec_decode_audio, etc.
+ avcodec_flush_buffers(CodecCtx);
+ end
+ else
+ begin
+ // we need a Workaround to avoid plopping noise with ogg-vorbis and
+ // mp3 (in older versions of FFmpeg).
+ // We will just reopen the codec.
+ FFmpegCore.LockAVCodec();
+ try
+ avcodec_close(CodecCtx);
+ avcodec_open(CodecCtx, Codec);
+ finally
+ FFmpegCore.UnlockAVCodec();
+ end;
+ end;
+end;
+
+function TFFmpegDecodeStream.DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
+var
+ PaketDecodedSize: integer; // size of packet data used for decoding
+ DataSize: integer; // size of output data decoded by FFmpeg
+ BlockQueue: boolean;
+ SilenceDuration: double;
+ {$IFDEF DebugFFmpegDecode}
+ TmpPos: double;
+ {$ENDIF}
+begin
+ Result := -1;
+
+ if (EOF) then
+ Exit;
+
+ while(true) do
+ begin
+ // for titles with start_time > 0 we have to generate silence
+ // until we reach the pts of the first data packet.
+ if (AudioPaketSilence > 0) then
+ begin
+ DataSize := Min(AudioPaketSilence, BufferSize);
+ FillChar(Buffer[0], DataSize, 0);
+ Dec(AudioPaketSilence, DataSize);
+ AudioStreamPos := AudioStreamPos + DataSize / FormatInfo.BytesPerSec;
+ Result := DataSize;
+ Exit;
+ end;
+
+ // read packet data
+ while (AudioPaketSize > 0) do
+ begin
+ DataSize := BufferSize;
+
+ {$IF LIBAVCODEC_VERSION >= 51030000} // 51.30.0
+ PaketDecodedSize := avcodec_decode_audio2(CodecCtx, PSmallint(Buffer),
+ DataSize, AudioPaketData, AudioPaketSize);
+ {$ELSE}
+ PaketDecodedSize := avcodec_decode_audio(CodecCtx, PSmallint(Buffer),
+ DataSize, AudioPaketData, AudioPaketSize);
+ {$IFEND}
+
+ if(PaketDecodedSize < 0) then
+ begin
+ // if error, skip frame
+ {$IFDEF DebugFFmpegDecode}
+ DebugWriteln('Skip audio frame');
+ {$ENDIF}
+ AudioPaketSize := 0;
+ Break;
+ end;
+
+ Inc(AudioPaketData, PaketDecodedSize);
+ Dec(AudioPaketSize, PaketDecodedSize);
+
+ // check if avcodec_decode_audio returned data, otherwise fetch more frames
+ if (DataSize <= 0) then
+ Continue;
+
+ // update stream position by the amount of fetched data
+ AudioStreamPos := AudioStreamPos + DataSize / FormatInfo.BytesPerSec;
+
+ // we have data, return it and come back for more later
+ Result := DataSize;
+ Exit;
+ end;
+
+ // free old packet data
+ if (AudioPaket.data <> nil) then
+ av_free_packet(@AudioPaket);
+
+ // do not block queue on seeking (to avoid deadlocks on the DecoderLock)
+ if (IsSeeking()) then
+ BlockQueue := false
+ else
+ BlockQueue := true;
+
+ // request a new packet and block if none available.
+ // If this fails, the queue was aborted.
+ if (PacketQueue.Get(AudioPaket, BlockQueue) <= 0) then
+ Exit;
+
+ // handle Status-packet
+ if (PChar(AudioPaket.data) = STATUS_PACKET) then
+ begin
+ AudioPaket.data := nil;
+ AudioPaketData := nil;
+ AudioPaketSize := 0;
+
+ case (AudioPaket.flags) of
+ PKT_STATUS_FLAG_FLUSH:
+ begin
+ // just used if SetPositionIntern was called without the flush flag.
+ FlushCodecBuffers;
+ end;
+ PKT_STATUS_FLAG_EOF: // end-of-file
+ begin
+ // ignore EOF while seeking
+ if (not IsSeeking()) then
+ SetEOF(true);
+ // buffer contains no data -> result = -1
+ Exit;
+ end;
+ PKT_STATUS_FLAG_ERROR:
+ begin
+ SetError(true);
+ Log.LogStatus('I/O Error', 'TFFmpegDecodeStream.DecodeFrame');
+ Exit;
+ end;
+ PKT_STATUS_FLAG_EMPTY:
+ begin
+ SilenceDuration := PDouble(PacketQueue.GetStatusInfo(AudioPaket))^;
+ AudioPaketSilence := Round(SilenceDuration * FormatInfo.SampleRate) * FormatInfo.FrameSize;
+ PacketQueue.FreeStatusInfo(AudioPaket);
+ end
+ else
+ begin
+ Log.LogStatus('Unknown status', 'TFFmpegDecodeStream.DecodeFrame');
+ end;
+ end;
+
+ Continue;
+ end;
+
+ AudioPaketData := PChar(AudioPaket.data);
+ AudioPaketSize := AudioPaket.size;
+
+ // if available, update the stream position to the presentation time of this package
+ if(AudioPaket.pts <> AV_NOPTS_VALUE) then
+ begin
+ {$IFDEF DebugFFmpegDecode}
+ TmpPos := AudioStreamPos;
+ {$ENDIF}
+ AudioStreamPos := av_q2d(AudioStream^.time_base) * AudioPaket.pts;
+ {$IFDEF DebugFFmpegDecode}
+ DebugWriteln('Timestamp: ' + floattostrf(AudioStreamPos, ffFixed, 15, 3) + ' ' +
+ '(Calc: ' + floattostrf(TmpPos, ffFixed, 15, 3) + '), ' +
+ 'Diff: ' + floattostrf(AudioStreamPos-TmpPos, ffFixed, 15, 3));
+ {$ENDIF}
+ end;
+ end;
+end;
+
+function TFFmpegDecodeStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+var
+ CopyByteCount: integer; // number of bytes to copy
+ RemainByteCount: integer; // number of bytes left (remain) to read
+ BufferPos: integer;
+
+ // prioritize pause requests
+ procedure LockDecoder();
+ begin
+ SDL_mutexP(StateLock);
+ while (DecoderPauseRequestCount > 0) do
+ SDL_CondWait(DecoderResumeCond, StateLock);
+ DecoderLocked := true;
+ SDL_mutexV(StateLock);
+ end;
+
+ procedure UnlockDecoder();
+ begin
+ SDL_mutexP(StateLock);
+ DecoderLocked := false;
+ SDL_CondBroadcast(DecoderUnlockedCond);
+ SDL_mutexV(StateLock);
+ end;
+
+begin
+ Result := -1;
+
+ // set number of bytes to copy to the output buffer
+ BufferPos := 0;
+
+ LockDecoder();
+ try
+ // leave if end-of-file is reached
+ if (EOF) then
+ Exit;
+
+ // copy data to output buffer
+ while (BufferPos < BufferSize) do
+ begin
+ // check if we need more data
+ if (AudioBufferPos >= AudioBufferSize) then
+ begin
+ AudioBufferPos := 0;
+
+ // we have already sent all our data; get more
+ AudioBufferSize := DecodeFrame(AudioBuffer, AUDIO_BUFFER_SIZE);
+
+ // check for errors or EOF
+ if(AudioBufferSize < 0) then
+ begin
+ Result := BufferPos;
+ Exit;
+ end;
+ end;
+
+ // calc number of new bytes in the decode-buffer
+ CopyByteCount := AudioBufferSize - AudioBufferPos;
+ // resize copy-count if more bytes available than needed (remaining bytes are used the next time)
+ RemainByteCount := BufferSize - BufferPos;
+ if (CopyByteCount > RemainByteCount) then
+ CopyByteCount := RemainByteCount;
+
+ Move(AudioBuffer[AudioBufferPos], Buffer[BufferPos], CopyByteCount);
+
+ Inc(BufferPos, CopyByteCount);
+ Inc(AudioBufferPos, CopyByteCount);
+ end;
+ finally
+ UnlockDecoder();
+ end;
+
+ Result := BufferSize;
+end;
+
+
+{ TAudioDecoder_FFmpeg }
+
+function TAudioDecoder_FFmpeg.GetName: String;
+begin
+ Result := 'FFmpeg_Decoder';
+end;
+
+function TAudioDecoder_FFmpeg.InitializeDecoder: boolean;
+begin
+ //Log.LogStatus('InitializeDecoder', 'UAudioDecoder_FFmpeg');
+ FFmpegCore := TMediaCore_FFmpeg.GetInstance();
+ av_register_all();
+
+ // Do not show uninformative error messages by default.
+ // FFmpeg prints all error-infos on the console by default what
+ // is very confusing as the playback of the files is correct.
+ // We consider these errors to be internal to FFMpeg. They can be fixed
+ // by the FFmpeg guys only and do not provide any useful information in
+ // respect to USDX.
+ {$IFNDEF EnableFFmpegErrorOutput}
+ {$IF LIBAVUTIL_VERSION_MAJOR >= 50}
+ av_log_set_level(AV_LOG_FATAL);
+ {$ELSE}
+ // FATAL and ERROR share one log-level, so we have to use QUIET
+ av_log_set_level(AV_LOG_QUIET);
+ {$IFEND}
+ {$ENDIF}
+
+ Result := true;
+end;
+
+function TAudioDecoder_FFmpeg.FinalizeDecoder(): boolean;
+begin
+ Result := true;
+end;
+
+function TAudioDecoder_FFmpeg.Open(const Filename: string): TAudioDecodeStream;
+var
+ Stream: TFFmpegDecodeStream;
+begin
+ Result := nil;
+
+ Stream := TFFmpegDecodeStream.Create();
+ if (not Stream.Open(Filename)) then
+ begin
+ Stream.Free;
+ Exit;
+ end;
+
+ Result := Stream;
+end;
+
+
+initialization
+ MediaManager.Add(TAudioDecoder_FFmpeg.Create);
+
+end.
diff --git a/src/Classes/UAudioInput_Bass.pas b/src/Classes/UAudioInput_Bass.pas
new file mode 100644
index 00000000..65a4704d
--- /dev/null
+++ b/src/Classes/UAudioInput_Bass.pas
@@ -0,0 +1,481 @@
+unit UAudioInput_Bass;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ URecord,
+ UMusic;
+
+implementation
+
+uses
+ UMain,
+ UIni,
+ ULog,
+ UAudioCore_Bass,
+ UCommon, // (Note: for MakeLong on non-windows platforms)
+ {$IFDEF MSWINDOWS}
+ Windows, // (Note: for MakeLong)
+ {$ENDIF}
+ bass; // (Note: DWORD is redefined here -> insert after Windows-unit)
+
+type
+ TAudioInput_Bass = class(TAudioInputBase)
+ private
+ function EnumDevices(): boolean;
+ public
+ function GetName: String; override;
+ function InitializeRecord: boolean; override;
+ function FinalizeRecord: boolean; override;
+ end;
+
+ TBassInputDevice = class(TAudioInputDevice)
+ private
+ RecordStream: HSTREAM;
+ BassDeviceID: DWORD; // DeviceID used by BASS
+ SingleIn: boolean;
+
+ function SetInputSource(SourceIndex: integer): boolean;
+ function GetInputSource(): integer;
+ public
+ function Open(): boolean;
+ function Close(): boolean;
+ function Start(): boolean; override;
+ function Stop(): boolean; override;
+
+ function GetVolume(): single; override;
+ procedure SetVolume(Volume: single); override;
+ end;
+
+var
+ BassCore: TAudioCore_Bass;
+
+
+{ 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; inputDevice: Pointer): boolean; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+begin
+ AudioInputProcessor.HandleMicrophoneData(buffer, len, inputDevice);
+ Result := true;
+end;
+
+
+{ TBassInputDevice }
+
+function TBassInputDevice.GetInputSource(): integer;
+var
+ SourceCnt: integer;
+ i: integer;
+ flags: DWORD;
+begin
+ // get input-source config (subtract virtual device to get BASS indices)
+ SourceCnt := Length(Source)-1;
+
+ // find source
+ Result := -1;
+ for i := 0 to SourceCnt-1 do
+ begin
+ // get input settings
+ flags := BASS_RecordGetInput(i, PSingle(nil)^);
+ if (flags = DWORD(-1)) then
+ begin
+ Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.GetInputSource');
+ Exit;
+ end;
+
+ // check if current source is selected
+ if ((flags and BASS_INPUT_OFF) = 0) then
+ begin
+ // selected source found
+ Result := i;
+ Exit;
+ end;
+ end;
+end;
+
+function TBassInputDevice.SetInputSource(SourceIndex: integer): boolean;
+var
+ SourceCnt: integer;
+ i: integer;
+ flags: DWORD;
+begin
+ Result := false;
+
+ // check for invalid source index
+ if (SourceIndex < 0) then
+ Exit;
+
+ // get input-source config (subtract virtual device to get BASS indices)
+ SourceCnt := Length(Source)-1;
+
+ // turn on selected source (turns off the others for single-in devices)
+ if (not BASS_RecordSetInput(SourceIndex, BASS_INPUT_ON, -1)) then
+ begin
+ Log.LogError('BASS_RecordSetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Start');
+ Exit;
+ end;
+
+ // turn off all other sources (not needed for single-in devices)
+ if (not SingleIn) then
+ begin
+ for i := 0 to SourceCnt-1 do
+ begin
+ if (i = SourceIndex) then
+ continue;
+ // get input settings
+ flags := BASS_RecordGetInput(i, PSingle(nil)^);
+ if (flags = DWORD(-1)) then
+ begin
+ Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString(), 'TBassInputDevice.GetInputSource');
+ Exit;
+ end;
+ // deselect source if selected
+ if ((flags and BASS_INPUT_OFF) = 0) then
+ BASS_RecordSetInput(i, BASS_INPUT_OFF, -1);
+ end;
+ end;
+
+ Result := true;
+end;
+
+function TBassInputDevice.Open(): boolean;
+var
+ FormatFlags: DWORD;
+ SourceIndex: integer;
+const
+ latency = 20; // 20ms callback period (= latency)
+begin
+ Result := false;
+
+ if (not BASS_RecordInit(BassDeviceID)) then
+ begin
+ Log.LogError('BASS_RecordInit['+Name+']: ' +
+ BassCore.ErrorGetString(), 'TBassInputDevice.Open');
+ Exit;
+ end;
+
+ if (not BassCore.ConvertAudioFormatToBASSFlags(AudioFormat.Format, FormatFlags)) then
+ begin
+ Log.LogError('Unhandled sample-format', 'TBassInputDevice.Open');
+ Exit;
+ end;
+
+ // start capturing in paused state
+ RecordStream := BASS_RecordStart(Round(AudioFormat.SampleRate), AudioFormat.Channels,
+ MakeLong(FormatFlags or BASS_RECORD_PAUSE, latency),
+ @MicrophoneCallback, Self);
+ if (RecordStream = 0) then
+ begin
+ Log.LogError('BASS_RecordStart: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Open');
+ BASS_RecordFree;
+ Exit;
+ end;
+
+ // save current source selection and select new source
+ SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
+ if (SourceIndex = -1) then
+ begin
+ // nothing to do if default source is used
+ SourceRestore := -1;
+ end
+ else
+ begin
+ // store current source-index and select new source
+ SourceRestore := GetInputSource();
+ SetInputSource(SourceIndex);
+ end;
+
+ Result := true;
+end;
+
+{* Start input-capturing on this device. *}
+function TBassInputDevice.Start(): boolean;
+begin
+ Result := false;
+
+ // recording already started -> stop first
+ if (RecordStream <> 0) then
+ Stop();
+
+ // TODO: Do not open the device here (takes too much time).
+ if not Open() then
+ Exit;
+
+ if (not BASS_ChannelPlay(RecordStream, true)) then
+ begin
+ Log.LogError('BASS_ChannelPlay: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Start');
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+{* Stop input-capturing on this device. *}
+function TBassInputDevice.Stop(): boolean;
+begin
+ Result := false;
+
+ if (RecordStream = 0) then
+ Exit;
+ if (not BASS_RecordSetDevice(BassDeviceID)) then
+ Exit;
+
+ if (not BASS_ChannelStop(RecordStream)) then
+ begin
+ Log.LogError('BASS_ChannelStop: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Stop');
+ end;
+
+ // TODO: Do not close the device here (takes too much time).
+ Result := Close();
+end;
+
+function TBassInputDevice.Close(): boolean;
+begin
+ // restore source selection
+ if (SourceRestore >= 0) then
+ begin
+ SetInputSource(SourceRestore);
+ end;
+
+ // free data
+ if (not BASS_RecordFree()) then
+ begin
+ Log.LogError('BASS_RecordFree: ' + BassCore.ErrorGetString(), 'TBassInputDevice.Close');
+ Result := false;
+ end
+ else
+ begin
+ Result := true;
+ end;
+
+ RecordStream := 0;
+end;
+
+function TBassInputDevice.GetVolume(): single;
+var
+ SourceIndex: integer;
+ lVolume: Single;
+begin
+ Result := 0;
+
+ SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
+ if (SourceIndex = -1) then
+ begin
+ // if default source used find selected source
+ SourceIndex := GetInputSource();
+ if (SourceIndex = -1) then
+ Exit;
+ end;
+
+ if (BASS_RecordGetInput(SourceIndex, lVolume) = DWORD(-1)) then
+ begin
+ Log.LogError('BASS_RecordGetInput: ' + BassCore.ErrorGetString() , 'TBassInputDevice.GetVolume');
+ Exit;
+ end;
+ Result := lVolume;
+end;
+
+procedure TBassInputDevice.SetVolume(Volume: single);
+var
+ SourceIndex: integer;
+begin
+ SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
+ if (SourceIndex = -1) then
+ begin
+ // if default source used find selected source
+ SourceIndex := GetInputSource();
+ if (SourceIndex = -1) then
+ Exit;
+ end;
+
+ // clip volume to valid range
+ if (Volume > 1.0) then
+ Volume := 1.0
+ else if (Volume < 0) then
+ Volume := 0;
+
+ if (not BASS_RecordSetInput(SourceIndex, 0, Volume)) then
+ begin
+ Log.LogError('BASS_RecordSetInput: ' + BassCore.ErrorGetString() , 'TBassInputDevice.SetVolume');
+ end;
+end;
+
+
+{ TAudioInput_Bass }
+
+function TAudioInput_Bass.GetName: String;
+begin
+ result := 'BASS_Input';
+end;
+
+function TAudioInput_Bass.EnumDevices(): boolean;
+var
+ Descr: PChar;
+ SourceName: PChar;
+ Flags: integer;
+ BassDeviceID: integer;
+ BassDevice: TBassInputDevice;
+ DeviceIndex: integer;
+ DeviceInfo: BASS_DEVICEINFO;
+ SourceIndex: integer;
+ RecordInfo: BASS_RECORDINFO;
+ SelectedSourceIndex: integer;
+begin
+ result := false;
+
+ DeviceIndex := 0;
+ BassDeviceID := 0;
+ SetLength(AudioInputProcessor.DeviceList, 0);
+
+ // checks for recording devices and puts them into an array
+ while true do
+ begin
+ if (not BASS_RecordGetDeviceInfo(BassDeviceID, DeviceInfo)) then
+ break;
+
+ // try to initialize 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.DeviceList, DeviceIndex+1);
+
+ // TODO: free object on termination
+ BassDevice := TBassInputDevice.Create();
+ AudioInputProcessor.DeviceList[DeviceIndex] := BassDevice;
+
+ Descr := DeviceInfo.name;
+
+ BassDevice.BassDeviceID := BassDeviceID;
+ BassDevice.Name := UnifyDeviceName(Descr, DeviceIndex);
+
+ // zero info-struct as some fields might not be set (e.g. freq is just set on Vista and MacOSX)
+ FillChar(RecordInfo, SizeOf(RecordInfo), 0);
+ // retrieve recording device info
+ BASS_RecordGetInfo(RecordInfo);
+
+ // 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.
+ // FIXME: does BASS use LSB/MSB or system integer values for 16bit?
+ 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;
+
+ // get info if multiple input-sources can be selected at once
+ BassDevice.SingleIn := RecordInfo.singlein;
+
+ // init list for capture buffers per channel
+ SetLength(BassDevice.CaptureChannel, BassDevice.AudioFormat.Channels);
+
+ BassDevice.MicSource := -1;
+ BassDevice.SourceRestore := -1;
+
+ // add a virtual default source (will not change mixer-settings)
+ SetLength(BassDevice.Source, 1);
+ BassDevice.Source[0].Name := DEFAULT_SOURCE_NAME;
+
+ // add real input sources
+ SourceIndex := 1;
+
+ // process each input
+ while true do
+ begin
+ SourceName := BASS_RecordGetInputName(SourceIndex-1);
+
+ {$IFDEF DARWIN}
+ // Under MacOSX the SingStar Mics have an empty InputName.
+ // So, we have to add a hard coded Workaround for this problem
+ // FIXME: - Do we need this anymore? Doesn't the (new) default source already solve this problem?
+ // - Normally a nil return value of BASS_RecordGetInputName() means end-of-list, so maybe
+ // BASS is not able to detect any mic-sources (the default source will work then).
+ // - Does BASS_RecordGetInfo() return true or false? If it returns true in this case
+ // we could use this value to check if the device exists.
+ // Please check that, eddie.
+ // If it returns false, then the source is not detected and it does not make sense to add a second
+ // fake device here.
+ // What about BASS_RecordGetInput()? Does it return a value <> -1?
+ // - Does it even work at all with this fake source-index, now that input switching works?
+ // This info was not used before (sources were never switched), so it did not matter what source-index was used.
+ // But now BASS_RecordSetInput() will probably fail.
+ if ((SourceName = nil) and (SourceIndex = 1) and (Pos('USBMIC Serial#', Descr) > 0)) then
+ SourceName := 'Microphone'
+ {$ENDIF}
+
+ if (SourceName = nil) then
+ break;
+
+ SetLength(BassDevice.Source, Length(BassDevice.Source)+1);
+ BassDevice.Source[SourceIndex].Name := SourceName;
+
+ // get input-source info
+ Flags := BASS_RecordGetInput(SourceIndex, PSingle(nil)^);
+ if (Flags <> -1) then
+ begin
+ // is the current source a mic-source?
+ if ((Flags and BASS_INPUT_TYPE_MIC) <> 0) then
+ BassDevice.MicSource := SourceIndex;
+ end;
+
+ Inc(SourceIndex);
+ end;
+
+ // FIXME: this call hangs in FPC (windows) every 2nd time USDX is called.
+ // Maybe because the sound-device was not released properly?
+ BASS_RecordFree;
+
+ Inc(DeviceIndex);
+ end;
+
+ Inc(BassDeviceID);
+ end;
+
+ result := true;
+end;
+
+function TAudioInput_Bass.InitializeRecord(): boolean;
+begin
+ BassCore := TAudioCore_Bass.GetInstance();
+ Result := EnumDevices();
+end;
+
+function TAudioInput_Bass.FinalizeRecord(): boolean;
+begin
+ CaptureStop;
+ Result := inherited FinalizeRecord;
+end;
+
+
+initialization
+ MediaManager.Add(TAudioInput_Bass.Create);
+
+end.
diff --git a/src/Classes/UAudioInput_Portaudio.pas b/src/Classes/UAudioInput_Portaudio.pas
new file mode 100644
index 00000000..9a1c3e99
--- /dev/null
+++ b/src/Classes/UAudioInput_Portaudio.pas
@@ -0,0 +1,474 @@
+unit UAudioInput_Portaudio;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I ../switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ UMusic;
+
+implementation
+
+uses
+ {$IFDEF UsePortmixer}
+ portmixer,
+ {$ENDIF}
+ portaudio,
+ UAudioCore_Portaudio,
+ URecord,
+ UIni,
+ ULog,
+ UMain;
+
+type
+ TAudioInput_Portaudio = class(TAudioInputBase)
+ private
+ AudioCore: TAudioCore_Portaudio;
+ function EnumDevices(): boolean;
+ public
+ function GetName: String; override;
+ function InitializeRecord: boolean; override;
+ function FinalizeRecord: boolean; override;
+ end;
+
+ TPortaudioInputDevice = class(TAudioInputDevice)
+ private
+ RecordStream: PPaStream;
+ {$IFDEF UsePortmixer}
+ Mixer: PPxMixer;
+ {$ENDIF}
+ PaDeviceIndex: TPaDeviceIndex;
+ public
+ function Open(): boolean;
+ function Close(): boolean;
+ function Start(): boolean; override;
+ function Stop(): boolean; override;
+
+ function GetVolume(): single; override;
+ procedure SetVolume(Volume: single); override;
+ end;
+
+function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ inputDevice: Pointer): Integer; cdecl; forward;
+
+function MicrophoneTestCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ inputDevice: Pointer): Integer; cdecl; forward;
+
+
+{ TPortaudioInputDevice }
+
+function TPortaudioInputDevice.Open(): boolean;
+var
+ Error: TPaError;
+ inputParams: TPaStreamParameters;
+ deviceInfo: PPaDeviceInfo;
+ SourceIndex: integer;
+begin
+ Result := false;
+
+ // get input latency info
+ deviceInfo := Pa_GetDeviceInfo(PaDeviceIndex);
+
+ // set input stream parameters
+ with inputParams do
+ begin
+ device := PaDeviceIndex;
+ channelCount := AudioFormat.Channels;
+ sampleFormat := paInt16;
+ suggestedLatency := deviceInfo^.defaultLowInputLatency;
+ hostApiSpecificStreamInfo := nil;
+ end;
+
+ //Log.LogStatus(deviceInfo^.name, 'Portaudio');
+ //Log.LogStatus(floattostr(deviceInfo^.defaultLowInputLatency), 'Portaudio');
+
+ // open input stream
+ Error := Pa_OpenStream(RecordStream, @inputParams, nil,
+ AudioFormat.SampleRate,
+ paFramesPerBufferUnspecified, paNoFlag,
+ @MicrophoneCallback, Pointer(Self));
+ if(Error <> paNoError) then
+ begin
+ Log.LogError('Error opening stream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Open');
+ Exit;
+ end;
+
+ {$IFDEF UsePortmixer}
+ // open default mixer
+ Mixer := Px_OpenMixer(RecordStream, 0);
+ if (Mixer = nil) then
+ begin
+ Log.LogError('Error opening mixer: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Open');
+ end
+ else
+ begin
+ // save current source selection and select new source
+ SourceIndex := Ini.InputDeviceConfig[CfgIndex].Input-1;
+ if (SourceIndex = -1) then
+ begin
+ // nothing to do if default source is used
+ SourceRestore := -1;
+ end
+ else
+ begin
+ // store current source-index and select new source
+ SourceRestore := Px_GetCurrentInputSource(Mixer); // -1 in error case
+ Px_SetCurrentInputSource(Mixer, SourceIndex);
+ end;
+ end;
+ {$ENDIF}
+
+ Result := true;
+end;
+
+function TPortaudioInputDevice.Start(): boolean;
+var
+ Error: TPaError;
+begin
+ Result := false;
+
+ // recording already started -> stop first
+ if (RecordStream <> nil) then
+ Stop();
+
+ // TODO: Do not open the device here (takes too much time).
+ if (not Open()) then
+ Exit;
+
+ // start capture
+ Error := Pa_StartStream(RecordStream);
+ if(Error <> paNoError) then
+ begin
+ Log.LogError('Error starting stream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Start');
+ Close();
+ RecordStream := nil;
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+function TPortaudioInputDevice.Stop(): boolean;
+var
+ Error: TPaError;
+begin
+ Result := false;
+
+ if (RecordStream = nil) then
+ Exit;
+
+ // Note: do NOT call Pa_StopStream here!
+ // It gets stuck on devices with non-working callback as Pa_StopStream
+ // waits until all buffers have been handled (which never occurs in that case).
+ Error := Pa_AbortStream(RecordStream);
+ if (Error <> paNoError) then
+ begin
+ Log.LogError('Pa_AbortStream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Stop');
+ end;
+
+ Result := Close();
+end;
+
+function TPortaudioInputDevice.Close(): boolean;
+var
+ Error: TPaError;
+begin
+ {$IFDEF UsePortmixer}
+ if (Mixer <> nil) then
+ begin
+ // restore source selection
+ if (SourceRestore >= 0) then
+ begin
+ Px_SetCurrentInputSource(Mixer, SourceRestore);
+ end;
+
+ // close mixer
+ Px_CloseMixer(Mixer);
+ Mixer := nil;
+ end;
+ {$ENDIF}
+
+ Error := Pa_CloseStream(RecordStream);
+ if (Error <> paNoError) then
+ begin
+ Log.LogError('Pa_CloseStream: ' + Pa_GetErrorText(Error), 'TPortaudioInputDevice.Close');
+ Result := false;
+ end
+ else
+ begin
+ Result := true;
+ end;
+
+ RecordStream := nil;
+end;
+
+function TPortaudioInputDevice.GetVolume(): single;
+begin
+ Result := 0;
+ {$IFDEF UsePortmixer}
+ if (Mixer <> nil) then
+ Result := Px_GetInputVolume(Mixer);
+ {$ENDIF}
+end;
+
+procedure TPortaudioInputDevice.SetVolume(Volume: single);
+begin
+ {$IFDEF UsePortmixer}
+ if (Mixer <> nil) then
+ begin
+ // clip to valid range
+ if (Volume > 1.0) then
+ Volume := 1.0
+ else if (Volume < 0) then
+ Volume := 0;
+ Px_SetInputVolume(Mixer, Volume);
+ end;
+ {$ENDIF}
+end;
+
+
+{ TAudioInput_Portaudio }
+
+function TAudioInput_Portaudio.GetName: String;
+begin
+ result := 'Portaudio';
+end;
+
+function TAudioInput_Portaudio.EnumDevices(): boolean;
+var
+ i: integer;
+ paApiIndex: TPaHostApiIndex;
+ paApiInfo: PPaHostApiInfo;
+ deviceName: string;
+ deviceIndex: TPaDeviceIndex;
+ deviceInfo: PPaDeviceInfo;
+ channelCnt: integer;
+ SC: integer; // soundcard
+ err: TPaError;
+ errMsg: string;
+ paDevice: TPortaudioInputDevice;
+ inputParams: TPaStreamParameters;
+ stream: PPaStream;
+ streamInfo: PPaStreamInfo;
+ sampleRate: double;
+ latency: TPaTime;
+ {$IFDEF UsePortmixer}
+ mixer: PPxMixer;
+ sourceCnt: integer;
+ sourceIndex: integer;
+ sourceName: string;
+ {$ENDIF}
+ cbPolls: integer;
+ cbWorks: boolean;
+begin
+ Result := false;
+
+ // choose the best available Audio-API
+ paApiIndex := AudioCore.GetPreferredApiIndex();
+ if(paApiIndex = -1) then
+ begin
+ Log.LogError('No working Audio-API found', 'TAudioInput_Portaudio.EnumDevices');
+ Exit;
+ end;
+
+ paApiInfo := Pa_GetHostApiInfo(paApiIndex);
+
+ SC := 0;
+
+ // init array-size to max. input-devices count
+ SetLength(AudioInputProcessor.DeviceList, paApiInfo^.deviceCount);
+ for i:= 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ // convert API-specific device-index to global index
+ deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
+ deviceInfo := Pa_GetDeviceInfo(deviceIndex);
+
+ channelCnt := deviceInfo^.maxInputChannels;
+
+ // current device is no input device -> skip
+ if (channelCnt <= 0) then
+ continue;
+
+ // portaudio returns a channel-count of 128 for some devices
+ // (e.g. the "default"-device), so we have to detect those
+ // fantasy channel counts.
+ if (channelCnt > 8) then
+ channelCnt := 2;
+
+ paDevice := TPortaudioInputDevice.Create();
+ AudioInputProcessor.DeviceList[SC] := paDevice;
+
+ // retrieve device-name
+ deviceName := deviceInfo^.name;
+ paDevice.Name := deviceName;
+ paDevice.PaDeviceIndex := deviceIndex;
+
+ sampleRate := deviceInfo^.defaultSampleRate;
+
+ // on vista and xp the defaultLowInputLatency may be set to 0 but it works.
+ // TODO: correct too low latencies (what is a too low latency, maybe < 10ms?)
+ latency := deviceInfo^.defaultLowInputLatency;
+
+ // setup desired input parameters
+ // TODO: retry with input-latency set to 20ms (defaultLowInputLatency might
+ // not be set correctly in OSS)
+ with inputParams do
+ begin
+ device := deviceIndex;
+ channelCount := channelCnt;
+ sampleFormat := paInt16;
+ suggestedLatency := latency;
+ hostApiSpecificStreamInfo := nil;
+ end;
+
+ // check souncard and adjust sample-rate
+ if (not AudioCore.TestDevice(@inputParams, nil, sampleRate)) then
+ begin
+ // ignore device if it does not work
+ Log.LogError('Device "'+paDevice.Name+'" does not work',
+ 'TAudioInput_Portaudio.EnumDevices');
+ paDevice.Free();
+ continue;
+ end;
+
+ // open device for further info
+ err := Pa_OpenStream(stream, @inputParams, nil, sampleRate,
+ paFramesPerBufferUnspecified, paNoFlag, @MicrophoneTestCallback, nil);
+ if(err <> paNoError) then
+ begin
+ // unable to open device -> skip
+ errMsg := Pa_GetErrorText(err);
+ Log.LogError('Device error: "'+ deviceName +'" ('+ errMsg +')',
+ 'TAudioInput_Portaudio.EnumDevices');
+ paDevice.Free();
+ continue;
+ end;
+
+ // adjust sample-rate (might be changed by portaudio)
+ streamInfo := Pa_GetStreamInfo(stream);
+ if (streamInfo <> nil) then
+ begin
+ if (sampleRate <> streamInfo^.sampleRate) then
+ begin
+ Log.LogStatus('Portaudio changed Samplerate from ' + FloatToStr(sampleRate) +
+ ' to ' + FloatToStr(streamInfo^.sampleRate),
+ 'TAudioInput_Portaudio.InitializeRecord');
+ sampleRate := streamInfo^.sampleRate;
+ end;
+ end;
+
+ // create audio-format info and resize capture-buffer array
+ paDevice.AudioFormat := TAudioFormatInfo.Create(
+ channelCnt,
+ sampleRate,
+ asfS16
+ );
+ SetLength(paDevice.CaptureChannel, paDevice.AudioFormat.Channels);
+
+ Log.LogStatus('InputDevice "'+paDevice.Name+'"@' +
+ IntToStr(paDevice.AudioFormat.Channels)+'x'+
+ FloatToStr(paDevice.AudioFormat.SampleRate)+'Hz ('+
+ FloatTostr(inputParams.suggestedLatency)+'sec)' ,
+ 'Portaudio.EnumDevices');
+
+ // portaudio does not provide a source-type check
+ paDevice.MicSource := -1;
+ paDevice.SourceRestore := -1;
+
+ // add a virtual default source (will not change mixer-settings)
+ SetLength(paDevice.Source, 1);
+ paDevice.Source[0].Name := DEFAULT_SOURCE_NAME;
+
+ {$IFDEF UsePortmixer}
+ // use default mixer
+ mixer := Px_OpenMixer(stream, 0);
+
+ // get input count
+ sourceCnt := Px_GetNumInputSources(mixer);
+ SetLength(paDevice.Source, sourceCnt+1);
+
+ // get input names
+ for sourceIndex := 1 to sourceCnt do
+ begin
+ sourceName := Px_GetInputSourceName(mixer, sourceIndex-1);
+ paDevice.Source[sourceIndex].Name := sourceName;
+ end;
+
+ Px_CloseMixer(mixer);
+ {$ENDIF}
+
+ // close test-stream
+ Pa_CloseStream(stream);
+
+ Inc(SC);
+ end;
+
+ // adjust size to actual input-device count
+ SetLength(AudioInputProcessor.DeviceList, SC);
+
+ Log.LogStatus('#Input-Devices: ' + inttostr(SC), 'Portaudio');
+
+ Result := true;
+end;
+
+function TAudioInput_Portaudio.InitializeRecord(): boolean;
+var
+ err: TPaError;
+begin
+ AudioCore := TAudioCore_Portaudio.GetInstance();
+
+ // initialize portaudio
+ err := Pa_Initialize();
+ if(err <> paNoError) then
+ begin
+ Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord');
+ Result := false;
+ Exit;
+ end;
+
+ Result := EnumDevices();
+end;
+
+function TAudioInput_Portaudio.FinalizeRecord: boolean;
+begin
+ CaptureStop;
+ Pa_Terminate();
+ Result := inherited FinalizeRecord();
+end;
+
+{*
+ * Portaudio input capture callback.
+ *}
+function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ inputDevice: Pointer): Integer; cdecl;
+begin
+ AudioInputProcessor.HandleMicrophoneData(input, frameCount*4, inputDevice);
+ result := paContinue;
+end;
+
+{*
+ * Portaudio test capture callback.
+ *}
+function MicrophoneTestCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ inputDevice: Pointer): Integer; cdecl;
+begin
+ // this callback is called only once
+ result := paAbort;
+end;
+
+
+initialization
+ MediaManager.add(TAudioInput_Portaudio.Create);
+
+end.
diff --git a/src/Classes/UAudioPlaybackBase.pas b/src/Classes/UAudioPlaybackBase.pas
new file mode 100644
index 00000000..2337d43f
--- /dev/null
+++ b/src/Classes/UAudioPlaybackBase.pas
@@ -0,0 +1,292 @@
+unit UAudioPlaybackBase;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMusic;
+
+type
+ TAudioPlaybackBase = class(TInterfacedObject, IAudioPlayback)
+ protected
+ OutputDeviceList: TAudioOutputDeviceList;
+ MusicStream: TAudioPlaybackStream;
+ function CreatePlaybackStream(): TAudioPlaybackStream; virtual; abstract;
+ procedure ClearOutputDeviceList();
+ function GetLatency(): double; virtual; abstract;
+
+ // open sound or music stream (used by Open() and OpenSound())
+ function OpenStream(const Filename: string): TAudioPlaybackStream;
+ function OpenDecodeStream(const Filename: string): TAudioDecodeStream;
+ public
+ function GetName: string; virtual; abstract;
+
+ function Open(const Filename: string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+ procedure FadeIn(Time: real; TargetVolume: single);
+
+ procedure SetSyncSource(SyncSource: TSyncSource);
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ function InitializePlayback: boolean; virtual; abstract;
+ function FinalizePlayback: boolean; virtual;
+
+ //function SetOutputDevice(Device: TAudioOutputDevice): boolean;
+ function GetOutputDeviceList(): TAudioOutputDeviceList;
+
+ procedure SetAppVolume(Volume: single); virtual; abstract;
+ procedure SetVolume(Volume: single);
+ procedure SetLoop(Enabled: boolean);
+
+ procedure Rewind;
+ function Finished: boolean;
+ function Length: real;
+
+ // Sounds
+ function OpenSound(const Filename: string): TAudioPlaybackStream;
+ procedure PlaySound(Stream: TAudioPlaybackStream);
+ procedure StopSound(Stream: TAudioPlaybackStream);
+
+ // Equalizer
+ procedure GetFFTData(var Data: TFFTData);
+
+ // Interface for Visualizer
+ function GetPCMData(var Data: TPCMData): Cardinal;
+
+ function CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; virtual; abstract;
+ end;
+
+
+implementation
+
+uses
+ ULog,
+ SysUtils;
+
+{ TAudioPlaybackBase }
+
+function TAudioPlaybackBase.FinalizePlayback: boolean;
+begin
+ FreeAndNil(MusicStream);
+ ClearOutputDeviceList();
+ Result := true;
+end;
+
+function TAudioPlaybackBase.Open(const Filename: string): boolean;
+begin
+ // free old MusicStream
+ MusicStream.Free;
+
+ MusicStream := OpenStream(Filename);
+ if not assigned(MusicStream) then
+ begin
+ Result := false;
+ Exit;
+ end;
+
+ //MusicStream.AddSoundEffect(TVoiceRemoval.Create());
+
+ Result := true;
+end;
+
+procedure TAudioPlaybackBase.Close;
+begin
+ FreeAndNil(MusicStream);
+end;
+
+function TAudioPlaybackBase.OpenDecodeStream(const Filename: String): TAudioDecodeStream;
+var
+ i: integer;
+begin
+ for i := 0 to AudioDecoders.Count-1 do
+ begin
+ Result := IAudioDecoder(AudioDecoders[i]).Open(Filename);
+ if (assigned(Result)) then
+ begin
+ Log.LogInfo('Using decoder ' + IAudioDecoder(AudioDecoders[i]).GetName() +
+ ' for "' + Filename + '"', 'TAudioPlaybackBase.OpenDecodeStream');
+ Exit;
+ end;
+ end;
+ Result := nil;
+end;
+
+procedure OnClosePlaybackStream(Stream: TAudioProcessingStream);
+var
+ PlaybackStream: TAudioPlaybackStream;
+ SourceStream: TAudioSourceStream;
+begin
+ PlaybackStream := TAudioPlaybackStream(Stream);
+ SourceStream := PlaybackStream.GetSourceStream();
+ SourceStream.Free;
+end;
+
+function TAudioPlaybackBase.OpenStream(const Filename: string): TAudioPlaybackStream;
+var
+ PlaybackStream: TAudioPlaybackStream;
+ DecodeStream: TAudioDecodeStream;
+begin
+ Result := nil;
+
+ //Log.LogStatus('Loading Sound: "' + Filename + '"', 'TAudioPlayback_Bass.OpenStream');
+
+ DecodeStream := OpenDecodeStream(Filename);
+ if (not assigned(DecodeStream)) then
+ begin
+ Log.LogStatus('Could not open "' + Filename + '"', 'TAudioPlayback_Bass.OpenStream');
+ Exit;
+ end;
+
+ // create a matching playback-stream for the decoder
+ PlaybackStream := CreatePlaybackStream();
+ if (not PlaybackStream.Open(DecodeStream)) then
+ begin
+ FreeAndNil(PlaybackStream);
+ FreeAndNil(DecodeStream);
+ Exit;
+ end;
+
+ PlaybackStream.AddOnCloseHandler(OnClosePlaybackStream);
+
+ Result := PlaybackStream;
+end;
+
+procedure TAudioPlaybackBase.Play;
+begin
+ if assigned(MusicStream) then
+ MusicStream.Play();
+end;
+
+procedure TAudioPlaybackBase.Pause;
+begin
+ if assigned(MusicStream) then
+ MusicStream.Pause();
+end;
+
+procedure TAudioPlaybackBase.Stop;
+begin
+ if assigned(MusicStream) then
+ MusicStream.Stop();
+end;
+
+function TAudioPlaybackBase.Length: real;
+begin
+ if assigned(MusicStream) then
+ Result := MusicStream.Length
+ else
+ Result := 0;
+end;
+
+function TAudioPlaybackBase.GetPosition: real;
+begin
+ if assigned(MusicStream) then
+ Result := MusicStream.Position
+ else
+ Result := 0;
+end;
+
+procedure TAudioPlaybackBase.SetPosition(Time: real);
+begin
+ if assigned(MusicStream) then
+ MusicStream.Position := Time;
+end;
+
+procedure TAudioPlaybackBase.SetSyncSource(SyncSource: TSyncSource);
+begin
+ if assigned(MusicStream) then
+ MusicStream.SetSyncSource(SyncSource);
+end;
+
+procedure TAudioPlaybackBase.Rewind;
+begin
+ SetPosition(0);
+end;
+
+function TAudioPlaybackBase.Finished: boolean;
+begin
+ if assigned(MusicStream) then
+ Result := (MusicStream.Status = ssStopped)
+ else
+ Result := true;
+end;
+
+procedure TAudioPlaybackBase.SetVolume(Volume: single);
+begin
+ if assigned(MusicStream) then
+ MusicStream.Volume := Volume;
+end;
+
+procedure TAudioPlaybackBase.FadeIn(Time: real; TargetVolume: single);
+begin
+ if assigned(MusicStream) then
+ MusicStream.FadeIn(Time, TargetVolume);
+end;
+
+procedure TAudioPlaybackBase.SetLoop(Enabled: boolean);
+begin
+ if assigned(MusicStream) then
+ MusicStream.Loop := Enabled;
+end;
+
+// Equalizer
+procedure TAudioPlaybackBase.GetFFTData(var data: TFFTData);
+begin
+ if assigned(MusicStream) then
+ MusicStream.GetFFTData(data);
+end;
+
+{*
+ * Copies interleaved PCM SInt16 stereo samples into data.
+ * Returns the number of frames
+ *}
+function TAudioPlaybackBase.GetPCMData(var data: TPCMData): Cardinal;
+begin
+ if assigned(MusicStream) then
+ Result := MusicStream.GetPCMData(data)
+ else
+ Result := 0;
+end;
+
+function TAudioPlaybackBase.OpenSound(const Filename: string): TAudioPlaybackStream;
+begin
+ Result := OpenStream(Filename);
+end;
+
+procedure TAudioPlaybackBase.PlaySound(stream: TAudioPlaybackStream);
+begin
+ if assigned(stream) then
+ stream.Play();
+end;
+
+procedure TAudioPlaybackBase.StopSound(stream: TAudioPlaybackStream);
+begin
+ if assigned(stream) then
+ stream.Stop();
+end;
+
+procedure TAudioPlaybackBase.ClearOutputDeviceList();
+var
+ DeviceIndex: integer;
+begin
+ for DeviceIndex := 0 to High(OutputDeviceList) do
+ OutputDeviceList[DeviceIndex].Free();
+ SetLength(OutputDeviceList, 0);
+end;
+
+function TAudioPlaybackBase.GetOutputDeviceList(): TAudioOutputDeviceList;
+begin
+ Result := OutputDeviceList;
+end;
+
+end.
diff --git a/src/Classes/UAudioPlayback_Bass.pas b/src/Classes/UAudioPlayback_Bass.pas
new file mode 100644
index 00000000..41a91173
--- /dev/null
+++ b/src/Classes/UAudioPlayback_Bass.pas
@@ -0,0 +1,731 @@
+unit UAudioPlayback_Bass;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+implementation
+
+uses
+ Classes,
+ SysUtils,
+ Math,
+ UIni,
+ UMain,
+ UMusic,
+ UAudioPlaybackBase,
+ UAudioCore_Bass,
+ ULog,
+ sdl,
+ bass;
+
+type
+ PHDSP = ^HDSP;
+
+type
+ TBassPlaybackStream = class(TAudioPlaybackStream)
+ private
+ Handle: HSTREAM;
+ NeedsRewind: boolean;
+ PausedSeek: boolean; // true if a seek was performed in pause state
+
+ procedure Reset();
+ function IsEOF(): boolean;
+ protected
+ function GetLatency(): double; override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ function GetLength(): real; override;
+ function GetStatus(): TStreamStatus; override;
+ function GetVolume(): single; override;
+ procedure SetVolume(Volume: single); override;
+ function GetPosition: real; override;
+ procedure SetPosition(Time: real); override;
+ public
+ constructor Create();
+ destructor Destroy(); override;
+
+ function Open(SourceStream: TAudioSourceStream): boolean; override;
+ procedure Close(); override;
+
+ procedure Play(); override;
+ procedure Pause(); override;
+ procedure Stop(); override;
+ procedure FadeIn(Time: real; TargetVolume: single); override;
+
+ procedure AddSoundEffect(Effect: TSoundEffect); override;
+ procedure RemoveSoundEffect(Effect: TSoundEffect); override;
+
+ procedure GetFFTData(var Data: TFFTData); override;
+ function GetPCMData(var Data: TPCMData): Cardinal; override;
+
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+
+ function ReadData(Buffer: PChar; BufferSize: integer): integer;
+
+ property EOF: boolean READ IsEOF;
+ end;
+
+const
+ MAX_VOICE_DELAY = 0.020; // 20ms
+
+type
+ TBassVoiceStream = class(TAudioVoiceStream)
+ private
+ Handle: HSTREAM;
+ public
+ function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
+ procedure Close(); override;
+
+ procedure WriteData(Buffer: PChar; BufferSize: integer); override;
+ function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ function IsEOF(): boolean; override;
+ function IsError(): boolean; override;
+ end;
+
+type
+ TAudioPlayback_Bass = class(TAudioPlaybackBase)
+ private
+ function EnumDevices(): boolean;
+ protected
+ function GetLatency(): double; override;
+ function CreatePlaybackStream(): TAudioPlaybackStream; override;
+ public
+ function GetName: String; override;
+ function InitializePlayback(): boolean; override;
+ function FinalizePlayback: boolean; override;
+ procedure SetAppVolume(Volume: single); override;
+ function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; override;
+ end;
+
+ TBassOutputDevice = class(TAudioOutputDevice)
+ private
+ BassDeviceID: DWORD; // DeviceID used by BASS
+ end;
+
+var
+ BassCore: TAudioCore_Bass;
+
+
+{ TBassPlaybackStream }
+
+function PlaybackStreamHandler(handle: HSTREAM; buffer: Pointer; length: DWORD; user: Pointer): DWORD;
+{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+var
+ PlaybackStream: TBassPlaybackStream;
+ BytesRead: integer;
+begin
+ PlaybackStream := TBassPlaybackStream(user);
+ if (not assigned (PlaybackStream)) then
+ begin
+ Result := BASS_STREAMPROC_END;
+ Exit;
+ end;
+
+ BytesRead := PlaybackStream.ReadData(buffer, length);
+ // check for errors
+ if (BytesRead < 0) then
+ Result := BASS_STREAMPROC_END
+ // check for EOF
+ else if (PlaybackStream.EOF) then
+ Result := BytesRead or BASS_STREAMPROC_END
+ // no error/EOF
+ else
+ Result := BytesRead;
+end;
+
+function TBassPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+var
+ AdjustedSize: integer;
+ RequestedSourceSize, SourceSize: integer;
+ SkipCount: integer;
+ SourceFormatInfo: TAudioFormatInfo;
+ FrameSize: integer;
+ PadFrame: PChar;
+ //Info: BASS_INFO;
+ //Latency: double;
+begin
+ Result := -1;
+
+ if (not assigned(SourceStream)) then
+ Exit;
+
+ // sanity check
+ if (BufferSize = 0) then
+ begin
+ Result := 0;
+ Exit;
+ end;
+
+ SourceFormatInfo := SourceStream.GetAudioFormatInfo();
+ FrameSize := SourceFormatInfo.FrameSize;
+
+ // check how much data to fetch to be in synch
+ AdjustedSize := Synchronize(BufferSize, SourceFormatInfo);
+
+ // skip data if we are too far behind
+ SkipCount := AdjustedSize - BufferSize;
+ while (SkipCount > 0) do
+ begin
+ RequestedSourceSize := Min(SkipCount, BufferSize);
+ SourceSize := SourceStream.ReadData(Buffer, RequestedSourceSize);
+ // if an error or EOF occured stop skipping and handle error/EOF with the next ReadData()
+ if (SourceSize <= 0) then
+ break;
+ Dec(SkipCount, SourceSize);
+ end;
+
+ // get source data (e.g. from a decoder)
+ RequestedSourceSize := Min(AdjustedSize, BufferSize);
+ SourceSize := SourceStream.ReadData(Buffer, RequestedSourceSize);
+ if (SourceSize < 0) then
+ Exit;
+
+ // set preliminary result
+ Result := SourceSize;
+
+ // if we are to far ahead, fill output-buffer with last frame of source data
+ // Note that AdjustedSize is used instead of SourceSize as the SourceSize might
+ // be less than expected because of errors etc.
+ if (AdjustedSize < BufferSize) then
+ begin
+ // use either the last frame for padding or fill with zero
+ if (SourceSize >= FrameSize) then
+ PadFrame := @Buffer[SourceSize-FrameSize]
+ else
+ PadFrame := nil;
+
+ FillBufferWithFrame(@Buffer[SourceSize], BufferSize - SourceSize,
+ PadFrame, FrameSize);
+ Result := BufferSize;
+ end;
+end;
+
+constructor TBassPlaybackStream.Create();
+begin
+ inherited;
+ Reset();
+end;
+
+destructor TBassPlaybackStream.Destroy();
+begin
+ Close();
+ inherited;
+end;
+
+function TBassPlaybackStream.Open(SourceStream: TAudioSourceStream): boolean;
+var
+ FormatInfo: TAudioFormatInfo;
+ FormatFlags: DWORD;
+begin
+ Result := false;
+
+ // close previous stream and reset state
+ Reset();
+
+ // sanity check if stream is valid
+ if not assigned(SourceStream) then
+ Exit;
+
+ Self.SourceStream := SourceStream;
+ FormatInfo := SourceStream.GetAudioFormatInfo();
+ if (not BassCore.ConvertAudioFormatToBASSFlags(FormatInfo.Format, FormatFlags)) then
+ begin
+ Log.LogError('Unhandled sample-format', 'TBassPlaybackStream.Open');
+ Exit;
+ end;
+
+ // create matching playback stream
+ Handle := BASS_StreamCreate(Round(FormatInfo.SampleRate), FormatInfo.Channels, formatFlags,
+ @PlaybackStreamHandler, Self);
+ if (Handle = 0) then
+ begin
+ Log.LogError('BASS_StreamCreate failed: ' + BassCore.ErrorGetString(BASS_ErrorGetCode()),
+ 'TBassPlaybackStream.Open');
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+procedure TBassPlaybackStream.Close();
+begin
+ // stop and free stream
+ if (Handle <> 0) then
+ begin
+ Bass_StreamFree(Handle);
+ Handle := 0;
+ end;
+
+ // Note: PerformOnClose must be called before SourceStream is invalidated
+ PerformOnClose();
+ // unset source-stream
+ SourceStream := nil;
+end;
+
+procedure TBassPlaybackStream.Reset();
+begin
+ Close();
+ NeedsRewind := false;
+ PausedSeek := false;
+end;
+
+procedure TBassPlaybackStream.Play();
+var
+ NeedsFlush: boolean;
+begin
+ if (not assigned(SourceStream)) then
+ Exit;
+
+ NeedsFlush := true;
+
+ if (BASS_ChannelIsActive(Handle) = BASS_ACTIVE_PAUSED) then
+ begin
+ // only paused (and not seeked while paused) streams are not flushed
+ if (not PausedSeek) then
+ NeedsFlush := false;
+ // paused streams do not need a rewind
+ NeedsRewind := false;
+ end;
+
+ // rewind if necessary. Cases that require no rewind are:
+ // - stream was created and never played
+ // - stream was paused and is resumed now
+ // - stream was stopped and set to a new position already
+ if (NeedsRewind) then
+ SourceStream.Position := 0;
+
+ NeedsRewind := true;
+ PausedSeek := false;
+
+ // start playing and flush buffers on rewind
+ BASS_ChannelPlay(Handle, NeedsFlush);
+end;
+
+procedure TBassPlaybackStream.FadeIn(Time: real; TargetVolume: single);
+begin
+ // start stream
+ Play();
+ // start fade-in: slide from fadeStart- to fadeEnd-volume in FadeInTime
+ BASS_ChannelSlideAttribute(Handle, BASS_ATTRIB_VOL, TargetVolume, Trunc(Time * 1000));
+end;
+
+procedure TBassPlaybackStream.Pause();
+begin
+ BASS_ChannelPause(Handle);
+end;
+
+procedure TBassPlaybackStream.Stop();
+begin
+ BASS_ChannelStop(Handle);
+end;
+
+function TBassPlaybackStream.IsEOF(): boolean;
+begin
+ if (assigned(SourceStream)) then
+ Result := SourceStream.EOF
+ else
+ Result := true;
+end;
+
+function TBassPlaybackStream.GetLatency(): double;
+begin
+ // TODO: should we consider output latency for synching (needs BASS_DEVICE_LATENCY)?
+ //if (BASS_GetInfo(Info)) then
+ // Latency := Info.latency / 1000
+ //else
+ // Latency := 0;
+ Result := 0;
+end;
+
+function TBassPlaybackStream.GetVolume(): single;
+var
+ lVolume: single;
+begin
+ if (not BASS_ChannelGetAttribute(Handle, BASS_ATTRIB_VOL, lVolume)) then
+ begin
+ Log.LogError('BASS_ChannelGetAttribute: ' + BassCore.ErrorGetString(),
+ 'TBassPlaybackStream.GetVolume');
+ Result := 0;
+ Exit;
+ end;
+ Result := Round(lVolume);
+end;
+
+procedure TBassPlaybackStream.SetVolume(Volume: single);
+begin
+ // clamp volume
+ if Volume < 0 then
+ Volume := 0;
+ if Volume > 1.0 then
+ Volume := 1.0;
+ // set volume
+ BASS_ChannelSetAttribute(Handle, BASS_ATTRIB_VOL, Volume);
+end;
+
+function TBassPlaybackStream.GetPosition: real;
+var
+ BufferPosByte: QWORD;
+ BufferPosSec: double;
+begin
+ if assigned(SourceStream) then
+ begin
+ BufferPosByte := BASS_ChannelGetData(Handle, nil, BASS_DATA_AVAILABLE);
+ BufferPosSec := BASS_ChannelBytes2Seconds(Handle, BufferPosByte);
+ // decrease the decoding position by the amount buffered (and hence not played)
+ // in the BASS playback stream.
+ Result := SourceStream.Position - BufferPosSec;
+ end
+ else
+ begin
+ Result := -1;
+ end;
+end;
+
+procedure TBassPlaybackStream.SetPosition(Time: real);
+var
+ ChannelState: DWORD;
+begin
+ if assigned(SourceStream) then
+ begin
+ ChannelState := BASS_ChannelIsActive(Handle);
+ if (ChannelState = BASS_ACTIVE_STOPPED) then
+ begin
+ // if the stream is stopped, do not rewind when the stream is played next time
+ NeedsRewind := false
+ end
+ else if (ChannelState = BASS_ACTIVE_PAUSED) then
+ begin
+ // buffers must be flushed if in paused state but there is no
+ // BASS_ChannelFlush() function so we have to use BASS_ChannelPlay() called in Play().
+ PausedSeek := true;
+ end;
+
+ // set new position
+ SourceStream.Position := Time;
+ end;
+end;
+
+function TBassPlaybackStream.GetLength(): real;
+begin
+ if assigned(SourceStream) then
+ Result := SourceStream.Length
+ else
+ Result := -1;
+end;
+
+function TBassPlaybackStream.GetStatus(): TStreamStatus;
+var
+ State: DWORD;
+begin
+ State := BASS_ChannelIsActive(Handle);
+ case State of
+ BASS_ACTIVE_PLAYING,
+ BASS_ACTIVE_STALLED:
+ Result := ssPlaying;
+ BASS_ACTIVE_PAUSED:
+ Result := ssPaused;
+ BASS_ACTIVE_STOPPED:
+ Result := ssStopped;
+ else
+ begin
+ Log.LogError('Unknown status', 'TBassPlaybackStream.GetStatus');
+ Result := ssStopped;
+ end;
+ end;
+end;
+
+function TBassPlaybackStream.GetLoop(): boolean;
+begin
+ if assigned(SourceStream) then
+ Result := SourceStream.Loop
+ else
+ Result := false;
+end;
+
+procedure TBassPlaybackStream.SetLoop(Enabled: boolean);
+begin
+ if assigned(SourceStream) then
+ SourceStream.Loop := Enabled;
+end;
+
+procedure DSPProcHandler(handle: HDSP; channel: DWORD; buffer: Pointer; length: DWORD; user: Pointer);
+{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+var
+ Effect: TSoundEffect;
+begin
+ Effect := TSoundEffect(user);
+ if assigned(Effect) then
+ Effect.Callback(buffer, length);
+end;
+
+procedure TBassPlaybackStream.AddSoundEffect(Effect: TSoundEffect);
+var
+ DspHandle: HDSP;
+begin
+ if assigned(Effect.engineData) then
+ begin
+ Log.LogError('TSoundEffect.engineData already set', 'TBassPlaybackStream.AddSoundEffect');
+ Exit;
+ end;
+
+ DspHandle := BASS_ChannelSetDSP(Handle, @DSPProcHandler, Effect, 0);
+ if (DspHandle = 0) then
+ begin
+ Log.LogError(BassCore.ErrorGetString(), 'TBassPlaybackStream.AddSoundEffect');
+ Exit;
+ end;
+
+ GetMem(Effect.EngineData, SizeOf(HDSP));
+ PHDSP(Effect.EngineData)^ := DspHandle;
+end;
+
+procedure TBassPlaybackStream.RemoveSoundEffect(Effect: TSoundEffect);
+begin
+ if not assigned(Effect.EngineData) then
+ begin
+ Log.LogError('TSoundEffect.engineData invalid', 'TBassPlaybackStream.RemoveSoundEffect');
+ Exit;
+ end;
+
+ if not BASS_ChannelRemoveDSP(Handle, PHDSP(Effect.EngineData)^) then
+ begin
+ Log.LogError(BassCore.ErrorGetString(), 'TBassPlaybackStream.RemoveSoundEffect');
+ Exit;
+ end;
+
+ FreeMem(Effect.EngineData);
+ Effect.EngineData := nil;
+end;
+
+procedure TBassPlaybackStream.GetFFTData(var Data: TFFTData);
+begin
+ // get FFT channel data (Mono, FFT512 -> 256 values)
+ BASS_ChannelGetData(Handle, @Data, BASS_DATA_FFT512);
+end;
+
+{*
+ * Copies interleaved PCM SInt16 stereo samples into data.
+ * Returns the number of frames
+ *}
+function TBassPlaybackStream.GetPCMData(var Data: TPCMData): Cardinal;
+var
+ Info: BASS_CHANNELINFO;
+ nBytes: DWORD;
+begin
+ Result := 0;
+
+ FillChar(Data, SizeOf(TPCMData), 0);
+
+ // no support for non-stereo files at the moment
+ BASS_ChannelGetInfo(Handle, Info);
+ if (Info.chans <> 2) then
+ Exit;
+
+ nBytes := BASS_ChannelGetData(Handle, @Data, SizeOf(TPCMData));
+ if(nBytes <= 0) then
+ Result := 0
+ else
+ Result := nBytes div SizeOf(TPCMStereoSample);
+end;
+
+function TBassPlaybackStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ if assigned(SourceStream) then
+ Result := SourceStream.GetAudioFormatInfo()
+ else
+ Result := nil;
+end;
+
+
+{ TBassVoiceStream }
+
+function TBassVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
+var
+ Flags: DWORD;
+begin
+ Result := false;
+
+ Close();
+
+ if (not inherited Open(ChannelMap, FormatInfo)) then
+ Exit;
+
+ // get channel flags
+ BassCore.ConvertAudioFormatToBASSFlags(FormatInfo.Format, Flags);
+
+ (*
+ // distribute the mics equally to both speakers
+ if ((ChannelMap and CHANNELMAP_LEFT) <> 0) then
+ Flags := Flags or BASS_SPEAKER_FRONTLEFT;
+ if ((ChannelMap and CHANNELMAP_RIGHT) <> 0) then
+ Flags := Flags or BASS_SPEAKER_FRONTRIGHT;
+ *)
+
+ // create the channel
+ Handle := BASS_StreamCreate(Round(FormatInfo.SampleRate), 1, Flags, STREAMPROC_PUSH, nil);
+
+ // start the channel
+ BASS_ChannelPlay(Handle, true);
+
+ Result := true;
+end;
+
+procedure TBassVoiceStream.Close();
+begin
+ if (Handle <> 0) then
+ begin
+ BASS_ChannelStop(Handle);
+ BASS_StreamFree(Handle);
+ end;
+ inherited Close();
+end;
+
+procedure TBassVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
+var QueueSize: DWORD;
+begin
+ if ((Handle <> 0) and (BufferSize > 0)) then
+ begin
+ // query the queue size (normally 0)
+ QueueSize := BASS_StreamPutData(Handle, nil, 0);
+ // flush the buffer if the delay would be too high
+ if (QueueSize > MAX_VOICE_DELAY * FormatInfo.BytesPerSec) then
+ BASS_ChannelPlay(Handle, true);
+ // send new data to playback buffer
+ BASS_StreamPutData(Handle, Buffer, BufferSize);
+ end;
+end;
+
+// Note: we do not need the read-function for the BASS implementation
+function TBassVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+begin
+ Result := -1;
+end;
+
+function TBassVoiceStream.IsEOF(): boolean;
+begin
+ Result := false;
+end;
+
+function TBassVoiceStream.IsError(): boolean;
+begin
+ Result := false;
+end;
+
+
+{ TAudioPlayback_Bass }
+
+function TAudioPlayback_Bass.GetName: String;
+begin
+ Result := 'BASS_Playback';
+end;
+
+function TAudioPlayback_Bass.EnumDevices(): boolean;
+var
+ BassDeviceID: DWORD;
+ DeviceIndex: integer;
+ Device: TBassOutputDevice;
+ DeviceInfo: BASS_DEVICEINFO;
+begin
+ Result := true;
+
+ ClearOutputDeviceList();
+
+ // skip "no sound"-device (ID = 0)
+ BassDeviceID := 1;
+
+ while (true) do
+ begin
+ // check for device
+ if (not BASS_GetDeviceInfo(BassDeviceID, DeviceInfo)) then
+ Break;
+
+ // set device info
+ Device := TBassOutputDevice.Create();
+ Device.Name := DeviceInfo.name;
+ Device.BassDeviceID := BassDeviceID;
+
+ // add device to list
+ SetLength(OutputDeviceList, BassDeviceID);
+ OutputDeviceList[BassDeviceID-1] := Device;
+
+ Inc(BassDeviceID);
+ end;
+end;
+
+function TAudioPlayback_Bass.InitializePlayback(): boolean;
+begin
+ result := false;
+
+ BassCore := TAudioCore_Bass.GetInstance();
+
+ EnumDevices();
+
+ //Log.BenchmarkStart(4);
+ //Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
+
+ // TODO: use BASS_DEVICE_LATENCY to determine the latency
+ if not BASS_Init(-1, 44100, 0, 0, nil) then
+ begin
+ Log.LogError('Could not initialize BASS', 'TAudioPlayback_Bass.InitializePlayback');
+ Exit;
+ end;
+
+ //Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
+
+ // config playing buffer
+ //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
+ //BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
+
+ result := true;
+end;
+
+function TAudioPlayback_Bass.FinalizePlayback(): boolean;
+begin
+ Close;
+ BASS_Free;
+ inherited FinalizePlayback();
+ Result := true;
+end;
+
+function TAudioPlayback_Bass.CreatePlaybackStream(): TAudioPlaybackStream;
+begin
+ Result := TBassPlaybackStream.Create();
+end;
+
+procedure TAudioPlayback_Bass.SetAppVolume(Volume: single);
+begin
+ // set volume for this application (ranges from 0..10000 since BASS 2.4)
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Round(Volume*10000));
+end;
+
+function TAudioPlayback_Bass.CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+var
+ VoiceStream: TAudioVoiceStream;
+begin
+ Result := nil;
+
+ VoiceStream := TBassVoiceStream.Create();
+ if (not VoiceStream.Open(ChannelMap, FormatInfo)) then
+ begin
+ VoiceStream.Free;
+ Exit;
+ end;
+
+ Result := VoiceStream;
+end;
+
+function TAudioPlayback_Bass.GetLatency(): double;
+begin
+ Result := 0;
+end;
+
+
+initialization
+ MediaManager.Add(TAudioPlayback_Bass.Create);
+
+end.
diff --git a/src/Classes/UAudioPlayback_Portaudio.pas b/src/Classes/UAudioPlayback_Portaudio.pas
new file mode 100644
index 00000000..c3717ba6
--- /dev/null
+++ b/src/Classes/UAudioPlayback_Portaudio.pas
@@ -0,0 +1,361 @@
+unit UAudioPlayback_Portaudio;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ UMusic;
+
+implementation
+
+uses
+ portaudio,
+ UAudioCore_Portaudio,
+ UAudioPlayback_SoftMixer,
+ ULog,
+ UIni,
+ UMain;
+
+type
+ TAudioPlayback_Portaudio = class(TAudioPlayback_SoftMixer)
+ private
+ paStream: PPaStream;
+ AudioCore: TAudioCore_Portaudio;
+ Latency: double;
+ function OpenDevice(deviceIndex: TPaDeviceIndex): boolean;
+ function EnumDevices(): boolean;
+ protected
+ function InitializeAudioPlaybackEngine(): boolean; override;
+ function StartAudioPlaybackEngine(): boolean; override;
+ procedure StopAudioPlaybackEngine(); override;
+ function FinalizeAudioPlaybackEngine(): boolean; override;
+ function GetLatency(): double; override;
+ public
+ function GetName: String; override;
+ end;
+
+ TPortaudioOutputDevice = class(TAudioOutputDevice)
+ private
+ PaDeviceIndex: TPaDeviceIndex;
+ end;
+
+
+{ TAudioPlayback_Portaudio }
+
+function PortaudioAudioCallback(input: Pointer; output: Pointer; frameCount: Longword;
+ timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
+ userData: Pointer): Integer; cdecl;
+var
+ Engine: TAudioPlayback_Portaudio;
+begin
+ Engine := TAudioPlayback_Portaudio(userData);
+ // update latency
+ Engine.Latency := timeInfo.outputBufferDacTime - timeInfo.currentTime;
+ // call superclass callback
+ Engine.AudioCallback(output, frameCount * Engine.FormatInfo.FrameSize);
+ Result := paContinue;
+end;
+
+function TAudioPlayback_Portaudio.GetName: String;
+begin
+ Result := 'Portaudio_Playback';
+end;
+
+function TAudioPlayback_Portaudio.OpenDevice(deviceIndex: TPaDeviceIndex): boolean;
+var
+ DeviceInfo : PPaDeviceInfo;
+ SampleRate : double;
+ OutParams : TPaStreamParameters;
+ StreamInfo : PPaStreamInfo;
+ err : TPaError;
+begin
+ Result := false;
+
+ DeviceInfo := Pa_GetDeviceInfo(deviceIndex);
+
+ Log.LogInfo('Audio-Output Device: ' + DeviceInfo^.name, 'TAudioPlayback_Portaudio.OpenDevice');
+
+ SampleRate := DeviceInfo^.defaultSampleRate;
+
+ with OutParams do
+ begin
+ device := deviceIndex;
+ channelCount := 2;
+ sampleFormat := paInt16;
+ suggestedLatency := DeviceInfo^.defaultLowOutputLatency;
+ hostApiSpecificStreamInfo := nil;
+ end;
+
+ // check souncard and adjust sample-rate
+ if not AudioCore.TestDevice(nil, @OutParams, SampleRate) then
+ begin
+ Log.LogStatus('TestDevice failed!', 'TAudioPlayback_Portaudio.OpenDevice');
+ Exit;
+ end;
+
+ // open output stream
+ err := Pa_OpenStream(paStream, nil, @OutParams, SampleRate,
+ paFramesPerBufferUnspecified,
+ paNoFlag, @PortaudioAudioCallback, Self);
+ if(err <> paNoError) then
+ begin
+ Log.LogStatus(Pa_GetErrorText(err), 'TAudioPlayback_Portaudio.OpenDevice');
+ paStream := nil;
+ Exit;
+ end;
+
+ // get estimated latency (will be updated with real latency in the callback)
+ StreamInfo := Pa_GetStreamInfo(paStream);
+ if (StreamInfo <> nil) then
+ Latency := StreamInfo^.outputLatency
+ else
+ Latency := 0;
+
+ FormatInfo := TAudioFormatInfo.Create(
+ OutParams.channelCount,
+ SampleRate,
+ asfS16 // FIXME: is paInt16 system-dependant or -independant?
+ );
+
+ Result := true;
+end;
+
+function TAudioPlayback_Portaudio.EnumDevices(): boolean;
+var
+ i: integer;
+ paApiIndex: TPaHostApiIndex;
+ paApiInfo: PPaHostApiInfo;
+ deviceName: string;
+ deviceIndex: TPaDeviceIndex;
+ deviceInfo: PPaDeviceInfo;
+ channelCnt: integer;
+ SC: integer; // soundcard
+ err: TPaError;
+ errMsg: string;
+ paDevice: TPortaudioOutputDevice;
+ outputParams: TPaStreamParameters;
+ stream: PPaStream;
+ streamInfo: PPaStreamInfo;
+ sampleRate: double;
+ latency: TPaTime;
+ cbPolls: integer;
+ cbWorks: boolean;
+begin
+ Result := false;
+
+(*
+ // choose the best available Audio-API
+ paApiIndex := AudioCore.GetPreferredApiIndex();
+ if(paApiIndex = -1) then
+ begin
+ Log.LogError('No working Audio-API found', 'TAudioPlayback_Portaudio.EnumDevices');
+ Exit;
+ end;
+
+ paApiInfo := Pa_GetHostApiInfo(paApiIndex);
+
+ SC := 0;
+
+ // init array-size to max. output-devices count
+ SetLength(OutputDeviceList, paApiInfo^.deviceCount);
+ for i:= 0 to High(OutputDeviceList) do
+ begin
+ // convert API-specific device-index to global index
+ deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
+ deviceInfo := Pa_GetDeviceInfo(deviceIndex);
+
+ channelCnt := deviceInfo^.maxOutputChannels;
+
+ // current device is no output device -> skip
+ if (channelCnt <= 0) then
+ continue;
+
+ // portaudio returns a channel-count of 128 for some devices
+ // (e.g. the "default"-device), so we have to detect those
+ // fantasy channel counts.
+ if (channelCnt > 8) then
+ channelCnt := 2;
+
+ paDevice := TPortaudioOutputDevice.Create();
+ OutputDeviceList[SC] := paDevice;
+
+ // retrieve device-name
+ deviceName := deviceInfo^.name;
+ paDevice.Name := deviceName;
+ paDevice.PaDeviceIndex := deviceIndex;
+
+ if (deviceInfo^.defaultSampleRate > 0) then
+ sampleRate := deviceInfo^.defaultSampleRate
+ else
+ sampleRate := 44100;
+
+ // on vista and xp the defaultLowInputLatency may be set to 0 but it works.
+ // TODO: correct too low latencies (what is a too low latency, maybe < 10ms?)
+ latency := deviceInfo^.defaultLowInputLatency;
+
+ // setup desired output parameters
+ // TODO: retry with input-latency set to 20ms (defaultLowOutputLatency might
+ // not be set correctly in OSS)
+ with outputParams do
+ begin
+ device := deviceIndex;
+ channelCount := channelCnt;
+ sampleFormat := paInt16;
+ suggestedLatency := latency;
+ hostApiSpecificStreamInfo := nil;
+ end;
+
+ // check if mic-callback works (might not be called on some devices)
+ if (not TAudioCore_Portaudio.TestDevice(nil, @outputParams, sampleRate)) then
+ begin
+ // ignore device if callback did not work
+ Log.LogError('Device "'+paDevice.Name+'" does not respond',
+ 'TAudioPlayback_Portaudio.InitializeRecord');
+ paDevice.Free();
+ continue;
+ end;
+
+ // open device for further info
+ err := Pa_OpenStream(stream, nil, @outputParams, sampleRate,
+ paFramesPerBufferUnspecified, paNoFlag, @MicrophoneTestCallback, nil);
+ if(err <> paNoError) then
+ begin
+ // unable to open device -> skip
+ errMsg := Pa_GetErrorText(err);
+ Log.LogError('Device error: "'+ deviceName +'" ('+ errMsg +')',
+ 'TAudioPlayback_Portaudio.InitializeRecord');
+ paDevice.Free();
+ continue;
+ end;
+
+ // adjust sample-rate (might be changed by portaudio)
+ streamInfo := Pa_GetStreamInfo(stream);
+ if (streamInfo <> nil) then
+ begin
+ if (sampleRate <> streamInfo^.sampleRate) then
+ begin
+ Log.LogStatus('Portaudio changed Samplerate from ' + FloatToStr(sampleRate) +
+ ' to ' + FloatToStr(streamInfo^.sampleRate),
+ 'TAudioInput_Portaudio.InitializeRecord');
+ sampleRate := streamInfo^.sampleRate;
+ end;
+ end;
+
+ // create audio-format info and resize capture-buffer array
+ paDevice.AudioFormat := TAudioFormatInfo.Create(
+ channelCnt,
+ sampleRate,
+ asfS16
+ );
+ SetLength(paDevice.CaptureChannel, paDevice.AudioFormat.Channels);
+
+ Log.LogStatus('OutputDevice "'+paDevice.Name+'"@' +
+ IntToStr(paDevice.AudioFormat.Channels)+'x'+
+ FloatToStr(paDevice.AudioFormat.SampleRate)+'Hz ('+
+ FloatTostr(outputParams.suggestedLatency)+'sec)' ,
+ 'TAudioInput_Portaudio.InitializeRecord');
+
+ // close test-stream
+ Pa_CloseStream(stream);
+
+ Inc(SC);
+ end;
+
+ // adjust size to actual input-device count
+ SetLength(OutputDeviceList, SC);
+
+ Log.LogStatus('#Output-Devices: ' + inttostr(SC), 'Portaudio');
+*)
+
+ Result := true;
+end;
+
+function TAudioPlayback_Portaudio.InitializeAudioPlaybackEngine(): boolean;
+var
+ paApiIndex : TPaHostApiIndex;
+ paApiInfo : PPaHostApiInfo;
+ paOutDevice : TPaDeviceIndex;
+ err: TPaError;
+begin
+ Result := false;
+
+ AudioCore := TAudioCore_Portaudio.GetInstance();
+
+ // initialize portaudio
+ err := Pa_Initialize();
+ if(err <> paNoError) then
+ begin
+ Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord');
+ Exit;
+ end;
+
+ paApiIndex := AudioCore.GetPreferredApiIndex();
+ if(paApiIndex = -1) then
+ begin
+ Log.LogError('No working Audio-API found', 'TAudioPlayback_Portaudio.InitializeAudioPlaybackEngine');
+ Exit;
+ end;
+
+ EnumDevices();
+
+ paApiInfo := Pa_GetHostApiInfo(paApiIndex);
+ Log.LogInfo('Audio-Output API-Type: ' + paApiInfo^.name, 'TAudioPlayback_Portaudio.OpenDevice');
+
+ paOutDevice := paApiInfo^.defaultOutputDevice;
+ if (not OpenDevice(paOutDevice)) then
+ begin
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+function TAudioPlayback_Portaudio.StartAudioPlaybackEngine(): boolean;
+var
+ err: TPaError;
+begin
+ Result := false;
+
+ if (paStream = nil) then
+ Exit;
+
+ err := Pa_StartStream(paStream);
+ if(err <> paNoError) then
+ begin
+ Log.LogStatus('Pa_StartStream: '+Pa_GetErrorText(err), 'UAudioPlayback_Portaudio');
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+procedure TAudioPlayback_Portaudio.StopAudioPlaybackEngine();
+begin
+ if (paStream <> nil) then
+ Pa_StopStream(paStream);
+end;
+
+function TAudioPlayback_Portaudio.FinalizeAudioPlaybackEngine(): boolean;
+begin
+ Pa_Terminate();
+ Result := true;
+end;
+
+function TAudioPlayback_Portaudio.GetLatency(): double;
+begin
+ Result := Latency;
+end;
+
+
+initialization
+ MediaManager.Add(TAudioPlayback_Portaudio.Create);
+
+end.
diff --git a/src/Classes/UAudioPlayback_SDL.pas b/src/Classes/UAudioPlayback_SDL.pas
new file mode 100644
index 00000000..deef91e8
--- /dev/null
+++ b/src/Classes/UAudioPlayback_SDL.pas
@@ -0,0 +1,160 @@
+unit UAudioPlayback_SDL;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ UMusic;
+
+implementation
+
+uses
+ sdl,
+ UAudioPlayback_SoftMixer,
+ ULog,
+ UIni,
+ UMain;
+
+type
+ TAudioPlayback_SDL = class(TAudioPlayback_SoftMixer)
+ private
+ Latency: double;
+ function EnumDevices(): boolean;
+ protected
+ function InitializeAudioPlaybackEngine(): boolean; override;
+ function StartAudioPlaybackEngine(): boolean; override;
+ procedure StopAudioPlaybackEngine(); override;
+ function FinalizeAudioPlaybackEngine(): boolean; override;
+ function GetLatency(): double; override;
+ public
+ function GetName: String; override;
+ procedure MixBuffers(dst, src: PChar; size: Cardinal; volume: Single); override;
+ end;
+
+
+{ TAudioPlayback_SDL }
+
+procedure SDLAudioCallback(userdata: Pointer; stream: PChar; len: integer); cdecl;
+var
+ Engine: TAudioPlayback_SDL;
+begin
+ Engine := TAudioPlayback_SDL(userdata);
+ Engine.AudioCallback(stream, len);
+end;
+
+function TAudioPlayback_SDL.GetName: String;
+begin
+ Result := 'SDL_Playback';
+end;
+
+function TAudioPlayback_SDL.EnumDevices(): boolean;
+begin
+ // Note: SDL does not provide Device-Selection capabilities (will be introduced in 1.3)
+ ClearOutputDeviceList();
+ SetLength(OutputDeviceList, 1);
+ OutputDeviceList[0] := TAudioOutputDevice.Create();
+ OutputDeviceList[0].Name := '[SDL Default-Device]';
+ Result := true;
+end;
+
+function TAudioPlayback_SDL.InitializeAudioPlaybackEngine(): boolean;
+var
+ DesiredAudioSpec, ObtainedAudioSpec: TSDL_AudioSpec;
+ SampleBufferSize: integer;
+begin
+ Result := false;
+
+ EnumDevices();
+
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) = -1) then
+ begin
+ Log.LogError('SDL_InitSubSystem failed!', 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
+ Exit;
+ end;
+
+ SampleBufferSize := IAudioOutputBufferSizeVals[Ini.AudioOutputBufferSizeIndex];
+ if (SampleBufferSize <= 0) then
+ begin
+ // Automatic setting default
+ // FIXME: too much glitches with 1024 samples
+ SampleBufferSize := 2048; //1024;
+ end;
+
+ FillChar(DesiredAudioSpec, SizeOf(DesiredAudioSpec), 0);
+ with DesiredAudioSpec do
+ begin
+ freq := 44100;
+ format := AUDIO_S16SYS;
+ channels := 2;
+ samples := SampleBufferSize;
+ callback := @SDLAudioCallback;
+ userdata := Self;
+ end;
+
+ // Note: always use the "obtained" parameter, otherwise SDL might try to convert
+ // the samples itself if the desired format is not available. This might lead
+ // to problems if for example ALSA does not support 44100Hz and proposes 48000Hz.
+ // Without the obtained parameter, SDL would try to convert 44.1kHz to 48kHz with
+ // its crappy (non working) converter resulting in a wrong (too high) pitch.
+ if(SDL_OpenAudio(@DesiredAudioSpec, @ObtainedAudioSpec) = -1) then
+ begin
+ Log.LogStatus('SDL_OpenAudio: ' + SDL_GetError(), 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
+ Exit;
+ end;
+
+ FormatInfo := TAudioFormatInfo.Create(
+ ObtainedAudioSpec.channels,
+ ObtainedAudioSpec.freq,
+ asfS16
+ );
+
+ // Note: SDL does not provide info of the internal buffer state.
+ // So we use the average buffer-size.
+ Latency := (ObtainedAudioSpec.samples/2) / FormatInfo.SampleRate;
+
+ Log.LogStatus('Opened audio device', 'TAudioPlayback_SDL.InitializeAudioPlaybackEngine');
+
+ Result := true;
+end;
+
+function TAudioPlayback_SDL.StartAudioPlaybackEngine(): boolean;
+begin
+ SDL_PauseAudio(0);
+ Result := true;
+end;
+
+procedure TAudioPlayback_SDL.StopAudioPlaybackEngine();
+begin
+ SDL_PauseAudio(1);
+end;
+
+function TAudioPlayback_SDL.FinalizeAudioPlaybackEngine(): boolean;
+begin
+ SDL_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ Result := true;
+end;
+
+function TAudioPlayback_SDL.GetLatency(): double;
+begin
+ Result := Latency;
+end;
+
+procedure TAudioPlayback_SDL.MixBuffers(dst, src: PChar; size: Cardinal; volume: Single);
+begin
+ SDL_MixAudio(PUInt8(dst), PUInt8(src), size, Round(volume * SDL_MIX_MAXVOLUME));
+end;
+
+
+initialization
+ MediaManager.add(TAudioPlayback_SDL.Create);
+
+end.
diff --git a/src/Classes/UAudioPlayback_SoftMixer.pas b/src/Classes/UAudioPlayback_SoftMixer.pas
new file mode 100644
index 00000000..6ddae980
--- /dev/null
+++ b/src/Classes/UAudioPlayback_SoftMixer.pas
@@ -0,0 +1,1132 @@
+unit UAudioPlayback_SoftMixer;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ sdl,
+ URingBuffer,
+ UMusic,
+ UAudioPlaybackBase;
+
+type
+ TAudioPlayback_SoftMixer = class;
+
+ TGenericPlaybackStream = class(TAudioPlaybackStream)
+ private
+ Engine: TAudioPlayback_SoftMixer;
+
+ SampleBuffer: PChar;
+ SampleBufferSize: integer;
+ SampleBufferCount: integer; // number of available bytes in SampleBuffer
+ SampleBufferPos: cardinal;
+
+ SourceBuffer: PChar;
+ SourceBufferSize: integer;
+ SourceBufferCount: integer; // number of available bytes in SourceBuffer
+
+ Converter: TAudioConverter;
+ Status: TStreamStatus;
+ InternalLock: PSDL_Mutex;
+ SoundEffects: TList;
+ fVolume: single;
+
+ FadeInStartTime, FadeInTime: cardinal;
+ FadeInStartVolume, FadeInTargetVolume: single;
+
+ NeedsRewind: boolean;
+
+ procedure Reset();
+
+ procedure ApplySoundEffects(Buffer: PChar; BufferSize: integer);
+ function InitFormatConversion(): boolean;
+ procedure FlushBuffers();
+
+ procedure LockSampleBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure UnlockSampleBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
+ protected
+ function GetLatency(): double; override;
+ function GetStatus(): TStreamStatus; override;
+ function GetVolume(): single; override;
+ procedure SetVolume(Volume: single); override;
+ function GetLength(): real; override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ function GetPosition: real; override;
+ procedure SetPosition(Time: real); override;
+ public
+ constructor Create(Engine: TAudioPlayback_SoftMixer);
+ destructor Destroy(); override;
+
+ function Open(SourceStream: TAudioSourceStream): boolean; override;
+ procedure Close(); override;
+
+ procedure Play(); override;
+ procedure Pause(); override;
+ procedure Stop(); override;
+ procedure FadeIn(Time: real; TargetVolume: single); override;
+
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+
+ function ReadData(Buffer: PChar; BufferSize: integer): integer;
+
+ function GetPCMData(var Data: TPCMData): Cardinal; override;
+ procedure GetFFTData(var Data: TFFTData); override;
+
+ procedure AddSoundEffect(Effect: TSoundEffect); override;
+ procedure RemoveSoundEffect(Effect: TSoundEffect); override;
+ end;
+
+ TAudioMixerStream = class
+ private
+ Engine: TAudioPlayback_SoftMixer;
+
+ ActiveStreams: TList;
+ MixerBuffer: PChar;
+ InternalLock: PSDL_Mutex;
+
+ AppVolume: single;
+
+ procedure Lock(); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure Unlock(); {$IFDEF HasInline}inline;{$ENDIF}
+
+ function GetVolume(): single;
+ procedure SetVolume(Volume: single);
+ public
+ constructor Create(Engine: TAudioPlayback_SoftMixer);
+ destructor Destroy(); override;
+ procedure AddStream(Stream: TAudioPlaybackStream);
+ procedure RemoveStream(Stream: TAudioPlaybackStream);
+ function ReadData(Buffer: PChar; BufferSize: integer): integer;
+
+ property Volume: single read GetVolume write SetVolume;
+ end;
+
+ TAudioPlayback_SoftMixer = class(TAudioPlaybackBase)
+ private
+ MixerStream: TAudioMixerStream;
+ protected
+ FormatInfo: TAudioFormatInfo;
+
+ function InitializeAudioPlaybackEngine(): boolean; virtual; abstract;
+ function StartAudioPlaybackEngine(): boolean; virtual; abstract;
+ procedure StopAudioPlaybackEngine(); virtual; abstract;
+ function FinalizeAudioPlaybackEngine(): boolean; virtual; abstract;
+ procedure AudioCallback(Buffer: PChar; Size: integer); {$IFDEF HasInline}inline;{$ENDIF}
+
+ function CreatePlaybackStream(): TAudioPlaybackStream; override;
+ public
+ function GetName: String; override; abstract;
+ function InitializePlayback(): boolean; override;
+ function FinalizePlayback: boolean; override;
+
+ procedure SetAppVolume(Volume: single); override;
+
+ function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream; override;
+
+ function GetMixer(): TAudioMixerStream; {$IFDEF HasInline}inline;{$ENDIF}
+ function GetAudioFormatInfo(): TAudioFormatInfo;
+
+ procedure MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single); virtual;
+ end;
+
+type
+ TGenericVoiceStream = class(TAudioVoiceStream)
+ private
+ VoiceBuffer: TRingBuffer;
+ BufferLock: PSDL_Mutex;
+ PlaybackStream: TGenericPlaybackStream;
+ Engine: TAudioPlayback_SoftMixer;
+ public
+ constructor Create(Engine: TAudioPlayback_SoftMixer);
+
+ function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
+ procedure Close(); override;
+ procedure WriteData(Buffer: PChar; BufferSize: integer); override;
+ function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ function IsEOF(): boolean; override;
+ function IsError(): boolean; override;
+ end;
+
+const
+ SOURCE_BUFFER_FRAMES = 4096;
+
+const
+ MAX_VOICE_DELAY = 0.500; // 20ms
+
+implementation
+
+uses
+ Math,
+ ULog,
+ UIni,
+ UFFT,
+ UAudioConverter,
+ UMain;
+
+{ TAudioMixerStream }
+
+constructor TAudioMixerStream.Create(Engine: TAudioPlayback_SoftMixer);
+begin
+ inherited Create();
+
+ Self.Engine := Engine;
+
+ ActiveStreams := TList.Create;
+ InternalLock := SDL_CreateMutex();
+ AppVolume := 1.0;
+end;
+
+destructor TAudioMixerStream.Destroy();
+begin
+ if assigned(MixerBuffer) then
+ Freemem(MixerBuffer);
+ ActiveStreams.Free;
+ SDL_DestroyMutex(InternalLock);
+ inherited;
+end;
+
+procedure TAudioMixerStream.Lock();
+begin
+ SDL_mutexP(InternalLock);
+end;
+
+procedure TAudioMixerStream.Unlock();
+begin
+ SDL_mutexV(InternalLock);
+end;
+
+function TAudioMixerStream.GetVolume(): single;
+begin
+ Lock();
+ Result := AppVolume;
+ Unlock();
+end;
+
+procedure TAudioMixerStream.SetVolume(Volume: single);
+begin
+ Lock();
+ AppVolume := Volume;
+ Unlock();
+end;
+
+procedure TAudioMixerStream.AddStream(Stream: TAudioPlaybackStream);
+begin
+ if not assigned(Stream) then
+ Exit;
+
+ Lock();
+ // check if stream is already in list to avoid duplicates
+ if (ActiveStreams.IndexOf(Pointer(Stream)) = -1) then
+ ActiveStreams.Add(Pointer(Stream));
+ Unlock();
+end;
+
+(*
+ * Sets the entry of stream in the ActiveStreams-List to nil
+ * but does not remove it from the list (Count is not changed!).
+ * Otherwise iterations over the elements might fail due to a
+ * changed Count-property.
+ * Call ActiveStreams.Pack() to remove the nil-pointers
+ * or check for nil-pointers when accessing ActiveStreams.
+ *)
+procedure TAudioMixerStream.RemoveStream(Stream: TAudioPlaybackStream);
+var
+ Index: integer;
+begin
+ Lock();
+ Index := activeStreams.IndexOf(Pointer(Stream));
+ if (Index <> -1) then
+ begin
+ // remove entry but do not decrease count-property
+ ActiveStreams[Index] := nil;
+ end;
+ Unlock();
+end;
+
+function TAudioMixerStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+var
+ i: integer;
+ Size: integer;
+ Stream: TGenericPlaybackStream;
+ NeedsPacking: boolean;
+begin
+ Result := BufferSize;
+
+ // zero target-buffer (silence)
+ FillChar(Buffer^, BufferSize, 0);
+
+ // resize mixer-buffer if necessary
+ ReallocMem(MixerBuffer, BufferSize);
+ if not assigned(MixerBuffer) then
+ Exit;
+
+ Lock();
+
+ NeedsPacking := false;
+
+ // mix streams to one stream
+ for i := 0 to ActiveStreams.Count-1 do
+ begin
+ if (ActiveStreams[i] = nil) then
+ begin
+ NeedsPacking := true;
+ continue;
+ end;
+
+ Stream := TGenericPlaybackStream(ActiveStreams[i]);
+ // fetch data from current stream
+ Size := Stream.ReadData(MixerBuffer, BufferSize);
+ if (Size > 0) then
+ begin
+ // mix stream-data with mixer-buffer
+ // Note: use Self.appVolume instead of Self.Volume to prevent recursive locking
+ Engine.MixBuffers(Buffer, MixerBuffer, Size, AppVolume * Stream.Volume);
+ end;
+ end;
+
+ // remove nil-pointers from list
+ if (NeedsPacking) then
+ begin
+ ActiveStreams.Pack();
+ end;
+
+ Unlock();
+end;
+
+
+{ TGenericPlaybackStream }
+
+constructor TGenericPlaybackStream.Create(Engine: TAudioPlayback_SoftMixer);
+begin
+ inherited Create();
+ Self.Engine := Engine;
+ InternalLock := SDL_CreateMutex();
+ SoundEffects := TList.Create;
+ Status := ssStopped;
+ Reset();
+end;
+
+destructor TGenericPlaybackStream.Destroy();
+begin
+ Close();
+ SDL_DestroyMutex(InternalLock);
+ FreeAndNil(SoundEffects);
+ inherited;
+end;
+
+procedure TGenericPlaybackStream.Reset();
+begin
+ SourceStream := nil;
+
+ FreeAndNil(Converter);
+
+ FreeMem(SampleBuffer);
+ SampleBuffer := nil;
+ SampleBufferPos := 0;
+ SampleBufferSize := 0;
+ SampleBufferCount := 0;
+
+ FreeMem(SourceBuffer);
+ SourceBuffer := nil;
+ SourceBufferSize := 0;
+ SourceBufferCount := 0;
+
+ NeedsRewind := false;
+
+ fVolume := 0;
+ SoundEffects.Clear;
+ FadeInTime := 0;
+end;
+
+function TGenericPlaybackStream.Open(SourceStream: TAudioSourceStream): boolean;
+begin
+ Result := false;
+
+ Close();
+
+ if (not assigned(SourceStream)) then
+ Exit;
+ Self.SourceStream := SourceStream;
+
+ if (not InitFormatConversion()) then
+ begin
+ // reset decode-stream so it will not be freed on destruction
+ Self.SourceStream := nil;
+ Exit;
+ end;
+
+ SourceBufferSize := SOURCE_BUFFER_FRAMES * SourceStream.GetAudioFormatInfo().FrameSize;
+ GetMem(SourceBuffer, SourceBufferSize);
+ fVolume := 1.0;
+
+ Result := true;
+end;
+
+procedure TGenericPlaybackStream.Close();
+begin
+ // stop audio-callback on this stream
+ Stop();
+
+ // Note: PerformOnClose must be called before SourceStream is invalidated
+ PerformOnClose();
+ // and free data
+ Reset();
+end;
+
+procedure TGenericPlaybackStream.LockSampleBuffer();
+begin
+ SDL_mutexP(InternalLock);
+end;
+
+procedure TGenericPlaybackStream.UnlockSampleBuffer();
+begin
+ SDL_mutexV(InternalLock);
+end;
+
+function TGenericPlaybackStream.InitFormatConversion(): boolean;
+var
+ SrcFormatInfo: TAudioFormatInfo;
+ DstFormatInfo: TAudioFormatInfo;
+begin
+ Result := false;
+
+ SrcFormatInfo := SourceStream.GetAudioFormatInfo();
+ DstFormatInfo := GetAudioFormatInfo();
+
+ // TODO: selection should not be done here, use a factory (TAudioConverterFactory) instead
+ {$IF Defined(UseFFmpegResample)}
+ Converter := TAudioConverter_FFmpeg.Create();
+ {$ELSEIF Defined(UseSRCResample)}
+ Converter := TAudioConverter_SRC.Create();
+ {$ELSE}
+ Converter := TAudioConverter_SDL.Create();
+ {$IFEND}
+
+ Result := Converter.Init(SrcFormatInfo, DstFormatInfo);
+end;
+
+procedure TGenericPlaybackStream.Play();
+var
+ Mixer: TAudioMixerStream;
+begin
+ // only paused streams are not flushed
+ if (Status = ssPaused) then
+ NeedsRewind := false;
+
+ // rewind if necessary. Cases that require no rewind are:
+ // - stream was created and never played
+ // - stream was paused and is resumed now
+ // - stream was stopped and set to a new position already
+ if (NeedsRewind) then
+ SetPosition(0);
+
+ // update status
+ Status := ssPlaying;
+
+ NeedsRewind := true;
+
+ // add this stream to the mixer
+ Mixer := Engine.GetMixer();
+ if (Mixer <> nil) then
+ Mixer.AddStream(Self);
+end;
+
+procedure TGenericPlaybackStream.FadeIn(Time: real; TargetVolume: single);
+begin
+ FadeInTime := Trunc(Time * 1000);
+ FadeInStartTime := SDL_GetTicks();
+ FadeInStartVolume := fVolume;
+ FadeInTargetVolume := TargetVolume;
+ Play();
+end;
+
+procedure TGenericPlaybackStream.Pause();
+var
+ Mixer: TAudioMixerStream;
+begin
+ if (Status <> ssPlaying) then
+ Exit;
+
+ Status := ssPaused;
+
+ Mixer := Engine.GetMixer();
+ if (Mixer <> nil) then
+ Mixer.RemoveStream(Self);
+end;
+
+procedure TGenericPlaybackStream.Stop();
+var
+ Mixer: TAudioMixerStream;
+begin
+ if (Status = ssStopped) then
+ Exit;
+
+ Status := ssStopped;
+
+ Mixer := Engine.GetMixer();
+ if (Mixer <> nil) then
+ Mixer.RemoveStream(Self);
+end;
+
+function TGenericPlaybackStream.GetLoop(): boolean;
+begin
+ if assigned(SourceStream) then
+ Result := SourceStream.Loop
+ else
+ Result := false;
+end;
+
+procedure TGenericPlaybackStream.SetLoop(Enabled: boolean);
+begin
+ if assigned(SourceStream) then
+ SourceStream.Loop := Enabled;
+end;
+
+function TGenericPlaybackStream.GetLength(): real;
+begin
+ if assigned(SourceStream) then
+ Result := SourceStream.Length
+ else
+ Result := -1;
+end;
+
+function TGenericPlaybackStream.GetLatency(): double;
+begin
+ Result := Engine.GetLatency();
+end;
+
+function TGenericPlaybackStream.GetStatus(): TStreamStatus;
+begin
+ Result := Status;
+end;
+
+function TGenericPlaybackStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := Engine.GetAudioFormatInfo();
+end;
+
+procedure TGenericPlaybackStream.FlushBuffers();
+begin
+ SampleBufferCount := 0;
+ SampleBufferPos := 0;
+ SourceBufferCount := 0;
+end;
+
+procedure TGenericPlaybackStream.ApplySoundEffects(Buffer: PChar; BufferSize: integer);
+var
+ i: integer;
+begin
+ for i := 0 to SoundEffects.Count-1 do
+ begin
+ if (SoundEffects[i] <> nil) then
+ begin
+ TSoundEffect(SoundEffects[i]).Callback(Buffer, BufferSize);
+ end;
+ end;
+end;
+
+function TGenericPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+var
+ ConversionInputCount: integer;
+ ConversionOutputSize: integer; // max. number of converted data (= buffer size)
+ ConversionOutputCount: integer; // actual number of converted data
+ SourceSize: integer;
+ RequestedSourceSize: integer;
+ NeededSampleBufferSize: integer;
+ BytesNeeded, BytesAvail: integer;
+ SourceFormatInfo, OutputFormatInfo: TAudioFormatInfo;
+ SourceFrameSize, OutputFrameSize: integer;
+ SkipOutputCount: integer; // number of output-data bytes to skip
+ SkipSourceCount: integer; // number of source-data bytes to skip
+ FillCount: integer; // number of bytes to fill with padding data
+ CopyCount: integer;
+ PadFrame: PChar;
+ i: integer;
+begin
+ Result := -1;
+
+ // sanity check for the source-stream
+ if (not assigned(SourceStream)) then
+ Exit;
+
+ SkipOutputCount := 0;
+ SkipSourceCount := 0;
+ FillCount := 0;
+
+ SourceFormatInfo := SourceStream.GetAudioFormatInfo();
+ SourceFrameSize := SourceFormatInfo.FrameSize;
+ OutputFormatInfo := GetAudioFormatInfo();
+ OutputFrameSize := OutputFormatInfo.FrameSize;
+
+ // synchronize (adjust buffer size)
+ BytesNeeded := Synchronize(BufferSize, OutputFormatInfo);
+ if (BytesNeeded > BufferSize) then
+ begin
+ SkipOutputCount := BytesNeeded - BufferSize;
+ BytesNeeded := BufferSize;
+ end
+ else if (BytesNeeded < BufferSize) then
+ begin
+ FillCount := BufferSize - BytesNeeded;
+ end;
+
+ // lock access to sample-buffer
+ LockSampleBuffer();
+ try
+
+ // skip sample-buffer data
+ SampleBufferPos := SampleBufferPos + SkipOutputCount;
+ // size of available bytes in SampleBuffer after skipping
+ SampleBufferCount := SampleBufferCount - SampleBufferPos;
+ // update byte skip-count
+ SkipOutputCount := -SampleBufferCount;
+
+ // now that we skipped all buffered data from the last pass, we have to skip
+ // data directly after fetching it from the source-stream.
+ if (SkipOutputCount > 0) then
+ begin
+ SampleBufferCount := 0;
+ // convert skip-count to source-format units and resize to a multiple of
+ // the source frame-size.
+ SkipSourceCount := Round((SkipOutputCount * OutputFormatInfo.GetRatio(SourceFormatInfo)) /
+ SourceFrameSize) * SourceFrameSize;
+ SkipOutputCount := 0;
+ end;
+
+ // copy data to front of buffer
+ if ((SampleBufferCount > 0) and (SampleBufferPos > 0)) then
+ Move(SampleBuffer[SampleBufferPos], SampleBuffer[0], SampleBufferCount);
+ SampleBufferPos := 0;
+
+ // resize buffer to a reasonable size
+ if (BufferSize > SampleBufferCount) then
+ begin
+ // Note: use BufferSize instead of BytesNeeded to minimize the need for resizing
+ SampleBufferSize := BufferSize;
+ ReallocMem(SampleBuffer, SampleBufferSize);
+ if (not assigned(SampleBuffer)) then
+ Exit;
+ end;
+
+ // fill sample-buffer (fetch and convert one block of source data per loop)
+ while (SampleBufferCount < BytesNeeded) do
+ begin
+ // move remaining source data from the previous pass to front of buffer
+ if (SourceBufferCount > 0) then
+ begin
+ Move(SourceBuffer[SourceBufferSize-SourceBufferCount],
+ SourceBuffer[0],
+ SourceBufferCount);
+ end;
+
+ SourceSize := SourceStream.ReadData(
+ @SourceBuffer[SourceBufferCount], SourceBufferSize-SourceBufferCount);
+ // break on error (-1) or if no data is available (0), e.g. while seeking
+ if (SourceSize <= 0) then
+ begin
+ // if we do not have data -> exit
+ if (SourceBufferCount = 0) then
+ begin
+ FlushBuffers();
+ Exit;
+ end;
+ // if we have some data, stop retrieving data from the source stream
+ // and use the data we have so far
+ Break;
+ end;
+
+ SourceBufferCount := SourceBufferCount + SourceSize;
+
+ // end-of-file reached -> stop playback
+ if (SourceStream.EOF) then
+ begin
+ if (Loop) then
+ SourceStream.Position := 0
+ else
+ Stop();
+ end;
+
+ if (SkipSourceCount > 0) then
+ begin
+ // skip data and update source buffer count
+ SourceBufferCount := SourceBufferCount - SkipSourceCount;
+ SkipSourceCount := -SourceBufferCount;
+ // continue with next pass if we skipped all data
+ if (SourceBufferCount <= 0) then
+ begin
+ SourceBufferCount := 0;
+ Continue;
+ end;
+ end;
+
+ // calc buffer size (might be bigger than actual resampled byte count)
+ ConversionOutputSize := Converter.GetOutputBufferSize(SourceBufferCount);
+ NeededSampleBufferSize := SampleBufferCount + ConversionOutputSize;
+
+ // resize buffer if necessary
+ if (SampleBufferSize < NeededSampleBufferSize) then
+ begin
+ SampleBufferSize := NeededSampleBufferSize;
+ ReallocMem(SampleBuffer, SampleBufferSize);
+ if (not assigned(SampleBuffer)) then
+ begin
+ FlushBuffers();
+ Exit;
+ end;
+ end;
+
+ // resample source data (Note: ConversionInputCount might be adjusted by Convert())
+ ConversionInputCount := SourceBufferCount;
+ ConversionOutputCount := Converter.Convert(
+ SourceBuffer, @SampleBuffer[SampleBufferCount], ConversionInputCount);
+ if (ConversionOutputCount = -1) then
+ begin
+ FlushBuffers();
+ Exit;
+ end;
+
+ // adjust sample- and source-buffer count by the number of converted bytes
+ SampleBufferCount := SampleBufferCount + ConversionOutputCount;
+ SourceBufferCount := SourceBufferCount - ConversionInputCount;
+ end;
+
+ // apply effects
+ ApplySoundEffects(SampleBuffer, SampleBufferCount);
+
+ // copy data to result buffer
+ CopyCount := Min(BytesNeeded, SampleBufferCount);
+ Move(SampleBuffer[0], Buffer[BufferSize - BytesNeeded], CopyCount);
+ Dec(BytesNeeded, CopyCount);
+ SampleBufferPos := CopyCount;
+
+ // release buffer lock
+ finally
+ UnlockSampleBuffer();
+ end;
+
+ // pad the buffer with the last frame if we are to fast
+ if (FillCount > 0) then
+ begin
+ if (CopyCount >= OutputFrameSize) then
+ PadFrame := @Buffer[CopyCount-OutputFrameSize]
+ else
+ PadFrame := nil;
+ FillBufferWithFrame(@Buffer[CopyCount], FillCount,
+ PadFrame, OutputFrameSize);
+ end;
+
+ // BytesNeeded now contains the number of remaining bytes we were not able to fetch
+ Result := BufferSize - BytesNeeded;
+end;
+
+function TGenericPlaybackStream.GetPCMData(var Data: TPCMData): Cardinal;
+var
+ ByteCount: integer;
+begin
+ Result := 0;
+
+ // just SInt16 stereo support for now
+ if ((Engine.GetAudioFormatInfo().Format <> asfS16) or
+ (Engine.GetAudioFormatInfo().Channels <> 2)) then
+ begin
+ Exit;
+ end;
+
+ // zero memory
+ FillChar(Data, SizeOf(Data), 0);
+
+ // TODO: At the moment just the first samples of the SampleBuffer
+ // are returned, even if there is newer data in the upper samples.
+
+ LockSampleBuffer();
+ ByteCount := Min(SizeOf(Data), SampleBufferCount);
+ if (ByteCount > 0) then
+ begin
+ Move(SampleBuffer[0], Data, ByteCount);
+ end;
+ UnlockSampleBuffer();
+
+ Result := ByteCount div SizeOf(TPCMStereoSample);
+end;
+
+procedure TGenericPlaybackStream.GetFFTData(var Data: TFFTData);
+var
+ i: integer;
+ Frames: integer;
+ DataIn: PSingleArray;
+ AudioFormat: TAudioFormatInfo;
+begin
+ // only works with SInt16 and Float values at the moment
+ AudioFormat := GetAudioFormatInfo();
+
+ DataIn := AllocMem(FFTSize * SizeOf(Single));
+ if (DataIn = nil) then
+ Exit;
+
+ LockSampleBuffer();
+ // TODO: We just use the first Frames frames, the others are ignored.
+ Frames := Min(FFTSize, SampleBufferCount div AudioFormat.FrameSize);
+ // use only first channel and convert data to float-values
+ case AudioFormat.Format of
+ asfS16:
+ begin
+ for i := 0 to Frames-1 do
+ DataIn[i] := PSmallInt(@SampleBuffer[i*AudioFormat.FrameSize])^ / -Low(SmallInt);
+ end;
+ asfFloat:
+ begin
+ for i := 0 to Frames-1 do
+ DataIn[i] := PSingle(@SampleBuffer[i*AudioFormat.FrameSize])^;
+ end;
+ end;
+ UnlockSampleBuffer();
+
+ WindowFunc(fwfHanning, FFTSize, DataIn);
+ PowerSpectrum(FFTSize, DataIn, @Data);
+ FreeMem(DataIn);
+
+ // resize data to a 0..1 range
+ for i := 0 to High(TFFTData) do
+ begin
+ Data[i] := Sqrt(Data[i]) / 100;
+ end;
+end;
+
+procedure TGenericPlaybackStream.AddSoundEffect(Effect: TSoundEffect);
+begin
+ if (not assigned(Effect)) then
+ Exit;
+
+ LockSampleBuffer();
+ // check if effect is already in list to avoid duplicates
+ if (SoundEffects.IndexOf(Pointer(Effect)) = -1) then
+ SoundEffects.Add(Pointer(Effect));
+ UnlockSampleBuffer();
+end;
+
+procedure TGenericPlaybackStream.RemoveSoundEffect(Effect: TSoundEffect);
+begin
+ LockSampleBuffer();
+ SoundEffects.Remove(Effect);
+ UnlockSampleBuffer();
+end;
+
+function TGenericPlaybackStream.GetPosition: real;
+var
+ BufferedTime: double;
+begin
+ if assigned(SourceStream) then
+ begin
+ LockSampleBuffer();
+
+ // calc the time of source data that is buffered (in the SampleBuffer and SourceBuffer)
+ // but not yet outputed
+ BufferedTime := (SampleBufferCount - SampleBufferPos) / Engine.FormatInfo.BytesPerSec +
+ SourceBufferCount / SourceStream.GetAudioFormatInfo().BytesPerSec;
+ // and subtract it from the source position
+ Result := SourceStream.Position - BufferedTime;
+
+ UnlockSampleBuffer();
+ end
+ else
+ begin
+ Result := -1;
+ end;
+end;
+
+procedure TGenericPlaybackStream.SetPosition(Time: real);
+begin
+ if assigned(SourceStream) then
+ begin
+ LockSampleBuffer();
+
+ SourceStream.Position := Time;
+ if (Status = ssStopped) then
+ NeedsRewind := false;
+ // do not use outdated data
+ FlushBuffers();
+
+ AvgSyncDiff := -1;
+
+ UnlockSampleBuffer();
+ end;
+end;
+
+function TGenericPlaybackStream.GetVolume(): single;
+var
+ FadeAmount: Single;
+begin
+ LockSampleBuffer();
+ // adjust volume if fading is enabled
+ if (FadeInTime > 0) then
+ begin
+ FadeAmount := (SDL_GetTicks() - FadeInStartTime) / FadeInTime;
+ // check if fade-target is reached
+ if (FadeAmount >= 1) then
+ begin
+ // target reached -> stop fading
+ FadeInTime := 0;
+ fVolume := FadeInTargetVolume;
+ end
+ else
+ begin
+ // fading in progress
+ fVolume := FadeAmount*FadeInTargetVolume + (1-FadeAmount)*FadeInStartVolume;
+ end;
+ end;
+ // return current volume
+ Result := fVolume;
+ UnlockSampleBuffer();
+end;
+
+procedure TGenericPlaybackStream.SetVolume(Volume: single);
+begin
+ LockSampleBuffer();
+ // stop fading
+ FadeInTime := 0;
+ // clamp volume
+ if (Volume > 1.0) then
+ fVolume := 1.0
+ else if (Volume < 0) then
+ fVolume := 0
+ else
+ fVolume := Volume;
+ UnlockSampleBuffer();
+end;
+
+
+{ TGenericVoiceStream }
+
+constructor TGenericVoiceStream.Create(Engine: TAudioPlayback_SoftMixer);
+begin
+ inherited Create();
+ Self.Engine := Engine;
+end;
+
+function TGenericVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
+var
+ BufferSize: integer;
+begin
+ Result := false;
+
+ Close();
+
+ if (not inherited Open(ChannelMap, FormatInfo)) then
+ Exit;
+
+ // Note:
+ // - use Self.FormatInfo instead of FormatInfo as the latter one might have a
+ // channel size of 2.
+ // - the buffer-size must be a multiple of the FrameSize
+ BufferSize := (Ceil(MAX_VOICE_DELAY * Self.FormatInfo.BytesPerSec) div Self.FormatInfo.FrameSize) *
+ Self.FormatInfo.FrameSize;
+ VoiceBuffer := TRingBuffer.Create(BufferSize);
+
+ BufferLock := SDL_CreateMutex();
+
+
+ // create a matching playback stream for the voice-stream
+ PlaybackStream := TGenericPlaybackStream.Create(Engine);
+ // link voice- and playback-stream
+ if (not PlaybackStream.Open(Self)) then
+ begin
+ PlaybackStream.Free;
+ Exit;
+ end;
+
+ // start voice passthrough
+ PlaybackStream.Play();
+
+ Result := true;
+end;
+
+procedure TGenericVoiceStream.Close();
+begin
+ // stop and free the playback stream
+ FreeAndNil(PlaybackStream);
+
+ // free data
+ FreeAndNil(VoiceBuffer);
+ if (BufferLock <> nil) then
+ SDL_DestroyMutex(BufferLock);
+
+ inherited Close();
+end;
+
+procedure TGenericVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
+begin
+ // lock access to buffer
+ SDL_mutexP(BufferLock);
+ try
+ if (VoiceBuffer = nil) then
+ Exit;
+ VoiceBuffer.Write(Buffer, BufferSize);
+ finally
+ SDL_mutexV(BufferLock);
+ end;
+end;
+
+function TGenericVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+begin
+ Result := -1;
+
+ // lock access to buffer
+ SDL_mutexP(BufferLock);
+ try
+ if (VoiceBuffer = nil) then
+ Exit;
+ Result := VoiceBuffer.Read(Buffer, BufferSize);
+ finally
+ SDL_mutexV(BufferLock);
+ end;
+end;
+
+function TGenericVoiceStream.IsEOF(): boolean;
+begin
+ SDL_mutexP(BufferLock);
+ Result := (VoiceBuffer = nil);
+ SDL_mutexV(BufferLock);
+end;
+
+function TGenericVoiceStream.IsError(): boolean;
+begin
+ Result := false;
+end;
+
+
+{ TAudioPlayback_SoftMixer }
+
+function TAudioPlayback_SoftMixer.InitializePlayback: boolean;
+begin
+ Result := false;
+
+ //Log.LogStatus('InitializePlayback', 'UAudioPlayback_SoftMixer');
+
+ if(not InitializeAudioPlaybackEngine()) then
+ Exit;
+
+ MixerStream := TAudioMixerStream.Create(Self);
+
+ if(not StartAudioPlaybackEngine()) then
+ Exit;
+
+ Result := true;
+end;
+
+function TAudioPlayback_SoftMixer.FinalizePlayback: boolean;
+begin
+ Close;
+ StopAudioPlaybackEngine();
+
+ FreeAndNil(MixerStream);
+ FreeAndNil(FormatInfo);
+
+ FinalizeAudioPlaybackEngine();
+ inherited FinalizePlayback;
+ Result := true;
+end;
+
+procedure TAudioPlayback_SoftMixer.AudioCallback(Buffer: PChar; Size: integer);
+begin
+ MixerStream.ReadData(Buffer, Size);
+end;
+
+function TAudioPlayback_SoftMixer.GetMixer(): TAudioMixerStream;
+begin
+ Result := MixerStream;
+end;
+
+function TAudioPlayback_SoftMixer.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := FormatInfo;
+end;
+
+function TAudioPlayback_SoftMixer.CreatePlaybackStream(): TAudioPlaybackStream;
+begin
+ Result := TGenericPlaybackStream.Create(Self);
+end;
+
+function TAudioPlayback_SoftMixer.CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+var
+ VoiceStream: TGenericVoiceStream;
+begin
+ Result := nil;
+
+ // create a voice stream
+ VoiceStream := TGenericVoiceStream.Create(Self);
+ if (not VoiceStream.Open(ChannelMap, FormatInfo)) then
+ begin
+ VoiceStream.Free;
+ Exit;
+ end;
+
+ Result := VoiceStream;
+end;
+
+procedure TAudioPlayback_SoftMixer.SetAppVolume(Volume: single);
+begin
+ // sets volume only for this application
+ MixerStream.Volume := Volume;
+end;
+
+procedure TAudioPlayback_SoftMixer.MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single);
+var
+ SampleIndex: Cardinal;
+ SampleInt: Integer;
+ SampleFlt: Single;
+begin
+ SampleIndex := 0;
+ case FormatInfo.Format of
+ asfS16:
+ begin
+ while (SampleIndex < Size) do
+ begin
+ // apply volume and sum with previous mixer value
+ SampleInt := PSmallInt(@DstBuffer[SampleIndex])^ +
+ Round(PSmallInt(@SrcBuffer[SampleIndex])^ * Volume);
+ // clip result
+ if (SampleInt > High(SmallInt)) then
+ SampleInt := High(SmallInt)
+ else if (SampleInt < Low(SmallInt)) then
+ SampleInt := Low(SmallInt);
+ // assign result
+ PSmallInt(@DstBuffer[SampleIndex])^ := SampleInt;
+ // increase index by one sample
+ Inc(SampleIndex, SizeOf(SmallInt));
+ end;
+ end;
+ asfFloat:
+ begin
+ while (SampleIndex < Size) do
+ begin
+ // apply volume and sum with previous mixer value
+ SampleFlt := PSingle(@DstBuffer[SampleIndex])^ +
+ PSingle(@SrcBuffer[SampleIndex])^ * Volume;
+ // clip result
+ if (SampleFlt > 1.0) then
+ SampleFlt := 1.0
+ else if (SampleFlt < -1.0) then
+ SampleFlt := -1.0;
+ // assign result
+ PSingle(@DstBuffer[SampleIndex])^ := SampleFlt;
+ // increase index by one sample
+ Inc(SampleIndex, SizeOf(Single));
+ end;
+ end;
+ else
+ begin
+ Log.LogError('Incompatible format', 'TAudioMixerStream.MixAudio');
+ end;
+ end;
+end;
+
+end.
diff --git a/src/Classes/UCatCovers.pas b/src/Classes/UCatCovers.pas
new file mode 100644
index 00000000..d8f6cdb0
--- /dev/null
+++ b/src/Classes/UCatCovers.pas
@@ -0,0 +1,173 @@
+unit UCatCovers;
+/////////////////////////////////////////////////////////////////////////
+// UCatCovers by Whiteshark //
+// Class for listing and managing the Category Covers //
+/////////////////////////////////////////////////////////////////////////
+
+interface
+
+{$I switches.inc}
+
+uses UIni;
+
+type
+ TCatCovers = class
+ protected
+ cNames: array [0..high(ISorting)] of array of string;
+ cFiles: array [0..high(ISorting)] of array of string;
+ public
+ constructor Create;
+ procedure Load; //Load Cover aus Cover.ini and Cover Folder
+ procedure LoadPath(const CoversPath: string);
+ procedure Add(Sorting: integer; Name, Filename: string); //Add a Cover
+ function CoverExists(Sorting: integer; Name: string): boolean; //Returns True when a cover with the given Name exists
+ function GetCover(Sorting: integer; Name: string): string; //Returns the Filename of a Cover
+ end;
+
+var
+ CatCovers: TCatCovers;
+
+implementation
+
+uses
+ IniFiles,
+ SysUtils,
+ Classes,
+ // UFiles,
+ UMain,
+ ULog;
+
+constructor TCatCovers.Create;
+begin
+ inherited;
+ Load;
+end;
+
+procedure TCatCovers.Load;
+var
+ I: integer;
+begin
+ for I := 0 to CoverPaths.Count-1 do
+ LoadPath(CoverPaths[I]);
+end;
+
+(**
+ * Load Cover from Cover.ini and Cover Folder
+ *)
+procedure TCatCovers.LoadPath(const CoversPath: string);
+var
+ Ini: TMemIniFile;
+ SR: TSearchRec;
+ List: TStringlist;
+ I, J: Integer;
+ Name, Filename, Temp: string;
+begin
+ Ini := nil;
+ List := nil;
+
+ try
+ Ini := TMemIniFile.Create(CoversPath + 'covers.ini');
+ List := TStringlist.Create;
+
+ //Add every Cover in Covers Ini for Every Sorting option
+ for I := 0 to High(ISorting) do
+ begin
+ Ini.ReadSection(ISorting[I], List);
+
+ for J := 0 to List.Count - 1 do
+ Add(I, List.Strings[J], CoversPath + Ini.ReadString(ISorting[I], List.Strings[J], 'NoCover.jpg'));
+ end;
+ finally
+ Ini.Free;
+ List.Free;
+ end;
+
+ try
+ //Add Covers from Folder
+ if (FindFirst (CoversPath + '*.jpg', faAnyFile, SR) = 0) then
+ repeat
+ //Add Cover if it doesn't exist for every Section
+ Name := SR.Name;
+ Filename := CoversPath + Name;
+ Delete (Name, length(Name) - 3, 4);
+
+ for I := 0 to high(ISorting) do
+ begin
+ Temp := Name;
+ if ((I = sTitle) or (I = sTitle2)) and (Pos ('Title', Temp) <> 0) then
+ Delete (Temp, Pos ('Title', Temp), 5)
+ else if (I = sArtist) or (I = sArtist2) and (Pos ('Artist', Temp) <> 0) then
+ Delete (Temp, Pos ('Artist', Temp), 6);
+
+ if not CoverExists(I, Temp) then
+ Add (I, Temp, Filename);
+ end;
+ until FindNext (SR) <> 0;
+ finally
+ FindClose (SR);
+ end;
+end;
+
+ //Add a Cover
+procedure TCatCovers.Add(Sorting: integer; Name, Filename: string);
+begin
+ if FileExists (Filename) then //If Exists -> Add
+ begin
+ SetLength (CNames[Sorting], Length(CNames[Sorting]) + 1);
+ SetLength (CFiles[Sorting], Length(CNames[Sorting]) + 1);
+
+ CNames[Sorting][high(cNames[Sorting])] := Uppercase(Name);
+ CFiles[Sorting][high(cNames[Sorting])] := FileName;
+ end;
+end;
+
+ //Returns True when a cover with the given Name exists
+function TCatCovers.CoverExists(Sorting: integer; Name: string): boolean;
+var
+ I: Integer;
+begin
+ Result := False;
+ Name := Uppercase(Name); //Case Insensitiv
+
+ for I := 0 to high(cNames[Sorting]) do
+ begin
+ if (cNames[Sorting][I] = Name) then //Found Name
+ begin
+ Result := true;
+ break; //Break For Loop
+ end;
+ end;
+end;
+
+ //Returns the Filename of a Cover
+function TCatCovers.GetCover(Sorting: integer; Name: string): string;
+var
+ I: Integer;
+begin
+ Result := '';
+ Name := Uppercase(Name);
+
+ for I := 0 to high(cNames[Sorting]) do
+ begin
+ if cNames[Sorting][I] = Name then
+ begin
+ Result := cFiles[Sorting][I];
+ Break;
+ end;
+ end;
+
+ //No Cover
+ if (Result = '') then
+ begin
+ for I := 0 to CoverPaths.Count-1 do
+ begin
+ if (FileExists(CoverPaths[I] + 'NoCover.jpg')) then
+ begin
+ Result := CoverPaths[I] + 'NoCover.jpg';
+ Break;
+ end;
+ end;
+ end;
+end;
+
+end.
diff --git a/src/Classes/UCommandLine.pas b/src/Classes/UCommandLine.pas
new file mode 100644
index 00000000..3c56c606
--- /dev/null
+++ b/src/Classes/UCommandLine.pas
@@ -0,0 +1,339 @@
+unit UCommandLine;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+type
+ //-----------
+ // TCMDParams - Class Reads Infos from ParamStr and set some easy Interface Variables
+ //-----------
+ TCMDParams = class
+ private
+ sLanguage: String;
+ sResolution: String;
+ public
+ //Some Boolean Variables Set when Reading Infos
+ Debug: Boolean;
+ Benchmark: Boolean;
+ NoLog: Boolean;
+ FullScreen: Boolean;
+ Joypad: Boolean;
+
+ //Some Value Variables Set when Reading Infos {-1: Not Set, others: Value}
+ Depth: Integer;
+ Screens: Integer;
+
+ //Some Strings Set when Reading Infos {Length=0 Not Set}
+ SongPath: String;
+ ConfigFile: String;
+ ScoreFile: String;
+
+ procedure showhelp();
+
+ //Pseudo Integer Values
+ Function GetLanguage: Integer;
+ Property Language: Integer read GetLanguage;
+
+ Function GetResolution: Integer;
+ Property Resolution: Integer read GetResolution;
+
+ //Some Procedures for Reading Infos
+ Constructor Create;
+
+ Procedure ResetVariables;
+ Procedure ReadParamInfo;
+ end;
+
+var
+ Params: TCMDParams;
+
+const
+ cHelp = 'help';
+ cDebug = 'debug';
+ cMediaInterfaces = 'showinterfaces';
+ cUseLocalPaths = 'localpaths';
+
+
+implementation
+
+uses SysUtils,
+ uPlatform;
+// uINI -- Nasty requirement... ( removed with permission of blindy )
+
+
+//-------------
+// Constructor - Create class, Reset Variables and Read Infos
+//-------------
+Constructor TCMDParams.Create;
+begin
+ inherited;
+
+ if FindCmdLineSwitch( cHelp ) or FindCmdLineSwitch( 'h' ) then
+ showhelp();
+
+ ResetVariables;
+ ReadParamInfo;
+end;
+
+procedure TCMDParams.showhelp();
+
+ function s( aString : String ) : string;
+ begin
+ result := aString + StringofChar( ' ', 15 - length( aString ) );
+ end;
+
+begin
+
+ writeln( '' );
+ writeln( '**************************************************************' );
+ writeln( ' UltraStar Deluxe - Command line switches ' );
+ writeln( '**************************************************************' );
+ writeln( '' );
+ writeln( ' '+s( 'Switch' ) +' : Purpose' );
+ writeln( ' ----------------------------------------------------------' );
+ writeln( ' '+s( cMediaInterfaces ) + #9 + ' : Show in-use media interfaces' );
+ writeln( ' '+s( cUseLocalPaths ) + #9 + ' : Use relative paths' );
+ writeln( ' '+s( cDebug ) + #9 + ' : Display Debugging info' );
+
+
+
+ writeln( '' );
+
+ platform.halt;
+end;
+
+//-------------
+// ResetVariables - Reset Class Variables
+//-------------
+Procedure TCMDParams.ResetVariables;
+begin
+ Debug := False;
+ Benchmark := False;
+ NoLog := False;
+ FullScreen := False;
+ Joypad := False;
+
+ //Some Value Variables Set when Reading Infos {-1: Not Set, others: Value}
+ sResolution := '';
+ sLanguage := '';
+ Depth := -1;
+ Screens := -1;
+
+ //Some Strings Set when Reading Infos {Length=0 Not Set}
+ SongPath := '';
+ ConfigFile := '';
+ ScoreFile := '';
+end;
+
+//-------------
+// ReadParamInfo - Read Infos from Parameters
+//-------------
+Procedure TCMDParams.ReadParamInfo;
+var
+ I: Integer;
+ PCount: Integer;
+ Command: String;
+begin
+ PCount := ParamCount;
+ //Log.LogError('ParamCount: ' + Inttostr(PCount));
+
+
+ //Check all Parameters
+ For I := 1 to PCount do
+ begin
+ Command := Paramstr(I);
+ //Log.LogError('Start parsing Command: ' + Command);
+ //Is String Parameter ?
+ if (Length(Command) > 1) AND (Command[1] = '-') then
+ begin
+ //Remove - from Command
+ Command := Lowercase(Trim(Copy(Command, 2, Length(Command) - 1)));
+ //Log.LogError('Command prepared: ' + Command);
+
+ //Check Command
+
+ // Boolean Triggers:
+ if (Command = 'debug') then
+ Debug := True
+ else if (Command = 'benchmark') then
+ Benchmark := True
+ else if (Command = 'nolog') then
+ NoLog := True
+ else if (Command = 'fullscreen') then
+ Fullscreen := True
+ else if (Command = 'window') then
+ Fullscreen := False
+ else if (Command = 'joypad') then
+ Joypad := True
+
+ //Integer Variables
+ else if (Command = 'depth') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ Command := ParamStr(I + 1);
+
+ //Check for valid Value
+ If (Command = '16') then
+ Depth := 0
+ Else If (Command = '32') then
+ Depth := 1;
+ end;
+ end
+
+ else if (Command = 'screens') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ Command := ParamStr(I + 1);
+
+ //Check for valid Value
+ If (Command = '1') then
+ Screens := 0
+ Else If (Command = '2') then
+ Screens := 1;
+ end;
+ end
+
+ //Pseudo Integer Values
+ else if (Command = 'language') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ //Write Value to String
+ sLanguage := Lowercase(ParamStr(I + 1));
+ end;
+ end
+
+ else if (Command = 'resolution') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ //Write Value to String
+ sResolution := Lowercase(ParamStr(I + 1));
+ end;
+ end
+
+ //String Values
+ else if (Command = 'songpath') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ //Write Value to String
+ SongPath := ParamStr(I + 1);
+ end;
+ end
+
+ else if (Command = 'configfile') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ //Write Value to String
+ ConfigFile := ParamStr(I + 1);
+
+ //is this a relative PAth -> then add Gamepath
+ if Not ((Length(ConfigFile) > 2) AND (ConfigFile[2] = ':')) then
+ ConfigFile := ExtractFilePath(ParamStr(0)) + Configfile;
+ end;
+ end
+
+ else if (Command = 'scorefile') then
+ begin
+ //Check if there is another Parameter to get the Value from
+ if (PCount > I) then
+ begin
+ //Write Value to String
+ ScoreFile := ParamStr(I + 1);
+ end;
+ end;
+
+ end;
+
+ end;
+
+{ Log.LogError('Values: ');
+
+ if Debug then
+ Log.LogError('Debug');
+
+ if Benchmark then
+ Log.LogError('Benchmark');
+
+ if NoLog then
+ Log.LogError('NoLog');
+
+ if Fullscreen then
+ Log.LogError('FullScreen');
+
+ if JoyStick then
+ Log.LogError('Joystick');
+
+
+ Log.LogError('Screens: ' + Inttostr(Screens));
+ Log.LogError('Depth: ' + Inttostr(Depth));
+
+ Log.LogError('Resolution: ' + Inttostr(Resolution));
+ Log.LogError('Resolution: ' + Inttostr(Language));
+
+ Log.LogError('sResolution: ' + sResolution);
+ Log.LogError('sLanguage: ' + sLanguage);
+
+ Log.LogError('ConfigFile: ' + ConfigFile);
+ Log.LogError('SongPath: ' + SongPath);
+ Log.LogError('ScoreFile: ' + ScoreFile); }
+
+end;
+
+//-------------
+// GetLanguage - Get Language ID from saved String Information
+//-------------
+Function TCMDParams.GetLanguage: Integer;
+var
+ I: integer;
+begin
+ Result := -1;
+{* JB - 12sep07 to remove uINI dependency
+
+ //Search for Language
+ For I := 0 to high(ILanguage) do
+ if (LowerCase(ILanguage[I]) = sLanguage) then
+ begin
+ Result := I;
+ Break;
+ end;
+*}
+end;
+
+//-------------
+// GetResolution - Get Resolution ID from saved String Information
+//-------------
+Function TCMDParams.GetResolution: Integer;
+var
+ I: integer;
+begin
+ Result := -1;
+{* JB - 12sep07 to remove uINI dependency
+
+ //Search for Resolution
+ For I := 0 to high(IResolution) do
+ if (LowerCase(IResolution[I]) = sResolution) then
+ begin
+ Result := I;
+ Break;
+ end;
+*}
+end;
+
+end.
diff --git a/src/Classes/UCommon.pas b/src/Classes/UCommon.pas
new file mode 100644
index 00000000..41e3c1f1
--- /dev/null
+++ b/src/Classes/UCommon.pas
@@ -0,0 +1,774 @@
+unit UCommon;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ Classes,
+ {$IFDEF MSWINDOWS}
+ Windows,
+ {$ENDIF}
+ sdl,
+ UConfig,
+ ULog;
+
+type
+ TMessageType = ( mtInfo, mtError );
+
+procedure ShowMessage( const msg : String; msgType: TMessageType = mtInfo );
+
+procedure ConsoleWriteLn(const msg: string);
+
+function GetResourceStream(const aName, aType : string): TStream;
+function RWopsFromStream(Stream: TStream): PSDL_RWops;
+
+{$IFDEF FPC}
+function RandomRange(aMin: Integer; aMax: Integer) : Integer;
+{$ENDIF}
+
+function StringReplaceW(text : WideString; search, rep: WideChar):WideString;
+function AdaptFilePaths( const aPath : widestring ): widestring;
+
+procedure DisableFloatingPointExceptions();
+procedure SetDefaultNumericLocale();
+procedure RestoreNumericLocale();
+
+{$IFNDEF MSWINDOWS}
+ procedure ZeroMemory( Destination: Pointer; Length: DWORD );
+ function MakeLong(a, b: Word): Longint;
+ (*
+ #define LOBYTE(a) (BYTE)(a)
+ #define HIBYTE(a) (BYTE)((a)>>8)
+ #define LOWORD(a) (WORD)(a)
+ #define HIWORD(a) (WORD)((a)>>16)
+ #define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8))
+ *)
+{$ENDIF}
+
+function FileExistsInsensitive(var FileName: string): boolean;
+
+(*
+ * 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;
+
+// A stable alternative to TList.Sort() (use TList.Sort() if applicable, see below)
+procedure MergeSort(List: TList; CompareFunc: TListSortCompare);
+
+function GetAlignedMem(Size: cardinal; Alignment: integer): Pointer;
+procedure FreeAlignedMem(P: Pointer);
+
+
+implementation
+
+uses
+ Math,
+ {$IFDEF Delphi}
+ Dialogs,
+ {$ENDIF}
+ UMain;
+
+
+// data used by the ...Locale() functions
+{$IFDEF LINUX}
+
+var
+ PrevNumLocale: string;
+
+const
+ LC_NUMERIC = 1;
+
+function setlocale(category: integer; locale: pchar): pchar; cdecl; external 'c' name 'setlocale';
+
+{$ENDIF}
+
+// In Linux and maybe MacOSX some units (like cwstring) call setlocale(LC_ALL, '')
+// to set the language/country specific locale (e.g. charset) for this application.
+// Unfortunately, LC_NUMERIC is set by this call too.
+// It defines the decimal-separator and other country-specific numeric settings.
+// This parameter is used by the C string-to-float parsing functions atof() and strtod().
+// After changing LC_NUMERIC some external C-based libs (like projectM) are not
+// able to parse strings correctly
+// (e.g. in Germany "0.9" is not recognized as a valid number anymore but "0,9" is).
+// So we reset the numeric settings to the default ('C').
+// Note: The behaviour of Pascal parsing functions (e.g. strtofloat()) is not
+// changed by this because it doesn't use the locale-settings.
+// TODO:
+// - Check if this is needed in MacOSX (at least the locale is set in cwstring)
+// - Find out which libs are concerned by this problem.
+// If only projectM is concerned by this problem set and restore the numeric locale
+// for each call to projectM instead of changing it globally.
+procedure SetDefaultNumericLocale();
+begin
+ {$ifdef LINUX}
+ PrevNumLocale := setlocale(LC_NUMERIC, nil);
+ setlocale(LC_NUMERIC, 'C');
+ {$endif}
+end;
+
+procedure RestoreNumericLocale();
+begin
+ {$ifdef LINUX}
+ setlocale(LC_NUMERIC, PChar(PrevNumLocale));
+ {$endif}
+end;
+
+(*
+ * If an invalid floating point operation was performed the Floating-point unit (FPU)
+ * generates a Floating-point exception (FPE). Dependending on the settings in
+ * the FPU's control-register (interrupt mask) the FPE is handled by the FPU itself
+ * (we will call this as "FPE disabled" later on) or is passed to the application
+ * (FPE enabled).
+ * If FPEs are enabled a floating-point division by zero (e.g. 10.0 / 0.0) is
+ * considered an error and an exception is thrown. Otherwise the FPU will handle
+ * the error and return the result infinity (INF) (10.0 / 0.0 = INF) without
+ * throwing an error to the application.
+ * The same applies to a division by INF that either raises an exception
+ * (FPE enabled) or returns 0.0 (FPE disabled).
+ * Normally (as with C-programs), Floating-point exceptions (FPE) are DISABLED
+ * on program startup (at least with Intel CPUs), but for some strange reasons
+ * they are ENABLED in pascal (both delphi and FPC) by default.
+ * Many libs operating with floating-point values rely heavily on the C-specific
+ * behaviour. So using them in delphi is a ticking time-bomb because sooner or
+ * later they will crash because of an FPE (this problem occurs massively
+ * in OpenGL-based libs like projectM). In contrast to this no error will occur
+ * if the lib is linked to a C-program.
+ *
+ * Further info on FPUs:
+ * For x86 and x86_64 CPUs we have to consider two FPU instruction sets.
+ * The math co-processor i387 (aka 8087 or x87) set introduced with the i386
+ * and SSE (Streaming SIMD Extensions) introduced with the Pentium3.
+ * Both of them have separate control-registers (x87: FPUControlWord, SSE: MXCSR)
+ * to control FPEs. Either has (among others) 6bits to enable/disable several
+ * exception types (Invalid,Denormalized,Zero,Overflow,Underflow,Precision).
+ * Those exception-types must all be masked (=1) to get the default C behaviour.
+ * The control-registers can be set with the asm-ops FLDCW (x87) and LDMXCSR (SSE).
+ * Instead of using assembler code, we can use Set8087CW() provided by delphi and
+ * FPC to set the x87 control-word. FPC also provides SetSSECSR() for SSE's MXCSR.
+ * Note that both Delphi and FPC enable FPEs (e.g. for div-by-zero) on program
+ * startup but only FPC enables FPEs (especially div-by-zero) for SSE too.
+ * So we have to mask FPEs for x87 in Delphi and FPC and for SSE in FPC only.
+ * FPC and Delphi both provide a SetExceptionMask() for control of the FPE
+ * mask. SetExceptionMask() sets the masks for x87 in Delphi and for x87 and SSE
+ * in FPC (seems as if Delphi [2005] is not SSE aware). So SetExceptionMask()
+ * is what we need and it even is plattform and CPU independent.
+ *
+ * Pascal OpenGL headers (like the Delphi standard ones or JEDI-SDL headers)
+ * already call Set8087CW() to disable FPEs but due to some bugs in the JEDI-SDL
+ * headers they do not work properly with FPC. I already patched them, so they
+ * work at least until they are updated the next time. In addition Set8086CW()
+ * does not suffice to disable FPEs because the SSE FPEs are not disabled by this.
+ * FPEs with SSE are a big problem with some libs because many linux distributions
+ * optimize code for SSE or Pentium3 (for example: int(INF) which convert the
+ * double value "infinity" to an integer might be automatically optimized by
+ * using SSE's CVTSD2SI instruction). So SSE FPEs must be turned off in any case
+ * to make USDX portable.
+ *
+ * Summary:
+ * Call this function on initialization to make sure FPEs are turned off.
+ * It will solve a lot of errors with FPEs in external libs.
+ *)
+procedure DisableFloatingPointExceptions();
+begin
+ (*
+ // We will use SetExceptionMask() instead of Set8087CW()/SetSSECSR().
+ // Note: Leave these lines for documentation purposes just in case
+ // SetExceptionMask() does not work anymore (due to bugs in FPC etc.).
+ {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
+ Set8087CW($133F);
+ {$IFEND}
+ {$IF Defined(FPC)}
+ if (has_sse_support) then
+ SetSSECSR($1F80);
+ {$IFEND}
+ *)
+
+ // disable all of the six FPEs (x87 and SSE) to be compatible with C/C++ and
+ // other libs which rely on the standard FPU behaviour (no div-by-zero FPE anymore).
+ SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,
+ exOverflow, exUnderflow, exPrecision]);
+end;
+
+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 := 1 to length(result) 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 MSWINDOWS}
+procedure ZeroMemory( Destination: Pointer; Length: DWORD );
+begin
+ FillChar( Destination^, Length, 0 );
+end;
+
+function MakeLong(A, B: Word): Longint;
+begin
+ Result := (LongInt(B) shl 16) + A;
+end;
+
+(*
+function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
+
+ // From http://en.wikipedia.org/wiki/RDTSC
+ function RDTSC: Int64; register;
+ asm
+ rdtsc
+ end;
+
+begin
+ // Use clock_gettime(CLOCK_REALTIME, ...) here (but not from the libc unit)
+ lpPerformanceCount := RDTSC();
+ result := true;
+end;
+
+function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
+begin
+ // clock_getres(CLOCK_REALTIME, ...)
+ lpFrequency := 0;
+ result := true;
+end;
+*)
+{$ENDIF}
+
+// Checks if a regular files or directory with the given name exists.
+// The comparison is case insensitive.
+function FileExistsInsensitive(var FileName: string): boolean;
+var
+ FilePath, LocalFileName: string;
+ SearchInfo: TSearchRec;
+begin
+{$IFDEF LINUX} // eddie: Changed FPC to LINUX: Windows and Mac OS X dont have case sensitive file systems
+ // speed up standard case
+ if FileExists(FileName) then
+ begin
+ Result := true;
+ exit;
+ end;
+
+ Result := false;
+
+ FilePath := ExtractFilePath(FileName);
+ if (FindFirst(FilePath+'*', faAnyFile, SearchInfo) = 0) then
+ begin
+ LocalFileName := ExtractFileName(FileName);
+ repeat
+ if (AnsiSameText(LocalFileName, SearchInfo.Name)) then
+ begin
+ FileName := FilePath + SearchInfo.Name;
+ Result := true;
+ break;
+ end;
+ until (FindNext(SearchInfo) <> 0);
+ end;
+ FindClose(SearchInfo);
+{$ELSE}
+ Result := FileExists(FileName);
+{$ENDIF}
+end;
+
+
+{$IFDEF Unix}
+ // include resource-file info (stored in the constant array "resources")
+ {$I ../resource.inc}
+{$ENDIF}
+
+function GetResourceStream(const aName, aType: string): TStream;
+{$IFDEF Unix}
+var
+ ResIndex: integer;
+ Filename: string;
+{$ENDIF}
+begin
+ Result := nil;
+
+ {$IFDEF Unix}
+ for ResIndex := 0 to High(resources) do
+ begin
+ if (resources[ResIndex][0] = aName ) and
+ (resources[ResIndex][1] = aType ) then
+ begin
+ try
+ Filename := ResourcesPath + resources[ResIndex][2];
+ Result := TFileStream.Create(Filename, fmOpenRead);
+ except
+ Log.LogError('Failed to open: "'+ resources[ResIndex][2] +'"', 'GetResourceStream');
+ end;
+ exit;
+ end;
+ end;
+ {$ELSE}
+ try
+ Result := TResourceStream.Create(HInstance, aName , PChar(aType));
+ except
+ Log.LogError('Invalid resource: "'+ aType + ':' + aName +'"', 'GetResourceStream');
+ end;
+ {$ENDIF}
+end;
+
+// +++++++++++++++++++++ helpers for RWOpsFromStream() +++++++++++++++
+ function SdlStreamSeek( context : PSDL_RWops; offset : Integer; whence : Integer ) : integer; cdecl;
+ var
+ stream : TStream;
+ origin : Word;
+ begin
+ stream := TStream( context.unknown );
+ if ( stream = nil ) then
+ raise EInvalidContainer.Create( 'SDLStreamSeek on nil' );
+ case whence of
+ 0 : origin := soFromBeginning; // Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
+ 1 : origin := soFromCurrent; // Offset is from the current position in the resource. Seek moves to Position + Offset.
+ 2 : origin := soFromEnd;
+ else
+ origin := soFromBeginning; // just in case
+ end;
+ Result := stream.Seek( offset, origin );
+ end;
+
+ function SdlStreamRead( context : PSDL_RWops; Ptr : Pointer; size : Integer; maxnum: Integer ) : Integer; cdecl;
+ var
+ stream : TStream;
+ begin
+ stream := TStream( context.unknown );
+ if ( stream = nil ) then
+ raise EInvalidContainer.Create( 'SDLStreamRead on nil' );
+ try
+ Result := stream.read( Ptr^, Size * maxnum ) div size;
+ except
+ Result := -1;
+ end;
+ end;
+
+ function SDLStreamClose( context : PSDL_RWops ) : Integer; cdecl;
+ var
+ stream : TStream;
+ begin
+ stream := TStream( context.unknown );
+ if ( stream = nil ) then
+ raise EInvalidContainer.Create( 'SDLStreamClose on nil' );
+ stream.Free;
+ Result := 1;
+ end;
+// -----------------------------------------------
+
+(*
+ * Creates an SDL_RWops handle from a TStream.
+ * The stream and RWops must be freed by the user after usage.
+ * Use SDL_FreeRW(...) to free the RWops data-struct.
+ *)
+function RWopsFromStream(Stream: TStream): PSDL_RWops;
+begin
+ Result := SDL_AllocRW();
+ if (Result = nil) then
+ Exit;
+
+ // set RW-callbacks
+ with Result^ do
+ begin
+ unknown := TUnknown(Stream);
+ seek := SDLStreamSeek;
+ read := SDLStreamRead;
+ write := nil;
+ close := SDLStreamClose;
+ type_ := 2;
+ end;
+end;
+
+
+
+{$IFDEF FPC}
+function RandomRange(aMin: Integer; aMax: Integer) : Integer;
+begin
+ RandomRange := Random(aMax-aMin) + aMin ;
+end;
+{$ENDIF}
+
+
+{$IFDEF FPC}
+var
+ MessageList: TStringList;
+ ConsoleHandler: TThreadID;
+ // Note: TRTLCriticalSection is defined in the units System and Libc, use System one
+ ConsoleCriticalSection: System.TRTLCriticalSection;
+ ConsoleEvent: PRTLEvent;
+ ConsoleQuit: boolean;
+{$ENDIF}
+
+(*
+ * Write to console if one is available.
+ * It checks if a console is available before output so it will not
+ * crash on windows if none is available.
+ * Do not use this function directly because it is not thread-safe,
+ * use ConsoleWriteLn() instead.
+ *)
+procedure _ConsoleWriteLn(const aString: string); {$IFDEF HasInline}inline;{$ENDIF}
+begin
+ {$IFDEF MSWINDOWS}
+ // sanity check to avoid crashes with writeln()
+ if (IsConsole) then
+ begin
+ {$ENDIF}
+ Writeln(aString);
+ {$IFDEF MSWINDOWS}
+ end;
+ {$ENDIF}
+end;
+
+{$IFDEF FPC}
+{*
+ * The console-handlers main-function.
+ * TODO: create a quit-event on closing.
+ *}
+function ConsoleHandlerFunc(param: pointer): PtrInt;
+var
+ i: integer;
+ quit: boolean;
+begin
+ quit := false;
+ while (not quit) do
+ begin
+ // wait for new output or quit-request
+ RTLeventWaitFor(ConsoleEvent);
+
+ System.EnterCriticalSection(ConsoleCriticalSection);
+ // output pending messages
+ for i := 0 to MessageList.Count-1 do
+ begin
+ _ConsoleWriteLn(MessageList[i]);
+ end;
+ MessageList.Clear();
+
+ // use local quit-variable to avoid accessing
+ // ConsoleQuit outside of the critical section
+ if (ConsoleQuit) then
+ quit := true;
+
+ RTLeventResetEvent(ConsoleEvent);
+ System.LeaveCriticalSection(ConsoleCriticalSection);
+ end;
+ result := 0;
+end;
+{$ENDIF}
+
+procedure InitConsoleOutput();
+begin
+ {$IFDEF FPC}
+ // init thread-safe output
+ MessageList := TStringList.Create();
+ System.InitCriticalSection(ConsoleCriticalSection);
+ ConsoleEvent := RTLEventCreate();
+ ConsoleQuit := false;
+ // must be a thread managed by FPC. Otherwise (e.g. SDL-thread)
+ // it will crash when using Writeln.
+ ConsoleHandler := BeginThread(@ConsoleHandlerFunc);
+ {$ENDIF}
+end;
+
+procedure FinalizeConsoleOutput();
+begin
+ {$IFDEF FPC}
+ // terminate console-handler
+ System.EnterCriticalSection(ConsoleCriticalSection);
+ ConsoleQuit := true;
+ RTLeventSetEvent(ConsoleEvent);
+ System.LeaveCriticalSection(ConsoleCriticalSection);
+ WaitForThreadTerminate(ConsoleHandler, 0);
+ // free data
+ System.DoneCriticalsection(ConsoleCriticalSection);
+ RTLeventDestroy(ConsoleEvent);
+ MessageList.Free();
+ {$ENDIF}
+end;
+
+{*
+ * With FPC console output is not thread-safe.
+ * Using WriteLn() from external threads (like in SDL callbacks)
+ * will damage the heap and crash the program.
+ * Most probably FPC uses thread-local-data (TLS) to lock a mutex on
+ * the console-buffer. This does not work with external lib's threads
+ * because these do not have the TLS data and so it crashes while
+ * accessing unallocated memory.
+ * The solution is to create an FPC-managed thread which has the TLS data
+ * and use it to handle the console-output (hence it is called Console-Handler)
+ * It should be safe to do so, but maybe FPC requires the main-thread to access
+ * the console-buffer only. In this case output should be delegated to it.
+ *
+ * TODO: - check if it is safe if an FPC-managed thread different than the
+ * main-thread accesses the console-buffer in FPC.
+ * - check if Delphi's WriteLn is thread-safe.
+ * - check if we need to synchronize file-output too
+ *}
+procedure ConsoleWriteLn(const msg: string);
+begin
+{$IFDEF CONSOLE}
+ {$IFDEF FPC}
+ // TODO: check for the main-thread and use a simple _ConsoleWriteLn() then?
+ //GetCurrentThreadThreadId();
+ System.EnterCriticalSection(ConsoleCriticalSection);
+ MessageList.Add(msg);
+ RTLeventSetEvent(ConsoleEvent);
+ System.LeaveCriticalSection(ConsoleCriticalSection);
+ {$ELSE}
+ _ConsoleWriteLn(msg);
+ {$ENDIF}
+{$ENDIF}
+end;
+
+procedure ShowMessage(const msg: String; msgType: TMessageType);
+{$IFDEF MSWINDOWS}
+var Flags: Cardinal;
+{$ENDIF}
+begin
+{$IF Defined(MSWINDOWS)}
+ case msgType of
+ mtInfo: Flags := MB_ICONINFORMATION or MB_OK;
+ mtError: Flags := MB_ICONERROR or MB_OK;
+ else Flags := MB_OK;
+ end;
+ MessageBox(0, PChar(msg), PChar(USDXVersionStr()), Flags);
+{$ELSE}
+ ConsoleWriteln(msg);
+{$IFEND}
+end;
+
+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;
+
+(*
+ * Recursive part of the MergeSort algorithm.
+ * OutList will be either InList or TempList and will be swapped in each
+ * depth-level of recursion. By doing this it we can directly merge into the
+ * output-list. If we only had In- and OutList parameters we had to merge into
+ * InList after the recursive calls and copy the data to the OutList afterwards.
+ *)
+procedure _MergeSort(InList, TempList, OutList: TList; StartPos, BlockSize: integer;
+ CompareFunc: TListSortCompare);
+var
+ LeftSize, RightSize: integer; // number of elements in left/right block
+ LeftEnd, RightEnd: integer; // Index after last element in left/right block
+ MidPos: integer; // index of first element in right block
+ Pos: integer; // position in output list
+begin
+ LeftSize := BlockSize div 2;
+ RightSize := BlockSize - LeftSize;
+ MidPos := StartPos + LeftSize;
+
+ // sort left and right halves of this block by recursive calls of this function
+ if (LeftSize >= 2) then
+ _MergeSort(InList, OutList, TempList, StartPos, LeftSize, CompareFunc)
+ else
+ TempList[StartPos] := InList[StartPos];
+ if (RightSize >= 2) then
+ _MergeSort(InList, OutList, TempList, MidPos, RightSize, CompareFunc)
+ else
+ TempList[MidPos] := InList[MidPos];
+
+ // merge sorted left and right sub-lists into output-list
+ LeftEnd := MidPos;
+ RightEnd := StartPos + BlockSize;
+ Pos := StartPos;
+ while ((StartPos < LeftEnd) and (MidPos < RightEnd)) do
+ begin
+ if (CompareFunc(TempList[StartPos], TempList[MidPos]) <= 0) then
+ begin
+ OutList[Pos] := TempList[StartPos];
+ Inc(StartPos);
+ end
+ else
+ begin
+ OutList[Pos] := TempList[MidPos];
+ Inc(MidPos);
+ end;
+ Inc(Pos);
+ end;
+
+ // copy remaining elements to output-list
+ while (StartPos < LeftEnd) do
+ begin
+ OutList[Pos] := TempList[StartPos];
+ Inc(StartPos);
+ Inc(Pos);
+ end;
+ while (MidPos < RightEnd) do
+ begin
+ OutList[Pos] := TempList[MidPos];
+ Inc(MidPos);
+ Inc(Pos);
+ end;
+end;
+
+(*
+ * Stable alternative to the instable TList.Sort() (uses QuickSort) implementation.
+ * A stable sorting algorithm preserves preordered items. E.g. if sorting by
+ * songs by title first and artist afterwards, the songs of each artist will
+ * be ordered by title. In contrast to this an unstable algorithm (like QuickSort)
+ * may destroy an existing order, so the songs of an artist will not be ordered
+ * by title anymore after sorting by artist in the previous example.
+ * If you do not need a stable algorithm, use TList.Sort() instead.
+ *)
+procedure MergeSort(List: TList; CompareFunc: TListSortCompare);
+var
+ TempList: TList;
+begin
+ TempList := TList.Create();
+ TempList.Count := List.Count;
+ if (List.Count >= 2) then
+ _MergeSort(List, TempList, List, 0, List.Count, CompareFunc);
+ TempList.Free;
+end;
+
+
+type
+ // stores the unaligned pointer of data allocated by GetAlignedMem()
+ PMemAlignHeader = ^TMemAlignHeader;
+ TMemAlignHeader = Pointer;
+
+(**
+ * Use this function to assure that allocated memory is aligned on a specific
+ * byte boundary.
+ * Alignment must be a power of 2.
+ *
+ * Important: Memory allocated with GetAlignedMem() MUST be freed with
+ * FreeAlignedMem(), FreeMem() will cause a segmentation fault.
+ *
+ * Hint: If you do not need dynamic memory, consider to allocate memory
+ * statically and use the {$ALIGN x} compiler directive. Note that delphi
+ * supports an alignment "x" of up to 8 bytes only whereas FPC supports
+ * alignments on 16 and 32 byte boundaries too.
+ *)
+{$WARNINGS OFF}
+function GetAlignedMem(Size: cardinal; Alignment: integer): Pointer;
+var
+ OrigPtr: Pointer;
+const
+ MIN_ALIGNMENT = 16;
+begin
+ // Delphi and FPC (tested with 2.2.0) align memory blocks allocated with
+ // GetMem() at least on 8 byte boundaries. Delphi uses a minimal alignment
+ // of either 8 or 16 bytes depending on the size of the requested block
+ // (see System.GetMinimumBlockAlignment). As we do not want to change the
+ // boundary for the worse, we align at least on MIN_ALIGN.
+ if (Alignment < MIN_ALIGNMENT) then
+ Alignment := MIN_ALIGNMENT;
+
+ // allocate unaligned memory
+ GetMem(OrigPtr, SizeOf(TMemAlignHeader) + Size + Alignment);
+ if (OrigPtr = nil) then
+ begin
+ Result := nil;
+ Exit;
+ end;
+
+ // reserve space for the header
+ Result := Pointer(PtrUInt(OrigPtr) + SizeOf(TMemAlignHeader));
+ // align memory
+ Result := Pointer(PtrUInt(Result) + Alignment - PtrUInt(Result) mod Alignment);
+
+ // set header with info on old pointer for FreeMem
+ PMemAlignHeader(PtrUInt(Result) - SizeOf(TMemAlignHeader))^ := OrigPtr;
+end;
+{$WARNINGS ON}
+
+{$WARNINGS OFF}
+procedure FreeAlignedMem(P: Pointer);
+begin
+ if (P <> nil) then
+ FreeMem(PMemAlignHeader(PtrUInt(P) - SizeOf(TMemAlignHeader))^);
+end;
+{$WARNINGS ON}
+
+
+initialization
+ InitConsoleOutput();
+
+finalization
+ FinalizeConsoleOutput();
+
+end.
diff --git a/src/Classes/UConfig.pas b/src/Classes/UConfig.pas
new file mode 100644
index 00000000..b77c2a5a
--- /dev/null
+++ b/src/Classes/UConfig.pas
@@ -0,0 +1,199 @@
+unit UConfig;
+
+// -------------------------------------------------------------------
+// Note on version comparison (for developers only):
+// -------------------------------------------------------------------
+// Delphi (in contrast to FPC) DOESN'T support MACROS. So we
+// can't define a macro like VERSION_MAJOR(version) to extract
+// parts of the version-number or to create version numbers for
+// comparison purposes as with a MAKE_VERSION(maj, min, rev) macro.
+// So we have to define constants for every part of the version here.
+//
+// In addition FPC (in contrast to delphi) DOES NOT support floating-
+// point numbers in $IF compiler-directives (e.g. {$IF VERSION > 1.23})
+// It also DOESN'T support arithmetic operations so we aren't able to
+// compare versions this way (brackets aren't supported too):
+// {$IF VERSION > ((VER_MAJ*2)+(VER_MIN*23)+(VER_REL*1))}
+//
+// Hence we have to use fixed numbers in the directives. At least
+// Pascal allows leading 0s so 0005 equals 5 (octals are
+// preceded by & and not by 0 in FPC).
+// We also fix the count of digits for each part of the version number
+// to 3 (aaaiiirrr with aaa=major, iii=minor, rrr=release version)
+//
+// A check for a library with at least a version of 2.5.11 would look
+// like this:
+// {$IF LIB_VERSION >= 002005011}
+//
+// If you just need to check the major version do this:
+// {$IF LIB_VERSION_MAJOR >= 23}
+//
+// IMPORTANT:
+// Because this unit must be included in a uses-section it is
+// not possible to use the version-numbers in this uses-clause.
+// Example:
+// interface
+// uses
+// versions, // include this file
+// {$IF USE_UNIT_XYZ}xyz;{$IFEND} // Error: USE_UNIT_XYZ not defined
+// const
+// {$IF USE_UNIT_XYZ}test = 2;{$IFEND} // OK
+// uses
+// {$IF USE_UNIT_XYZ}xyz;{$IFEND} // OK
+//
+// Even if this file was an include-file no constants could be declared
+// before the interface's uses clause.
+// In FPC macros {$DEFINE VER:= 3} could be used to declare the version-numbers
+// but this is incompatible to Delphi. In addition macros do not allow expand
+// arithmetic expressions. Although you can define
+// {$DEFINE FPC_VER:= FPC_VERSION*1000000+FPC_RELEASE*1000+FPC_PATCH}
+// the following check would fail:
+// {$IF FPC_VERSION_INT >= 002002000}
+// would fail because FPC_VERSION_INT is interpreted as a string.
+//
+// PLEASE consider this if you use version numbers in $IF compiler-
+// directives. Otherwise you might break portability.
+// -------------------------------------------------------------------
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+ {$MACRO ON} // for evaluation of FPC_VERSION/RELEASE/PATCH
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Sysutils;
+
+const
+ // IMPORTANT:
+ // If IncludeConstants is defined, the const-sections
+ // of the config-file will be included too.
+ // This switch is necessary because it is not possible to
+ // include the const-sections in the switches.inc.
+ // switches.inc is always included before the first uses-
+ // section but at that place no const-section is allowed.
+ // So we have to include the config-file in switches.inc
+ // with IncludeConstants undefined and in UConfig.pas with
+ // IncludeConstants defined (see the note above).
+ {$DEFINE IncludeConstants}
+
+ // include config-file (defines + constants)
+ {$IF Defined(MSWindows)}
+ {$I ../config-win.inc}
+ {$ELSEIF Defined(Linux)}
+ {$I ../config-linux.inc}
+ {$ELSEIF Defined(Darwin)}
+ {$I ../config-darwin.inc}
+ {$ELSE}
+ {$MESSAGE Fatal 'Unknown OS'}
+ {$IFEND}
+
+{* Libraries *}
+
+ VERSION_MAJOR = 1000000;
+ VERSION_MINOR = 1000;
+ VERSION_RELEASE = 1;
+
+ (*
+ * Current version of UltraStar Deluxe
+ *)
+ USDX_VERSION_MAJOR = 1;
+ USDX_VERSION_MINOR = 1;
+ USDX_VERSION_RELEASE = 0;
+ USDX_VERSION_STATE = 'Alpha';
+ USDX_STRING = 'UltraStar Deluxe';
+
+ (*
+ * FPC version numbers are already defined as built-in macros:
+ * FPC_VERSION (MAJOR)
+ * FPC_RELEASE (MINOR)
+ * FPC_PATCH (RELEASE)
+ * Since FPC_VERSION is already defined, we will use FPC_VERSION_INT as
+ * composed version number.
+ *)
+ {$IFNDEF FPC}
+ // Delphi 7 evaluates every $IF-directive even if it is disabled by a surrounding
+ // $IF or $IFDEF so the follwing will give you an error in delphi:
+ // {$IFDEF FPC}{$IF (FPC_VERSION > 2)}...{$IFEND}{$ENDIF}
+ // The reason for this error is that FPC_VERSION is not a valid constant.
+ // To avoid this error, we define dummys here.
+ FPC_VERSION = 0;
+ FPC_RELEASE = 0;
+ FPC_PATCH = 0;
+ {$ENDIF}
+
+ FPC_VERSION_INT = (FPC_VERSION * VERSION_MAJOR) +
+ (FPC_RELEASE * VERSION_MINOR) +
+ (FPC_PATCH * VERSION_RELEASE);
+
+
+ {$IFDEF HaveFFmpeg}
+
+ LIBAVCODEC_VERSION = (LIBAVCODEC_VERSION_MAJOR * VERSION_MAJOR) +
+ (LIBAVCODEC_VERSION_MINOR * VERSION_MINOR) +
+ (LIBAVCODEC_VERSION_RELEASE * VERSION_RELEASE);
+
+ LIBAVFORMAT_VERSION = (LIBAVFORMAT_VERSION_MAJOR * VERSION_MAJOR) +
+ (LIBAVFORMAT_VERSION_MINOR * VERSION_MINOR) +
+ (LIBAVFORMAT_VERSION_RELEASE * VERSION_RELEASE);
+
+ LIBAVUTIL_VERSION = (LIBAVUTIL_VERSION_MAJOR * VERSION_MAJOR) +
+ (LIBAVUTIL_VERSION_MINOR * VERSION_MINOR) +
+ (LIBAVUTIL_VERSION_RELEASE * VERSION_RELEASE);
+
+ {$IFDEF HaveSWScale}
+ LIBSWSCALE_VERSION = (LIBSWSCALE_VERSION_MAJOR * VERSION_MAJOR) +
+ (LIBSWSCALE_VERSION_MINOR * VERSION_MINOR) +
+ (LIBSWSCALE_VERSION_RELEASE * VERSION_RELEASE);
+ {$ENDIF}
+
+ {$ENDIF}
+
+ {$IFDEF HaveProjectM}
+ PROJECTM_VERSION = (PROJECTM_VERSION_MAJOR * VERSION_MAJOR) +
+ (PROJECTM_VERSION_MINOR * VERSION_MINOR) +
+ (PROJECTM_VERSION_RELEASE * VERSION_RELEASE);
+ {$ENDIF}
+
+ {$IFDEF HavePortaudio}
+ PORTAUDIO_VERSION = (PORTAUDIO_VERSION_MAJOR * VERSION_MAJOR) +
+ (PORTAUDIO_VERSION_MINOR * VERSION_MINOR) +
+ (PORTAUDIO_VERSION_RELEASE * VERSION_RELEASE);
+ {$ENDIF}
+
+ {$IFDEF HaveLibsamplerate}
+ LIBSAMPLERATE_VERSION = (LIBSAMPLERATE_VERSION_MAJOR * VERSION_MAJOR) +
+ (LIBSAMPLERATE_VERSION_MINOR * VERSION_MINOR) +
+ (LIBSAMPLERATE_VERSION_RELEASE * VERSION_RELEASE);
+ {$ENDIF}
+
+function USDXVersionStr(): string;
+function USDXShortVersionStr(): string;
+
+implementation
+
+uses
+ StrUtils, Math;
+
+function USDXShortVersionStr(): string;
+begin
+ Result :=
+ USDX_STRING +
+ IfThen(USDX_VERSION_STATE <> '', ' '+USDX_VERSION_STATE);
+end;
+
+function USDXVersionStr(): string;
+begin
+ Result :=
+ USDX_STRING + ' V ' +
+ IntToStr(USDX_VERSION_MAJOR) + '.' +
+ IntToStr(USDX_VERSION_MINOR) + '.' +
+ IntToStr(USDX_VERSION_RELEASE) +
+ IfThen(USDX_VERSION_STATE <> '', ' '+USDX_VERSION_STATE) +
+ ' Build';
+end;
+
+end.
diff --git a/src/Classes/UCore.pas b/src/Classes/UCore.pas
new file mode 100644
index 00000000..fe23a68e
--- /dev/null
+++ b/src/Classes/UCore.pas
@@ -0,0 +1,525 @@
+unit UCore;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ uPluginDefs,
+ uCoreModule,
+ UHooks,
+ UServices,
+ UModules;
+
+{*********************
+ TCore
+ Class manages all CoreModules, teh StartUp, teh MainLoop and the shutdown process
+ Also it does some Error Handling, and maybe sometime multithreaded Loading ;)
+*********************}
+
+type
+ TModuleListItem = record
+ Module: TCoreModule; //Instance of the Modules Class
+ Info: TModuleInfo; //ModuleInfo returned by Modules Modulinfo Proc
+ NeedsDeInit: Boolean; //True if Module was succesful inited
+ end;
+
+ TCore = class
+ private
+ //Some Hook Handles. See Plugin SDKs Hooks.txt for Infos
+ hLoadingFinished: THandle;
+ hMainLoop: THandle;
+ hTranslate: THandle;
+ hLoadTextures: THandle;
+ hExitQuery: THandle;
+ hExit: THandle;
+ hDebug: THandle;
+ hError: THandle;
+ sReportError: THandle;
+ sReportDebug: THandle;
+ sShowMessage: THandle;
+ sRetranslate: THandle;
+ sReloadTextures: THandle;
+ sGetModuleInfo: THandle;
+ sGetApplicationHandle: THandle;
+
+ Modules: Array [0..High(CORE_MODULES_TO_LOAD)] of TModuleListItem;
+
+ //Cur + Last Executed Setting and Getting ;)
+ iCurExecuted: Integer;
+ iLastExecuted: Integer;
+
+ procedure SetCurExecuted(Value: Integer);
+
+ //Function Get all Modules and Creates them
+ function GetModules: Boolean;
+
+ //Loads Core and all Modules
+ function Load: Boolean;
+
+ //Inits Core and all Modules
+ function Init: Boolean;
+
+ //DeInits Core and all Modules
+ function DeInit: Boolean;
+
+ //Load the Core
+ function LoadCore: Boolean;
+
+ //Init the Core
+ function InitCore: Boolean;
+
+ //DeInit the Core
+ function DeInitCore: Boolean;
+
+ //Called one Time per Frame
+ function MainLoop: Boolean;
+
+ public
+ Hooks: THookManager; //Teh Hook Manager ;)
+ Services: TServiceManager;//The Service Manager
+
+ Name: String; //Name of this Application
+ Version: LongWord; //Version of this ". For Info Look PluginDefs Functions
+
+ LastErrorReporter:String; //Who Reported the Last Error String
+ LastErrorString: String; //Last Error String reported
+
+ property CurExecuted: Integer read iCurExecuted write SetCurExecuted; //ID of Plugin or Module curently Executed
+ property LastExecuted: Integer read iLastExecuted;
+
+ //---------------
+ //Main Methods to control the Core:
+ //---------------
+ constructor Create(const cName: String; const cVersion: LongWord);
+
+ //Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
+ procedure Run;
+
+ //Method for other Classes to get Pointer to a specific Module
+ function GetModulebyName(const Name: String): PCoreModule;
+
+ //--------------
+ // Hook and Service Procs:
+ //--------------
+ function ShowMessage(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol)
+ function ReportError(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
+ function ReportDebug(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
+ function Retranslate(wParam: TwParam; lParam: TlParam): integer; //Calls Translate hook
+ function ReloadTextures(wParam: TwParam; lParam: TlParam): integer; //Calls LoadTextures hook
+ function GetModuleInfo(wParam: TwParam; lParam: TlParam): integer; //If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
+ function GetApplicationHandle(wParam: TwParam; lParam: TlParam): integer; //Returns Application Handle
+ end;
+
+var
+ Core: TCore;
+
+implementation
+
+uses
+ {$IFDEF win32}
+ Windows,
+ {$ENDIF}
+ SysUtils;
+
+//-------------
+// Create - Creates Class + Hook and Service Manager
+//-------------
+constructor TCore.Create(const cName: String; const cVersion: LongWord);
+begin
+ inherited Create;
+
+ Name := cName;
+ Version := cVersion;
+ iLastExecuted := 0;
+ iCurExecuted := 0;
+
+ LastErrorReporter := '';
+ LastErrorString := '';
+
+ Hooks := THookManager.Create(50);
+ Services := TServiceManager.Create;
+end;
+
+//-------------
+//Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
+//-------------
+procedure TCore.Run;
+var
+ Success: Boolean;
+
+ procedure HandleError(const ErrorMsg: string);
+ begin
+ if (LastErrorString <> '') then
+ Self.ShowMessage(CORE_SM_ERROR, PChar(ErrorMsg + ': ' + LastErrorString))
+ else
+ Self.ShowMessage(CORE_SM_ERROR, PChar(ErrorMsg));
+
+ //DeInit
+ DeInit;
+ end;
+
+begin
+ //Get Modules
+ try
+ Success := GetModules();
+ except
+ Success := False;
+ end;
+
+ if (not Success) then
+ begin
+ HandleError('Error Getting Modules');
+ Exit;
+ end;
+
+ //Loading
+ try
+ Success := Load();
+ except
+ Success := False;
+ end;
+
+ if (not Success) then
+ begin
+ HandleError('Error loading Modules');
+ Exit;
+ end;
+
+ //Init
+ try
+ Success := Init();
+ except
+ Success := False;
+ end;
+
+ if (not Success) then
+ begin
+ HandleError('Error initing Modules');
+ Exit;
+ end;
+
+ //Call Translate Hook
+ if (Hooks.CallEventChain(hTranslate, 0, nil) <> 0) then
+ begin
+ HandleError('Error translating');
+ Exit;
+ end;
+
+ //Calls LoadTextures Hook
+ if (Hooks.CallEventChain(hLoadTextures, 0, nil) <> 0) then
+ begin
+ HandleError('Error loading textures');
+ Exit;
+ end;
+
+ //Calls Loading Finished Hook
+ if (Hooks.CallEventChain(hLoadingFinished, 0, nil) <> 0) then
+ begin
+ HandleError('Error calling LoadingFinished Hook');
+ Exit;
+ end;
+
+ //Start MainLoop
+ while Success do
+ begin
+ Success := MainLoop();
+ // to-do : Call Display Draw here
+ end;
+end;
+
+//-------------
+//Called one Time per Frame
+//-------------
+function TCore.MainLoop: Boolean;
+begin
+ Result := False;
+end;
+
+//-------------
+//Function Get all Modules and Creates them
+//-------------
+function TCore.GetModules: Boolean;
+var
+ i: Integer;
+begin
+ Result := False;
+ for i := 0 to high(Modules) do
+ begin
+ try
+ Modules[i].NeedsDeInit := False;
+ Modules[i].Module := CORE_MODULES_TO_LOAD[i].Create;
+ Modules[i].Module.Info(@Modules[i].Info);
+ except
+ ReportError(Integer(PChar('Can''t get module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ Exit;
+ end;
+ end;
+ Result := True;
+end;
+
+//-------------
+//Loads Core and all Modules
+//-------------
+function TCore.Load: Boolean;
+var
+ i: Integer;
+begin
+ Result := LoadCore;
+
+ for i := 0 to High(CORE_MODULES_TO_LOAD) do
+ begin
+ try
+ Result := Modules[i].Module.Load;
+ except
+ Result := False;
+ end;
+
+ if (not Result) then
+ begin
+ ReportError(Integer(PChar('Error loading module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ break;
+ end;
+ end;
+end;
+
+//-------------
+//Inits Core and all Modules
+//-------------
+function TCore.Init: Boolean;
+var
+ i: Integer;
+begin
+ Result := InitCore;
+
+ for i := 0 to High(CORE_MODULES_TO_LOAD) do
+ begin
+ try
+ Result := Modules[i].Module.Init;
+ except
+ Result := False;
+ end;
+
+ if (not Result) then
+ begin
+ ReportError(Integer(PChar('Error initing module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ break;
+ end;
+
+ Modules[i].NeedsDeInit := Result;
+ end;
+end;
+
+//-------------
+//DeInits Core and all Modules
+//-------------
+function TCore.DeInit: boolean;
+var
+ i: integer;
+begin
+
+ for i := High(CORE_MODULES_TO_LOAD) downto 0 do
+ begin
+ try
+ if (Modules[i].NeedsDeInit) then
+ Modules[i].Module.DeInit;
+ except
+ end;
+ end;
+
+ DeInitCore;
+
+ Result := true;
+end;
+
+//-------------
+//Load the Core
+//-------------
+function TCore.LoadCore: Boolean;
+begin
+ hLoadingFinished := Hooks.AddEvent('Core/LoadingFinished');
+ hMainLoop := Hooks.AddEvent('Core/MainLoop');
+ hTranslate := Hooks.AddEvent('Core/Translate');
+ hLoadTextures := Hooks.AddEvent('Core/LoadTextures');
+ hExitQuery := Hooks.AddEvent('Core/ExitQuery');
+ hExit := Hooks.AddEvent('Core/Exit');
+ hDebug := Hooks.AddEvent('Core/NewDebugInfo');
+ hError := Hooks.AddEvent('Core/NewError');
+
+ sReportError := Services.AddService('Core/ReportError', nil, Self.ReportError);
+ sReportDebug := Services.AddService('Core/ReportDebug', nil, Self.ReportDebug);
+ sShowMessage := Services.AddService('Core/ShowMessage', nil, Self.ShowMessage);
+ sRetranslate := Services.AddService('Core/Retranslate', nil, Self.Retranslate);
+ sReloadTextures := Services.AddService('Core/ReloadTextures', nil, Self.ReloadTextures);
+ sGetModuleInfo := Services.AddService('Core/GetModuleInfo', nil, Self.GetModuleInfo);
+ sGetApplicationHandle := Services.AddService('Core/GetApplicationHandle', nil, Self.GetApplicationHandle);
+
+ //A little Test
+ Hooks.AddSubscriber('Core/NewError', HookTest);
+
+ result := true;
+end;
+
+//-------------
+//Init the Core
+//-------------
+function TCore.InitCore: Boolean;
+begin
+ //Don not init something atm.
+ result := true;
+end;
+
+//-------------
+//DeInit the Core
+//-------------
+function TCore.DeInitCore: Boolean;
+begin
+ // TODO: write TService-/HookManager.Free and call it here
+ Result := true;
+end;
+
+//-------------
+//Method for other classes to get pointer to a specific module
+//-------------
+function TCore.GetModuleByName(const Name: String): PCoreModule;
+var i: Integer;
+begin
+ Result := nil;
+ for i := 0 to High(Modules) do
+ begin
+ if (Modules[i].Info.Name = Name) then
+ begin
+ Result := @Modules[i].Module;
+ Break;
+ end;
+ end;
+end;
+
+//-------------
+// Shows a MessageDialog (lParam: PChar Text, wParam: Symbol)
+//-------------
+function TCore.ShowMessage(wParam: TwParam; lParam: TlParam): integer;
+{$IFDEF MSWINDOWS}
+var Params: Cardinal;
+{$ENDIF}
+begin
+ Result := -1;
+
+ {$IFDEF MSWINDOWS}
+ if (lParam <> nil) then
+ begin
+ Params := MB_OK;
+ case wParam of
+ CORE_SM_ERROR: Params := Params or MB_ICONERROR;
+ CORE_SM_WARNING: Params := Params or MB_ICONWARNING;
+ CORE_SM_INFO: Params := Params or MB_ICONINFORMATION;
+ end;
+
+ //Show:
+ Result := Messagebox(0, lParam, PChar(Name), Params);
+ end;
+ {$ENDIF}
+
+ // TODO: write ShowMessage for other OSes
+end;
+
+//-------------
+// Calls NewError HookChain (wParam: Pchar(Message), lParam: PChar(Reportername))
+//-------------
+function TCore.ReportError(wParam: TwParam; lParam: TlParam): integer;
+begin
+ //Update LastErrorReporter and LastErrorString
+ LastErrorReporter := String(PChar(lParam));
+ LastErrorString := String(PChar(Pointer(wParam)));
+
+ Hooks.CallEventChain(hError, wParam, lParam);
+
+ // FIXME: return a correct result
+ Result := 0;
+end;
+
+//-------------
+// Calls NewDebugInfo HookChain (wParam: Pchar(Message), lParam: PChar(Reportername))
+//-------------
+function TCore.ReportDebug(wParam: TwParam; lParam: TlParam): integer;
+begin
+ Hooks.CallEventChain(hDebug, wParam, lParam);
+
+ // FIXME: return a correct result
+ Result := 0;
+end;
+
+//-------------
+// Calls Translate hook
+//-------------
+function TCore.Retranslate(wParam: TwParam; lParam: TlParam): integer;
+begin
+ Hooks.CallEventChain(hTranslate, 1, nil);
+
+ // FIXME: return a correct result
+ Result := 0;
+end;
+
+//-------------
+// Calls LoadTextures hook
+//-------------
+function TCore.ReloadTextures(wParam: TwParam; lParam: TlParam): integer;
+begin
+ Hooks.CallEventChain(hLoadTextures, 1, nil);
+
+ // FIXME: return a correct result
+ Result := 0;
+end;
+
+//-------------
+// If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
+//-------------
+function TCore.GetModuleInfo(wParam: TwParam; lParam: TlParam): integer;
+var
+ I: integer;
+begin
+ if (Pointer(lParam) = nil) then
+ begin
+ Result := Length(Modules);
+ end
+ else
+ begin
+ try
+ for I := 0 to High(Modules) do
+ begin
+ AModuleInfo(Pointer(lParam))[I].Name := Modules[I].Info.Name;
+ AModuleInfo(Pointer(lParam))[I].Version := Modules[I].Info.Version;
+ AModuleInfo(Pointer(lParam))[I].Description := Modules[I].Info.Description;
+ end;
+ Result := Length(Modules);
+ except
+ Result := -1;
+ end;
+ end;
+end;
+
+//-------------
+// Returns Application Handle
+//-------------
+function TCore.GetApplicationHandle(wParam: TwParam; lParam: TlParam): integer;
+begin
+ Result := hInstance;
+end;
+
+//-------------
+// Called when setting CurExecuted
+//-------------
+procedure TCore.SetCurExecuted(Value: Integer);
+begin
+ //Set Last Executed
+ iLastExecuted := iCurExecuted;
+
+ //Set Cur Executed
+ iCurExecuted := Value;
+end;
+
+end.
diff --git a/src/Classes/UCoreModule.pas b/src/Classes/UCoreModule.pas
new file mode 100644
index 00000000..031fb04e
--- /dev/null
+++ b/src/Classes/UCoreModule.pas
@@ -0,0 +1,128 @@
+unit UCoreModule;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+{*********************
+ TCoreModule
+ Dummy Class that has Methods that will be called from Core
+ In the Best case every Piece of this Software is a Module
+*********************}
+uses UPluginDefs;
+
+type
+ PCoreModule = ^TCoreModule;
+ TCoreModule = class
+ public
+ Constructor Create; virtual;
+
+ //Function that gives some Infos about the Module to the Core
+ Procedure Info(const pInfo: PModuleInfo); virtual;
+
+ //Is Called on Loading.
+ //In this Method only Events and Services should be created
+ //to offer them to other Modules or Plugins during the Init process
+ //If False is Returned this will cause a Forced Exit
+ Function Load: Boolean; virtual;
+
+ //Is Called on Init Process
+ //In this Method you can Hook some Events and Create + Init
+ //your Classes, Variables etc.
+ //If False is Returned this will cause a Forced Exit
+ Function Init: Boolean; virtual;
+
+ //Is Called during Mainloop before 'Core/MainLoop' Hook and Drawing
+ //If False is Returned this will cause a Forced Exit
+ Function MainLoop: Boolean; virtual;
+
+ //Is Called if this Module has been Inited and there is a Exit.
+ //Deinit is in backwards Initing Order
+ //If False is Returned this will cause a Forced Exit
+ Procedure DeInit; virtual;
+
+ //Is Called if this Module will be unloaded and has been created
+ //Should be used to Free Memory
+ Destructor Destroy; override;
+ end;
+ cCoreModule = class of TCoreModule;
+
+implementation
+
+//-------------
+// Just the Constructor
+//-------------
+Constructor TCoreModule.Create;
+begin
+ //Dummy maaaan ;)
+ inherited;
+end;
+
+//-------------
+// Function that gives some Infos about the Module to the Core
+//-------------
+Procedure TCoreModule.Info(const pInfo: PModuleInfo);
+begin
+ pInfo^.Name := 'Not Set';
+ pInfo^.Version := 0;
+ pInfo^.Description := 'Not Set';
+end;
+
+//-------------
+//Is Called on Loading.
+//In this Method only Events and Services should be created
+//to offer them to other Modules or Plugins during the Init process
+//If False is Returned this will cause a Forced Exit
+//-------------
+Function TCoreModule.Load: Boolean;
+begin
+ //Dummy ftw!!
+ Result := True;
+end;
+
+//-------------
+//Is Called on Init Process
+//In this Method you can Hook some Events and Create + Init
+//your Classes, Variables etc.
+//If False is Returned this will cause a Forced Exit
+//-------------
+Function TCoreModule.Init: Boolean;
+begin
+ //Dummy ftw!!
+ Result := True;
+end;
+
+//-------------
+//Is Called during Mainloop before 'Core/MainLoop' Hook and Drawing
+//If False is Returned this will cause a Forced Exit
+//-------------
+Function TCoreModule.MainLoop: Boolean;
+begin
+ //Dummy ftw!!
+ Result := True;
+end;
+
+//-------------
+//Is Called if this Module has been Inited and there is a Exit.
+//Deinit is in backwards Initing Order
+//-------------
+Procedure TCoreModule.DeInit;
+begin
+ //Dummy ftw!!
+end;
+
+//-------------
+//Is Called if this Module will be unloaded and has been created
+//Should be used to Free Memory
+//-------------
+Destructor TCoreModule.Destroy;
+begin
+ //Dummy ftw!!
+ inherited;
+end;
+
+end.
diff --git a/src/Classes/UCovers.pas b/src/Classes/UCovers.pas
new file mode 100644
index 00000000..7bb57b4a
--- /dev/null
+++ b/src/Classes/UCovers.pas
@@ -0,0 +1,430 @@
+unit UCovers;
+
+{
+ TODO:
+ - adjust database to new song-loading (e.g. use SongIDs)
+ - support for deletion of outdated covers
+ - support for update of changed covers
+ - use paths relative to the song for removable disks support
+ (a drive might have a different drive-name the next time it is connected,
+ so "H:/songs/..." will not match "I:/songs/...")
+}
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ sdl,
+ SQLite3,
+ SQLiteTable3,
+ SysUtils,
+ Classes,
+ UImage,
+ UTexture;
+
+type
+ ECoverDBException = class(Exception)
+ end;
+
+ TCover = class
+ private
+ ID: int64;
+ Filename: WideString;
+ public
+ constructor Create(ID: int64; Filename: WideString);
+ function GetPreviewTexture(): TTexture;
+ function GetTexture(): TTexture;
+ end;
+
+ TThumbnailInfo = record
+ CoverWidth: integer; // Original width of cover
+ CoverHeight: integer; // Original height of cover
+ PixelFormat: TImagePixelFmt; // Pixel-format of thumbnail
+ end;
+
+ TCoverDatabase = class
+ private
+ DB: TSQLiteDatabase;
+ procedure InitCoverDatabase();
+ function CreateThumbnail(const Filename: WideString; var Info: TThumbnailInfo): PSDL_Surface;
+ function LoadCover(CoverID: int64): TTexture;
+ procedure DeleteCover(CoverID: int64);
+ function FindCoverIntern(const Filename: WideString): int64;
+ procedure Open();
+ function GetVersion(): integer;
+ procedure SetVersion(Version: integer);
+ public
+ constructor Create();
+ destructor Destroy; override;
+ function AddCover(const Filename: WideString): TCover;
+ function FindCover(const Filename: WideString): TCover;
+ function CoverExists(const Filename: WideString): boolean;
+ function GetMaxCoverSize(): integer;
+ procedure SetMaxCoverSize(Size: integer);
+ end;
+
+ TBlobWrapper = class(TCustomMemoryStream)
+ function Write(const Buffer; Count: Integer): Integer; override;
+ end;
+
+var
+ Covers: TCoverDatabase;
+
+implementation
+
+uses
+ UMain,
+ ULog,
+ UPlatform,
+ UIni,
+ Math,
+ DateUtils;
+
+const
+ COVERDB_FILENAME = 'cover.db';
+ COVERDB_VERSION = 01; // 0.1
+ COVER_TBL = 'Cover';
+ COVER_THUMBNAIL_TBL = 'CoverThumbnail';
+ COVER_IDX = 'Cover_Filename_IDX';
+
+// Note: DateUtils.DateTimeToUnix() will throw an exception in FPC
+function DateTimeToUnixTime(time: TDateTime): int64;
+begin
+ Result := Round((time - UnixDateDelta) * SecsPerDay);
+end;
+
+// Note: DateUtils.UnixToDateTime() will throw an exception in FPC
+function UnixTimeToDateTime(timestamp: int64): TDateTime;
+begin
+ Result := timestamp / SecsPerDay + UnixDateDelta;
+end;
+
+
+{ TBlobWrapper }
+
+function TBlobWrapper.Write(const Buffer; Count: Integer): Integer;
+begin
+ SetPointer(Pointer(Buffer), Count);
+ Result := Count;
+end;
+
+
+{ TCover }
+
+constructor TCover.Create(ID: int64; Filename: WideString);
+begin
+ Self.ID := ID;
+ Self.Filename := Filename;
+end;
+
+function TCover.GetPreviewTexture(): TTexture;
+begin
+ Result := Covers.LoadCover(ID);
+end;
+
+function TCover.GetTexture(): TTexture;
+begin
+ Result := Texture.LoadTexture(Filename);
+end;
+
+
+{ TCoverDatabase }
+
+constructor TCoverDatabase.Create();
+begin
+ inherited;
+
+ Open();
+ InitCoverDatabase();
+end;
+
+destructor TCoverDatabase.Destroy;
+begin
+ DB.Free;
+ inherited;
+end;
+
+function TCoverDatabase.GetVersion(): integer;
+begin
+ Result := DB.GetTableValue('PRAGMA user_version');
+end;
+
+procedure TCoverDatabase.SetVersion(Version: integer);
+begin
+ DB.ExecSQL(Format('PRAGMA user_version = %d', [Version]));
+end;
+
+function TCoverDatabase.GetMaxCoverSize(): integer;
+begin
+ Result := ITextureSizeVals[Ini.TextureSize];
+end;
+
+procedure TCoverDatabase.SetMaxCoverSize(Size: integer);
+var
+ I: integer;
+begin
+ // search for first valid cover-size > Size
+ for I := 0 to Length(ITextureSizeVals)-1 do
+ begin
+ if (Size <= ITextureSizeVals[I]) then
+ begin
+ Ini.TextureSize := I;
+ Exit;
+ end;
+ end;
+
+ // fall-back to highest size
+ Ini.TextureSize := High(ITextureSizeVals);
+end;
+
+procedure TCoverDatabase.Open();
+var
+ Version: integer;
+ Filename: string;
+begin
+ Filename := UTF8Encode(Platform.GetGameUserPath() + COVERDB_FILENAME);
+
+ DB := TSQLiteDatabase.Create(Filename);
+ Version := GetVersion();
+
+ // check version, if version is too old/new, delete database file
+ if ((Version <> 0) and (Version <> COVERDB_VERSION)) then
+ begin
+ Log.LogInfo('Outdated cover-database file found', 'TCoverDatabase.Open');
+ // close and delete outdated file
+ DB.Free;
+ if (not DeleteFile(Filename)) then
+ raise ECoverDBException.Create('Could not delete ' + Filename);
+ // reopen
+ DB := TSQLiteDatabase.Create(Filename);
+ Version := 0;
+ end;
+
+ // set version number after creation
+ if (Version = 0) then
+ SetVersion(COVERDB_VERSION);
+
+ // speed-up disk-writing. The default FULL-synchronous mode is too slow.
+ // With this option disk-writing is approx. 4 times faster but the database
+ // might be corrupted if the OS crashes, although this is very unlikely.
+ DB.ExecSQL('PRAGMA synchronous = OFF;');
+
+ // the next line rather gives a slow-down instead of a speed-up, so we do not use it
+ //DB.ExecSQL('PRAGMA temp_store = MEMORY;');
+end;
+
+procedure TCoverDatabase.InitCoverDatabase();
+begin
+ DB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+COVER_TBL+'] (' +
+ '[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
+ '[Filename] TEXT UNIQUE NOT NULL, ' +
+ '[Date] INTEGER NOT NULL, ' +
+ '[Width] INTEGER NOT NULL, ' +
+ '[Height] INTEGER NOT NULL ' +
+ ')');
+
+ DB.ExecSQL('CREATE INDEX IF NOT EXISTS ['+COVER_IDX+'] ON ['+COVER_TBL+'](' +
+ '[Filename] ASC' +
+ ')');
+
+ DB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+COVER_THUMBNAIL_TBL+'] (' +
+ '[ID] INTEGER NOT NULL PRIMARY KEY, ' +
+ '[Format] INTEGER NOT NULL, ' +
+ '[Width] INTEGER NOT NULL, ' +
+ '[Height] INTEGER NOT NULL, ' +
+ '[Data] BLOB NULL' +
+ ')');
+end;
+
+function TCoverDatabase.FindCoverIntern(const Filename: WideString): int64;
+begin
+ Result := DB.GetTableValue('SELECT [ID] FROM ['+COVER_TBL+'] ' +
+ 'WHERE [Filename] = ?',
+ [UTF8Encode(Filename)]);
+end;
+
+function TCoverDatabase.FindCover(const Filename: WideString): TCover;
+var
+ CoverID: int64;
+begin
+ Result := nil;
+ try
+ CoverID := FindCoverIntern(Filename);
+ if (CoverID > 0) then
+ Result := TCover.Create(CoverID, Filename);
+ except on E: Exception do
+ Log.LogError(E.Message, 'TCoverDatabase.FindCover');
+ end;
+end;
+
+function TCoverDatabase.CoverExists(const Filename: WideString): boolean;
+begin
+ Result := false;
+ try
+ Result := (FindCoverIntern(Filename) > 0);
+ except on E: Exception do
+ Log.LogError(E.Message, 'TCoverDatabase.CoverExists');
+ end;
+end;
+
+function TCoverDatabase.AddCover(const Filename: WideString): TCover;
+var
+ CoverID: int64;
+ Thumbnail: PSDL_Surface;
+ CoverData: TBlobWrapper;
+ FileDate: TDateTime;
+ Info: TThumbnailInfo;
+begin
+ Result := nil;
+
+ //if (not FileExists(Filename)) then
+ // Exit;
+
+ // TODO: replace '\' with '/' in filename
+ FileDate := Now(); //FileDateToDateTime(FileAge(Filename));
+
+ Thumbnail := CreateThumbnail(Filename, Info);
+ if (Thumbnail = nil) then
+ Exit;
+
+ CoverData := TBlobWrapper.Create;
+ CoverData.Write(Thumbnail^.pixels, Thumbnail^.h * Thumbnail^.pitch);
+
+ try
+ // Note: use a transaction to speed-up file-writing.
+ // Without data written by the first INSERT might be moved at the second INSERT.
+ DB.BeginTransaction();
+
+ // add general cover info
+ DB.ExecSQL('INSERT INTO ['+COVER_TBL+'] ' +
+ '([Filename], [Date], [Width], [Height]) VALUES' +
+ '(?, ?, ?, ?)',
+ [UTF8Encode(Filename), DateTimeToUnixTime(FileDate),
+ Info.CoverWidth, Info.CoverHeight]);
+
+ // get auto-generated cover ID
+ CoverID := DB.GetLastInsertRowID();
+
+ // add thumbnail info
+ DB.ExecSQL('INSERT INTO ['+COVER_THUMBNAIL_TBL+'] ' +
+ '([ID], [Format], [Width], [Height], [Data]) VALUES' +
+ '(?, ?, ?, ?, ?)',
+ [CoverID, Ord(Info.PixelFormat),
+ Thumbnail^.w, Thumbnail^.h, CoverData]);
+
+ Result := TCover.Create(CoverID, Filename);
+ except on E: Exception do
+ Log.LogError(E.Message, 'TCoverDatabase.AddCover');
+ end;
+
+ DB.Commit();
+ CoverData.Free;
+ SDL_FreeSurface(Thumbnail);
+end;
+
+function TCoverDatabase.LoadCover(CoverID: int64): TTexture;
+var
+ Width, Height: integer;
+ PixelFmt: TImagePixelFmt;
+ Data: PChar;
+ DataSize: integer;
+ Filename: WideString;
+ Table: TSQLiteUniTable;
+begin
+ Table := nil;
+
+ try
+ Table := DB.GetUniTable(Format(
+ 'SELECT C.[Filename], T.[Format], T.[Width], T.[Height], T.[Data] ' +
+ 'FROM ['+COVER_TBL+'] C ' +
+ 'INNER JOIN ['+COVER_THUMBNAIL_TBL+'] T ' +
+ 'USING(ID) ' +
+ 'WHERE [ID] = %d', [CoverID]));
+
+ Filename := UTF8Decode(Table.FieldAsString(0));
+ PixelFmt := TImagePixelFmt(Table.FieldAsInteger(1));
+ Width := Table.FieldAsInteger(2);
+ Height := Table.FieldAsInteger(3);
+
+ Data := Table.FieldAsBlobPtr(4, DataSize);
+ if (Data <> nil) and
+ (PixelFmt = ipfRGB) then
+ begin
+ Result := Texture.CreateTexture(Data, Filename, Width, Height, 24)
+ end
+ else
+ begin
+ FillChar(Result, SizeOf(TTexture), 0);
+ end;
+ except on E: Exception do
+ Log.LogError(E.Message, 'TCoverDatabase.LoadCover');
+ end;
+
+ Table.Free;
+end;
+
+procedure TCoverDatabase.DeleteCover(CoverID: int64);
+begin
+ DB.ExecSQL(Format('DELETE FROM ['+COVER_TBL+'] WHERE [ID] = %d', [CoverID]));
+ DB.ExecSQL(Format('DELETE FROM ['+COVER_THUMBNAIL_TBL+'] WHERE [ID] = %d', [CoverID]));
+end;
+
+(**
+ * Returns a pointer to an array of bytes containing the texture data in the
+ * requested size
+ *)
+function TCoverDatabase.CreateThumbnail(const Filename: WideString; var Info: TThumbnailInfo): PSDL_Surface;
+var
+ TargetAspect, SourceAspect: double;
+ //TargetWidth, TargetHeight: integer;
+ Thumbnail: PSDL_Surface;
+ MaxSize: integer;
+begin
+ Result := nil;
+
+ MaxSize := GetMaxCoverSize();
+
+ Thumbnail := LoadImage(Filename);
+ if (not assigned(Thumbnail)) then
+ begin
+ Log.LogError('Could not load cover: "'+ Filename +'"', 'TCoverDatabase.AddCover');
+ Exit;
+ end;
+
+ // Convert pixel format as needed
+ AdjustPixelFormat(Thumbnail, TEXTURE_TYPE_PLAIN);
+
+ Info.CoverWidth := Thumbnail^.w;
+ Info.CoverHeight := Thumbnail^.h;
+ Info.PixelFormat := ipfRGB;
+
+ (* TODO: keep aspect ratio
+ TargetAspect := Width / Height;
+ SourceAspect := TexSurface.w / TexSurface.h;
+
+ // Scale texture to covers dimensions (keep aspect)
+ if (SourceAspect >= TargetAspect) then
+ begin
+ TargetWidth := Width;
+ TargetHeight := Trunc(Width / SourceAspect);
+ end
+ else
+ begin
+ TargetHeight := Height;
+ TargetWidth := Trunc(Height * SourceAspect);
+ end;
+ *)
+
+ // TODO: do not scale if image is smaller
+ ScaleImage(Thumbnail, MaxSize, MaxSize);
+
+ Result := Thumbnail;
+end;
+
+end.
+
diff --git a/src/Classes/UDLLManager.pas b/src/Classes/UDLLManager.pas
new file mode 100644
index 00000000..3d32a72a
--- /dev/null
+++ b/src/Classes/UDLLManager.pas
@@ -0,0 +1,253 @@
+unit UDLLManager;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses ModiSDK,
+ UFiles;
+
+type
+ TDLLMan = class
+ private
+ hLib: THandle;
+ P_Init: fModi_Init;
+ P_Draw: fModi_Draw;
+ P_Finish: fModi_Finish;
+ P_RData: pModi_RData;
+ public
+ Plugins: array of TPluginInfo;
+ PluginPaths: array of String;
+ Selected: ^TPluginInfo;
+
+ constructor Create;
+
+ procedure GetPluginList;
+ procedure ClearPluginInfo(No: Cardinal);
+ function LoadPluginInfo(Filename: String; No: Cardinal): boolean;
+
+ function LoadPlugin(No: Cardinal): boolean;
+ procedure UnLoadPlugin;
+
+ function PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
+ function PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
+ function PluginFinish (var Playerinfo: TPlayerinfo): byte;
+ procedure PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
+ end;
+
+var
+ DLLMan: TDLLMan;
+
+const
+ DLLPath = 'Plugins';
+
+ {$IFDEF MSWINDOWS}
+ DLLExt = '.dll';
+ {$ENDIF}
+ {$IFDEF LINUX}
+ DLLExt = '.so';
+ {$ENDIF}
+ {$IFDEF DARWIN}
+ DLLExt = '.dylib';
+ {$ENDIF}
+
+implementation
+
+uses {$IFDEF MSWINDOWS}
+ windows,
+ {$ELSE}
+ dynlibs,
+ {$ENDIF}
+ ULog,
+ SysUtils;
+
+
+constructor TDLLMan.Create;
+begin
+ inherited;
+ SetLength(Plugins, 0);
+ SetLength(PluginPaths, Length(Plugins));
+ GetPluginList;
+end;
+
+procedure TDLLMan.GetPluginList;
+var
+ SR: TSearchRec;
+begin
+
+ if FindFirst(DLLPath +PathDelim+ '*' + DLLExt, faAnyFile , SR) = 0 then
+ begin
+ repeat
+ SetLength(Plugins, Length(Plugins)+1);
+ SetLength(PluginPaths, Length(Plugins));
+
+ if LoadPluginInfo(SR.Name, High(Plugins)) then //Loaded succesful
+ begin
+ PluginPaths[High(PluginPaths)] := SR.Name;
+ end
+ else //Error Loading
+ begin
+ SetLength(Plugins, Length(Plugins)-1);
+ SetLength(PluginPaths, Length(Plugins));
+ end;
+
+ until FindNext(SR) <> 0;
+ FindClose(SR);
+ end;
+end;
+
+procedure TDLLMan.ClearPluginInfo(No: Cardinal);
+begin
+ //Set to Party Modi Plugin
+ Plugins[No].Typ := 8;
+
+ Plugins[No].Name := 'unknown';
+ Plugins[No].NumPlayers := 0;
+
+ Plugins[No].Creator := 'Nobody';
+ Plugins[No].PluginDesc := 'NO_PLUGIN_DESC';
+
+ Plugins[No].LoadSong := True;
+ Plugins[No].ShowScore := True;
+ Plugins[No].ShowBars := False;
+ Plugins[No].ShowNotes := True;
+ Plugins[No].LoadVideo := True;
+ Plugins[No].LoadBack := True;
+
+ Plugins[No].TeamModeOnly := False;
+ Plugins[No].GetSoundData := False;
+ Plugins[No].Dummy := False;
+
+
+ Plugins[No].BGShowFull := False;
+ Plugins[No].BGShowFull_O := True;
+
+ Plugins[No].ShowRateBar:= False;
+ Plugins[No].ShowRateBar_O := True;
+
+ Plugins[No].EnLineBonus := False;
+ Plugins[No].EnLineBonus_O := True;
+end;
+
+function TDLLMan.LoadPluginInfo(Filename: String; No: Cardinal): boolean;
+var
+ hLibg: THandle;
+ Info: pModi_PluginInfo;
+ I: Integer;
+begin
+ Result := False;
+ //Clear Plugin Info
+ ClearPluginInfo(No);
+
+ {//Workaround Plugins Loaded 2 Times
+ For I := low(PluginPaths) to high(PluginPaths) do
+ if (PluginPaths[I] = Filename) then
+ exit; }
+
+ //Load Libary
+ hLibg := LoadLibrary(PChar(DLLPath +PathDelim+ Filename));
+ //If Loaded
+ if (hLibg <> 0) then
+ begin
+ //Load Info Procedure
+ @Info := GetProcAddress (hLibg, PChar('PluginInfo'));
+
+ //If Loaded
+ if (@Info <> nil) then
+ begin
+ //Load PluginInfo
+ Info (Plugins[No]);
+ Result := True;
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + Filename + '": Info Procedure not Found');
+
+ FreeLibrary (hLibg);
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + Filename + '": Libary not Loaded');
+end;
+
+function TDLLMan.LoadPlugin(No: Cardinal): boolean;
+begin
+ Result := False;
+ //Load Libary
+ hLib := LoadLibrary(PChar(DLLPath +PathDelim+ PluginPaths[No]));
+ //If Loaded
+ if (hLib <> 0) then
+ begin
+ //Load Info Procedure
+ @P_Init := GetProcAddress (hLib, PChar('Init'));
+ @P_Draw := GetProcAddress (hLib, PChar('Draw'));
+ @P_Finish := GetProcAddress (hLib, PChar('Finish'));
+
+ //If Loaded
+ if (@P_Init <> nil) And (@P_Draw <> nil) And (@P_Finish <> nil) then
+ begin
+ Selected := @Plugins[No];
+ Result := True;
+ end
+ else
+ begin
+ Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Procedures not Found');
+
+ end;
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Libary not Loaded');
+end;
+
+procedure TDLLMan.UnLoadPlugin;
+begin
+if (hLib <> 0) then
+ FreeLibrary (hLib);
+
+//Selected := nil;
+@P_Init := nil;
+@P_Draw := nil;
+@P_Finish := nil;
+@P_RData := nil;
+end;
+
+function TDLLMan.PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
+var
+ Methods: TMethodRec;
+begin
+ Methods.LoadTex := LoadTex;
+ Methods.Print := Print;
+ Methods.LoadSound := LoadSound;
+ Methods.PlaySound := PlaySound;
+
+ if (@P_Init <> nil) then
+ Result := P_Init (TeamInfo, PlayerInfo, Sentences, Methods)
+ else
+ Result := False
+end;
+
+function TDLLMan.PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
+begin
+if (@P_Draw <> nil) then
+ Result := P_Draw (PlayerInfo, CurSentence)
+else
+ Result := False
+end;
+
+function TDLLMan.PluginFinish (var Playerinfo: TPlayerinfo): byte;
+begin
+if (@P_Finish <> nil) then
+ Result := P_Finish (PlayerInfo)
+else
+ Result := 0;
+end;
+
+procedure TDLLMan.PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
+begin
+if (@P_RData <> nil) then
+ P_RData (handle, buffer, len, user);
+end;
+
+end.
diff --git a/src/Classes/UDataBase.pas b/src/Classes/UDataBase.pas
new file mode 100644
index 00000000..cd315df3
--- /dev/null
+++ b/src/Classes/UDataBase.pas
@@ -0,0 +1,533 @@
+unit UDataBase;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses USongs,
+ USong,
+ Classes,
+ SQLiteTable3;
+
+//--------------------
+//DataBaseSystem - Class including all DB Methods
+//--------------------
+type
+ TStatType = (
+ stBestScores, // Best Scores
+ stBestSingers, // Best Singers
+ stMostSungSong, // Most sung Songs
+ stMostPopBand // Most popular Band
+ );
+
+ // abstract super-class for statistic results
+ TStatResult = class
+ public
+ Typ: TStatType;
+ end;
+
+ TStatResultBestScores = class(TStatResult)
+ public
+ Singer: WideString;
+ Score: Word;
+ Difficulty: Byte;
+ SongArtist: WideString;
+ SongTitle: WideString;
+ end;
+
+ TStatResultBestSingers = class(TStatResult)
+ public
+ Player: WideString;
+ AverageScore: Word;
+ end;
+
+ TStatResultMostSungSong = class(TStatResult)
+ public
+ Artist: WideString;
+ Title: WideString;
+ TimesSung: Word;
+ end;
+
+ TStatResultMostPopBand = class(TStatResult)
+ public
+ ArtistName: WideString;
+ TimesSungTot: Word;
+ end;
+
+
+ TDataBaseSystem = class
+ private
+ ScoreDB: TSQLiteDatabase;
+ fFilename: string;
+
+ function GetVersion(): integer;
+ procedure SetVersion(Version: integer);
+ public
+ property Filename: string read fFilename;
+
+ destructor Destroy; override;
+
+ procedure Init(const Filename: string);
+ procedure ReadScore(Song: TSong);
+ procedure AddScore(Song: TSong; Level: integer; const Name: WideString; Score: integer);
+ procedure WriteScore(Song: TSong);
+
+ function GetStats(Typ: TStatType; Count: Byte; Page: Cardinal; Reversed: Boolean): TList;
+ procedure FreeStats(StatList: TList);
+ function GetTotalEntrys(Typ: TStatType): Cardinal;
+ function GetStatReset: TDateTime;
+ end;
+
+var
+ DataBase: TDataBaseSystem;
+
+implementation
+
+uses
+ ULog,
+ DateUtils,
+ StrUtils,
+ SysUtils;
+
+const
+ cDBVersion = 01; // 0.1
+ cUS_Scores = 'us_scores';
+ cUS_Songs = 'us_songs';
+ cUS_Statistics_Info = 'us_statistics_info';
+
+(**
+ * Opens Database and Create Tables if not Exist
+ *)
+procedure TDataBaseSystem.Init(const Filename: string);
+var
+ Version: integer;
+begin
+ if Assigned(ScoreDB) then
+ Exit;
+
+ Log.LogStatus('Initializing database: "'+Filename+'"', 'TDataBaseSystem.Init');
+
+ try
+
+ // Open Database
+ ScoreDB := TSQLiteDatabase.Create(Filename);
+ fFilename := Filename;
+
+ // Close and delete outdated file
+ Version := GetVersion();
+ if ((Version <> 0) and (Version <> cDBVersion)) then
+ begin
+ Log.LogInfo('Outdated cover-database file found', 'TDataBaseSystem.Init');
+ // Close and delete outdated file
+ ScoreDB.Free;
+ if (not DeleteFile(Filename)) then
+ raise Exception.Create('Could not delete ' + Filename);
+ // Reopen
+ ScoreDB := TSQLiteDatabase.Create(Filename);
+ Version := 0;
+ end;
+
+ // Set version number after creation
+ if (Version = 0) then
+ SetVersion(cDBVersion);
+
+
+ // SQLite does not handle VARCHAR(n) or INT(n) as expected.
+ // Texts do not have a restricted length, no matter which type is used,
+ // so use the native TEXT type. INT(n) is always INTEGER.
+ // In addition, SQLiteTable3 will fail if other types than the native SQLite
+ // types are used (especially FieldAsInteger). Also take care to write the
+ // types in upper-case letters although SQLite does not care about this -
+ // SQLiteTable3 is very sensitive in this regard.
+
+ ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Scores+'] (' +
+ '[SongID] INTEGER NOT NULL, ' +
+ '[Difficulty] INTEGER NOT NULL, ' +
+ '[Player] TEXT NOT NULL, ' +
+ '[Score] INTEGER NOT NULL' +
+ ');');
+
+ ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Songs+'] (' +
+ '[ID] INTEGER PRIMARY KEY, ' +
+ '[Artist] TEXT NOT NULL, ' +
+ '[Title] TEXT NOT NULL, ' +
+ '[TimesPlayed] INTEGER NOT NULL' +
+ ');');
+
+ if not ScoreDB.TableExists(cUS_Statistics_Info) then
+ begin
+ ScoreDB.ExecSQL('CREATE TABLE IF NOT EXISTS ['+cUS_Statistics_Info+'] (' +
+ '[ResetTime] INTEGER' +
+ ');');
+ // insert creation timestamp
+ ScoreDB.ExecSQL(Format('INSERT INTO ['+cUS_Statistics_Info+'] ' +
+ '([ResetTime]) VALUES(%d);',
+ [DateTimeToUnix(Now())]));
+ end;
+
+ except
+ on E: Exception do
+ begin
+ Log.LogError(E.Message, 'TDataBaseSystem.Init');
+ FreeAndNil(ScoreDB);
+ end;
+ end;
+
+end;
+
+(**
+ * Frees Database
+ *)
+destructor TDataBaseSystem.Destroy;
+begin
+ Log.LogInfo('TDataBaseSystem.Free', 'TDataBaseSystem.Destroy');
+ ScoreDB.Free;
+ inherited;
+end;
+
+(**
+ * Read Scores into SongArray
+ *)
+procedure TDataBaseSystem.ReadScore(Song: TSong);
+var
+ TableData: TSQLiteUniTable;
+ Difficulty: Integer;
+begin
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ TableData := nil;
+
+ try
+ // Search Song in DB
+ TableData := ScoreDB.GetUniTable(
+ 'SELECT [Difficulty], [Player], [Score] FROM ['+cUS_Scores+'] ' +
+ 'WHERE [SongID] = (' +
+ 'SELECT [ID] FROM ['+cUS_Songs+'] ' +
+ 'WHERE [Artist] = ? AND [Title] = ? ' +
+ 'LIMIT 1) ' +
+ 'ORDER BY [Score] DESC LIMIT 15',
+ [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
+
+ // Empty Old Scores
+ SetLength(Song.Score[0], 0);
+ SetLength(Song.Score[1], 0);
+ SetLength(Song.Score[2], 0);
+
+ // Go through all Entrys
+ while (not TableData.EOF) do
+ begin
+ // Add one Entry to Array
+ Difficulty := TableData.FieldAsInteger(TableData.FieldIndex['Difficulty']);
+ if ((Difficulty >= 0) and (Difficulty <= 2)) and
+ (Length(Song.Score[Difficulty]) < 5) then
+ begin
+ SetLength(Song.Score[Difficulty], Length(Song.Score[Difficulty]) + 1);
+
+ Song.Score[Difficulty, High(Song.Score[Difficulty])].Name :=
+ UTF8Decode(TableData.FieldByName['Player']);
+ Song.Score[Difficulty, High(Song.Score[Difficulty])].Score :=
+ TableData.FieldAsInteger(TableData.FieldIndex['Score']);
+ end;
+
+ TableData.Next;
+ end; // while
+
+ except
+ for Difficulty := 0 to 2 do
+ begin
+ SetLength(Song.Score[Difficulty], 1);
+ Song.Score[Difficulty, 1].Name := 'Error Reading ScoreDB';
+ end;
+ end;
+
+ TableData.Free;
+end;
+
+(**
+ * Adds one new score to DB
+ *)
+procedure TDataBaseSystem.AddScore(Song: TSong; Level: integer; const Name: WideString; Score: integer);
+var
+ ID: Integer;
+ TableData: TSQLiteTable;
+begin
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ // Prevent 0 Scores from being added
+ if (Score <= 0) then
+ Exit;
+
+ TableData := nil;
+
+ try
+
+ ID := ScoreDB.GetTableValue(
+ 'SELECT [ID] FROM ['+cUS_Songs+'] ' +
+ 'WHERE [Artist] = ? AND [Title] = ?',
+ [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
+ if (ID = 0) then
+ begin
+ // Create song if it does not exist
+ ScoreDB.ExecSQL(
+ 'INSERT INTO ['+cUS_Songs+'] ' +
+ '([ID], [Artist], [Title], [TimesPlayed]) VALUES ' +
+ '(NULL, ?, ?, 0);',
+ [UTF8Encode(Song.Artist), UTF8Encode(Song.Title)]);
+ // Get song-ID
+ ID := ScoreDB.GetLastInsertRowID();
+ end;
+ // Create new entry
+ ScoreDB.ExecSQL(
+ 'INSERT INTO ['+cUS_Scores+'] ' +
+ '([SongID] ,[Difficulty], [Player], [Score]) VALUES ' +
+ '(?, ?, ?, ?);',
+ [ID, Level, UTF8Encode(Name), Score]);
+
+ // Delete last position when there are more than 5 entrys.
+ // Fixes crash when there are > 5 ScoreEntrys
+ // Note: GetUniTable is not applicable here, as the results are used while
+ // table entries are deleted.
+ TableData := ScoreDB.GetTable(
+ 'SELECT [Player], [Score] FROM ['+cUS_Scores+'] ' +
+ 'WHERE [SongID] = ' + InttoStr(ID) + ' AND ' +
+ '[Difficulty] = ' + InttoStr(Level) +' ' +
+ 'ORDER BY [Score] DESC LIMIT -1 OFFSET 5');
+
+ while (not TableData.EOF) do
+ begin
+ // Note: Score is an int-value, so in contrast to Player, we do not bind
+ // this value. Otherwise we had to convert the string to an int to avoid
+ // an automatic cast of this field to the TEXT type (although it might even
+ // work that way).
+ ScoreDB.ExecSQL(
+ 'DELETE FROM ['+cUS_Scores+'] ' +
+ 'WHERE [SongID] = ' + InttoStr(ID) + ' AND ' +
+ '[Difficulty] = ' + InttoStr(Level) +' AND ' +
+ '[Player] = ? AND ' +
+ '[Score] = ' + TableData.FieldByName['Score'],
+ [TableData.FieldByName['Player']]);
+
+ TableData.Next;
+ end;
+
+ except on E: Exception do
+ Log.LogError(E.Message, 'TDataBaseSystem.AddScore');
+ end;
+
+ TableData.Free;
+end;
+
+(**
+ * Not needed with new System.
+ * Used for increment played count
+ *)
+procedure TDataBaseSystem.WriteScore(Song: TSong);
+begin
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ try
+ // Increase TimesPlayed
+ ScoreDB.ExecSQL(
+ 'UPDATE ['+cUS_Songs+'] ' +
+ 'SET [TimesPlayed] = [TimesPlayed] + 1 ' +
+ 'WHERE [Title] = ? AND [Artist] = ?;',
+ [UTF8Encode(Song.Title), UTF8Encode(Song.Artist)]);
+ except on E: Exception do
+ Log.LogError(E.Message, 'TDataBaseSystem.WriteScore');
+ end;
+end;
+
+(**
+ * Writes some stats to array.
+ * Returns nil if the database is not ready or a list with zero or more statistic
+ * entries.
+ * Free the result-list with FreeStats() after usage to avoid memory leaks.
+ *)
+function TDataBaseSystem.GetStats(Typ: TStatType; Count: Byte; Page: Cardinal; Reversed: Boolean): TList;
+var
+ Query: String;
+ TableData: TSQLiteUniTable;
+ Stat: TStatResult;
+begin
+ Result := nil;
+
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ {Todo: Add Prevention that only players with more than 5 scores are selected at type 2}
+
+ // Create query
+ case Typ of
+ stBestScores: begin
+ Query := 'SELECT [Player], [Difficulty], [Score], [Artist], [Title] FROM ['+cUS_Scores+'] ' +
+ 'INNER JOIN ['+cUS_Songs+'] ON ([SongID] = [ID]) ORDER BY [Score]';
+ end;
+ stBestSingers: begin
+ Query := 'SELECT [Player], ROUND(AVG([Score])) FROM ['+cUS_Scores+'] ' +
+ 'GROUP BY [Player] ORDER BY AVG([Score])';
+ end;
+ stMostSungSong: begin
+ Query := 'SELECT [Artist], [Title], [TimesPlayed] FROM ['+cUS_Songs+'] ' +
+ 'ORDER BY [TimesPlayed]';
+ end;
+ stMostPopBand: begin
+ Query := 'SELECT [Artist], SUM([TimesPlayed]) FROM ['+cUS_Songs+'] ' +
+ 'GROUP BY [Artist] ORDER BY SUM([TimesPlayed])';
+ end;
+ end;
+
+ // Add order direction
+ Query := Query + IfThen(Reversed, ' ASC', ' DESC');
+
+ // Add limit
+ Query := Query + ' LIMIT ' + InttoStr(Count * Page) + ', ' + InttoStr(Count) + ';';
+
+ // Execute query
+ try
+ TableData := ScoreDB.GetUniTable(Query);
+ except
+ on E: Exception do
+ begin
+ Log.LogError(E.Message, 'TDataBaseSystem.GetStats');
+ Exit;
+ end;
+ end;
+
+ Result := TList.Create;
+ Stat := nil;
+
+ // Copy result to stats array
+ while not TableData.EOF do
+ begin
+ case Typ of
+ stBestScores: begin
+ Stat := TStatResultBestScores.Create;
+ with TStatResultBestScores(Stat) do
+ begin
+ Singer := UTF8Decode(TableData.Fields[0]);
+ Difficulty := TableData.FieldAsInteger(1);
+ Score := TableData.FieldAsInteger(2);
+ SongArtist := UTF8Decode(TableData.Fields[3]);
+ SongTitle := UTF8Decode(TableData.Fields[4]);
+ end;
+ end;
+ stBestSingers: begin
+ Stat := TStatResultBestSingers.Create;
+ with TStatResultBestSingers(Stat) do
+ begin
+ Player := UTF8Decode(TableData.Fields[0]);
+ AverageScore := TableData.FieldAsInteger(1);
+ end;
+ end;
+ stMostSungSong: begin
+ Stat := TStatResultMostSungSong.Create;
+ with TStatResultMostSungSong(Stat) do
+ begin
+ Artist := UTF8Decode(TableData.Fields[0]);
+ Title := UTF8Decode(TableData.Fields[1]);
+ TimesSung := TableData.FieldAsInteger(2);
+ end;
+ end;
+ stMostPopBand: begin
+ Stat := TStatResultMostPopBand.Create;
+ with TStatResultMostPopBand(Stat) do
+ begin
+ ArtistName := UTF8Decode(TableData.Fields[0]);
+ TimesSungTot := TableData.FieldAsInteger(1);
+ end;
+ end
+ else
+ Log.LogCritical('Unknown stat-type', 'TDataBaseSystem.GetStats');
+ end;
+
+ Stat.Typ := Typ;
+ Result.Add(Stat);
+
+ TableData.Next;
+ end;
+
+ TableData.Free;
+end;
+
+procedure TDataBaseSystem.FreeStats(StatList: TList);
+var
+ I: integer;
+begin
+ if (StatList = nil) then
+ Exit;
+ for I := 0 to StatList.Count-1 do
+ TStatResult(StatList[I]).Free;
+ StatList.Free;
+end;
+
+(**
+ * Gets total number of entrys for a stats query
+ *)
+function TDataBaseSystem.GetTotalEntrys(Typ: TStatType): Cardinal;
+var
+ Query: String;
+begin
+ Result := 0;
+
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ try
+ // Create query
+ case Typ of
+ stBestScores:
+ Query := 'SELECT COUNT([SongID]) FROM ['+cUS_Scores+'];';
+ stBestSingers:
+ Query := 'SELECT COUNT(DISTINCT [Player]) FROM ['+cUS_Scores+'];';
+ stMostSungSong:
+ Query := 'SELECT COUNT([ID]) FROM ['+cUS_Songs+'];';
+ stMostPopBand:
+ Query := 'SELECT COUNT(DISTINCT [Artist]) FROM ['+cUS_Songs+'];';
+ end;
+
+ Result := ScoreDB.GetTableValue(Query);
+ except on E: Exception do
+ Log.LogError(E.Message, 'TDataBaseSystem.GetTotalEntrys');
+ end;
+
+end;
+
+(**
+ * Gets reset date of statistic data
+ *)
+function TDataBaseSystem.GetStatReset: TDateTime;
+var
+ Query: string;
+ ResetTime: int64;
+begin
+ Result := 0;
+
+ if not Assigned(ScoreDB) then
+ Exit;
+
+ try
+ Query := 'SELECT [ResetTime] FROM ['+cUS_Statistics_Info+'];';
+ Result := UnixToDateTime(ScoreDB.GetTableValue(Query));
+ except on E: Exception do
+ Log.LogError(E.Message, 'TDataBaseSystem.GetStatReset');
+ end;
+end;
+
+function TDataBaseSystem.GetVersion(): integer;
+begin
+ Result := ScoreDB.GetTableValue('PRAGMA user_version');
+end;
+
+procedure TDataBaseSystem.SetVersion(Version: integer);
+begin
+ ScoreDB.ExecSQL(Format('PRAGMA user_version = %d', [Version]));
+end;
+
+end.
diff --git a/src/Classes/UDraw.pas b/src/Classes/UDraw.pas
new file mode 100644
index 00000000..ff0920f5
--- /dev/null
+++ b/src/Classes/UDraw.pas
@@ -0,0 +1,1390 @@
+unit UDraw;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ ModiSDK,
+ UGraphicClasses;
+
+procedure SingDraw;
+procedure SingModiDraw (PlayerInfo: TPlayerInfo);
+procedure SingDrawBackground;
+procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
+procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
+procedure SingDrawLyricHelper(Left, LyricsMid: real);
+procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer);
+procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
+procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer);
+procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer);
+
+// TimeBar
+procedure SingDrawTimeBar();
+
+//Draw Editor NoteLines
+procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
+
+
+type
+ TRecR = record
+ Top: real;
+ Left: real;
+ Right: real;
+ Bottom: real;
+
+ Width: real;
+ WMid: real;
+ Height: real;
+ HMid: real;
+
+ Mid: real;
+ end;
+
+var
+ NotesW: real;
+ NotesH: real;
+ Starfr: integer;
+ StarfrG: integer;
+
+ //SingBar
+ TickOld: cardinal;
+ TickOld2:cardinal;
+
+const
+ Przedz = 32;
+
+implementation
+
+uses
+ gl,
+ UGraphic,
+ SysUtils,
+ UMusic,
+ URecord,
+ ULog,
+ UScreenSing,
+ UScreenSingModi,
+ ULyrics,
+ UMain,
+ TextGL,
+ UTexture,
+ UDrawTexture,
+ UIni,
+ Math,
+ UDLLManager;
+
+procedure SingDrawBackground;
+var
+ Rec: TRecR;
+ TexRec: TRecR;
+begin
+ if (ScreenSing.Tex_Background.TexNum > 0) then begin
+
+ glClearColor (1, 1, 1, 1);
+ glColor4f (1, 1, 1, 1);
+
+ if (Ini.MovieSize <= 1) then //HalfSize BG
+ begin
+ (* half screen + gradient *)
+ Rec.Top := 110; // 80
+ Rec.Bottom := Rec.Top + 20;
+ Rec.Left := 0;
+ Rec.Right := 800;
+
+ TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ TexRec.Left := 0;
+ TexRec.Right := ScreenSing.Tex_Background.TexW;
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ (* gradient draw *)
+ (* top *)
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glColor4f(1, 1, 1, 1);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+ (* mid *)
+ Rec.Top := Rec.Bottom;
+ Rec.Bottom := 490 - 20; // 490 - 20
+ TexRec.Top := TexRec.Bottom;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ (* bottom *)
+ Rec.Top := Rec.Bottom;
+ Rec.Bottom := 490; // 490
+ TexRec.Top := TexRec.Bottom;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ end
+ else //Full Size BG
+ begin
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
+ //glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0, 0); glVertex2f(0, 0);
+ glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600);
+ glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600);
+ glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0);
+
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ //glDisable(GL_BLEND);
+ end;
+ end;
+end;
+
+procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
+var
+ SampleIndex: integer;
+ Sound: TCaptureBuffer;
+ MaxX, MaxY: real;
+begin;
+ Sound := AudioInputProcessor.Sound[NrSound];
+
+ // Log.LogStatus('Oscilloscope', 'SingDraw');
+ glColor3f(Skin_OscR, Skin_OscG, Skin_OscB);
+ {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
+ glColor3f(1, 1, 1); }
+
+ MaxX := W-1;
+ MaxY := (H-1) / 2;
+
+ Sound.LockAnalysisBuffer();
+
+ glBegin(GL_LINE_STRIP);
+ for SampleIndex := 0 to High(Sound.AnalysisBuffer) do
+ begin
+ glVertex2f(X + MaxX * SampleIndex/High(Sound.AnalysisBuffer),
+ Y + MaxY * (1 - Sound.AnalysisBuffer[SampleIndex]/-Low(Smallint)));
+ end;
+ glEnd;
+
+ Sound.UnlockAnalysisBuffer();
+end;
+
+
+
+procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
+var
+ Count: integer;
+begin
+ glEnable(GL_BLEND);
+ glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4);
+ glBegin(GL_LINES);
+ for Count := 0 to 9 do begin
+ glVertex2f(Left, Top + Count * Space);
+ glVertex2f(Right, Top + Count * Space);
+ end;
+ glEnd;
+ glDisable(GL_BLEND);
+end;
+
+procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer);
+var
+ Count: integer;
+ TempR: real;
+begin
+ TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
+ glEnable(GL_BLEND);
+ glBegin(GL_LINES);
+ for Count := Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start to Lines[NrLines].Line[Lines[NrLines].Current].End_ do begin
+ if (Count mod Lines[NrLines].Resolution) = Lines[NrLines].NotesGAP then
+ glColor4f(0, 0, 0, 1)
+ else
+ glColor4f(0, 0, 0, 0.3);
+ glVertex2f(Left + TempR * (Count - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start), Top);
+ glVertex2f(Left + TempR * (Count - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start), Top + 135);
+ end;
+ glEnd;
+ glDisable(GL_BLEND);
+end;
+
+// draw blank Notebars
+procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
+var
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
+ R,G,B: real;
+
+ PlayerNumber: Integer;
+
+ GoldenStarPos : real;
+
+ lTmpA ,
+ lTmpB : real;
+begin
+// We actually don't have a playernumber in this procedure, it should reside in NrLines - but it's always set to zero
+// So we exploit this behavior a bit - we give NrLines the playernumber, keep it in playernumber - and then we set NrLines to zero
+// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then
+// BUT this is not implemented yet, all notes are drawn! :D
+
+ PlayerNumber := NrLines + 1; // Player 1 is 0
+ NrLines := 0;
+
+// exploit done
+
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ lTmpA := (Right-Left);
+ lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
+
+ if ( lTmpA > 0 ) AND
+ ( lTmpB > 0 ) THEN
+ begin
+ TempR := lTmpA / lTmpB;
+ end
+ else
+ begin
+ TempR := 0;
+ end;
+
+
+ with Lines[NrLines].Line[Lines[NrLines].Current] do begin
+ for Count := 0 to HighNote do begin
+ with Note[Count] do begin
+ if NoteType <> ntFreestyle then begin
+
+
+ if Ini.EffectSing = 0 then
+ // If Golden note Effect of then Change not Color
+ begin
+ case NoteType of
+ ntNormal: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
+ ntGolden: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could
+ end; // case
+ end //Else all Notes same Color
+ else
+ glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
+ // Czesci == teil, element == piece, element | koniec == end / ending
+ // lewa czesc - left part
+ Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+ Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
+ Rec.Bottom := Rec.Top + 2 * NotesH;
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ //We keep the postion of the top left corner b4 it's overwritten
+ GoldenStarPos := Rec.Left;
+ //done
+
+ // srodkowa czesc - middle part
+ Rec.Left := Rec.Right;
+ Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == length
+
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc - right part
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Golden Star Patch
+ if (NoteType = ntGolden) AND (Ini.EffectSing=1) then
+ begin
+ GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom);
+ end;
+
+ end; // if not FreeStyle
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+
+// draw sung notes
+procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer);
+var
+ TempR: real;
+ Rec: TRecR;
+ N: integer;
+ R, G, B, A: real;
+ NotesH2: real;
+begin
+ //Log.LogStatus('Player notes', 'SingDraw');
+
+ //if NrGracza = 0 then LoadColor(R, G, B, 'P1Light')
+ //else LoadColor(R, G, B, 'P2Light');
+
+ //R := 71/255;
+ //G := 175/255;
+ //B := 247/255;
+
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ //if Player[NrGracza].LengthNote > 0 then
+ begin
+ TempR := W / (Lines[0].Line[Lines[0].Current].End_ - Lines[0].Line[Lines[0].Current].Note[0].Start);
+ for N := 0 to Player[PlayerIndex].HighNote do
+ begin
+ with Player[PlayerIndex].Note[N] do
+ begin
+ // Left part of note
+ Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+
+ // Draw it in half size, if not hit
+ if Hit then
+ begin
+ NotesH2 := NotesH
+ end
+ else
+ begin
+ NotesH2 := int(NotesH * 0.65);
+ end;
+
+ Rec.Top := Y - (Tone-Lines[0].Line[Lines[0].Current].BaseNote)*Space/2 - NotesH2;
+ Rec.Bottom := Rec.Top + 2 *NotesH2;
+
+ // draw the left part
+ glColor3f(1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[PlayerIndex+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Middle part of the note
+ Rec.Left := Rec.Right;
+ Rec.Right := X + (Start+Length-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR - NotesW - 0.5 + 10*ScreenX;
+
+ // (nowe) - dunno
+ if (Start+Length-1 = LyricsState.CurrentBeatD) then
+ Rec.Right := Rec.Right - (1-Frac(LyricsState.MidBeatD)) * TempR;
+ // the left note is more right than the right note itself, sounds weird - so we fix that xD
+ if Rec.Right <= Rec.Left then
+ Rec.Right := Rec.Left;
+
+ // draw the middle part
+ glBindTexture(GL_TEXTURE_2D, Tex_Mid[PlayerIndex+1].TexNum);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glColor3f(1, 1, 1);
+
+ // the right part of the note
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Right[PlayerIndex+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Perfect note is stored
+ if Perfect and (Ini.EffectSing=1) then
+ begin
+ A := 1 - 2*(LyricsState.GetCurrentTime() - GetTimeFromBeat(Start+Length));
+ if not (Start+Length-1 = LyricsState.CurrentBeatD) then
+ begin
+ //Star animation counter
+ //inc(Starfr);
+ //Starfr := Starfr mod 128;
+ GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top);
+ end;
+ end;
+ end; // with
+ end; // for
+
+ // actually we need a comparison here, to determine if the singing process
+ // is ahead Rec.Right even if there is no singing
+
+ if (Ini.EffectSing = 1) then
+ GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, PlayerIndex);
+ end; // if
+end;
+
+//draw Note glow
+procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer);
+var
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
+ R,G,B: real;
+ X1, X2, X3, X4: real;
+ W, H: real;
+
+ lTmpA ,
+ lTmpB : real;
+begin
+ if (Player[PlayerIndex].ScoreTotalInt >= 0) then
+ begin
+ glColor4f(1, 1, 1, sqrt((1+sin( AudioPlayback.Position * 3))/4)/ 2 + 0.5 );
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ lTmpA := (Right-Left);
+ lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
+
+ if ( lTmpA > 0 ) and
+ ( lTmpB > 0 ) then
+ begin
+ TempR := lTmpA / lTmpB;
+ end
+ else
+ begin
+ TempR := 0;
+ end;
+
+ with Lines[NrLines].Line[Lines[NrLines].Current] do
+ begin
+ for Count := 0 to HighNote do
+ begin
+ with Note[Count] do
+ begin
+ if NoteType <> ntFreestyle then
+ begin
+ // begin: 14, 20
+ // easy: 6, 11
+ W := NotesW * 2 + 2;
+ H := NotesH * 1.5 + 3.5;
+
+ X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie
+ X1 := X2-W;
+
+ X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie
+ X4 := X3+W;
+
+ // left
+ Rec.Left := X1;
+ Rec.Right := X2;
+ Rec.Top := Top - (Tone-BaseNote)*Space/2 - H;
+ Rec.Bottom := Rec.Top + 2 * H;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[PlayerIndex+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // srodkowa czesc
+ Rec.Left := X2;
+ Rec.Right := X3;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[PlayerIndex+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc
+ Rec.Left := X3;
+ Rec.Right := X4;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[PlayerIndex+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ end; // if not FreeStyle
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end;
+end;
+
+(**
+ * Draws the lyrics helper bar.
+ * Left: position the bar starts at
+ * LyricsMid: the middle of the lyrics relative to the position Left
+ *)
+procedure SingDrawLyricHelper(Left, LyricsMid: real);
+var
+ Bounds: TRecR; // bounds of the lyric help bar
+ BarProgress: real; // progress of the lyrics helper
+ BarMoveDelta: real; // current beat relative to the beat the bar starts to move at
+ BarAlpha: real; // transparency
+ CurLine: PLine; // current lyric line (beat specific)
+ LineWidth: real; // lyric line width
+ FirstNoteBeat: integer; // beat of the first note in the current line
+ FirstNoteDelta: integer; // time in beats between the start of the current line and its first note
+ MoveStartX: real; // x-pos. the bar starts to move from
+ MoveDist: real; // number of pixels the bar will move
+ LyricEngine: TLyricEngine;
+const
+ BarWidth = 50; // width of the lyric helper bar
+ BarHeight = 30; // height of the lyric helper bar
+ BarMoveLimit = 40; // max. number of beats remaining before the bar starts to move
+begin
+ // get current lyrics line and the time in beats of its first note
+ CurLine := @Lines[0].Line[Lines[0].Current];
+
+ // FIXME: accessing ScreenSing is not that generic
+ LyricEngine := ScreenSing.Lyrics;
+
+ // do not draw the lyrics helper if the current line does not contain any note
+ if (Length(CurLine.Note) > 0) then
+ begin
+ // start beat of the first note of this line
+ FirstNoteBeat := CurLine.Note[0].Start;
+ // time in beats between the start of the current line and its first note
+ FirstNoteDelta := FirstNoteBeat - CurLine.Start;
+
+ // beats from current beat to the first note of the line
+ BarMoveDelta := FirstNoteBeat - LyricsState.MidBeat;
+
+ if (FirstNoteDelta > 8) and // if the wait-time is large enough
+ (BarMoveDelta > 0) then // and the first note of the line is not reached
+ begin
+ // let the bar blink to the beat
+ BarAlpha := 0.75 + cos(BarMoveDelta/2) * 0.25;
+
+ // if the number of beats to the first note is too big,
+ // the bar stays on the left side.
+ if (BarMoveDelta > BarMoveLimit) then
+ BarMoveDelta := BarMoveLimit;
+
+ // limit number of beats the bar moves
+ if (FirstNoteDelta > BarMoveLimit) then
+ FirstNoteDelta := BarMoveLimit;
+
+ // calc bar progress
+ BarProgress := 1 - BarMoveDelta / FirstNoteDelta;
+
+ // retrieve the width of the upper lyrics line on the display
+ if (LyricEngine.GetUpperLine() <> nil) then
+ LineWidth := LyricEngine.GetUpperLine().Width
+ else
+ LineWidth := 0;
+
+ // distance the bar will move (LyricRec.Left to beginning of text)
+ MoveDist := LyricsMid - LineWidth / 2 - BarWidth;
+ // if the line is too long the helper might move from right to left
+ // so we have to assure the start position is left of the text.
+ if (MoveDist >= 0) then
+ MoveStartX := Left
+ else
+ MoveStartX := Left + MoveDist;
+
+ // determine lyric help bar position and size
+ Bounds.Left := MoveStartX + BarProgress * MoveDist;
+ Bounds.Right := Bounds.Left + BarWidth;
+ Bounds.Top := Skin_LyricsT + 3;
+ Bounds.Bottom := Bounds.Top + BarHeight + 3;
+
+ // draw lyric help bar
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, BarAlpha);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Bounds.Left, Bounds.Top);
+ glTexCoord2f(0, 1); glVertex2f(Bounds.Left, Bounds.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Bounds.Right, Bounds.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Bounds.Right, Bounds.Top);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ end;
+end;
+
+procedure SingDraw;
+var
+ NR: TRecR; // lyrics area bounds (NR = NoteRec?)
+ LyricEngine: TLyricEngine;
+begin
+ // positions
+ if Ini.SingWindow = 0 then
+ NR.Left := 120
+ else
+ NR.Left := 20;
+
+ NR.Right := 780;
+
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ // FIXME: accessing ScreenSing is not that generic
+ LyricEngine := ScreenSing.Lyrics;
+
+ // background //BG Fullsize Mod
+ //SingDrawBackground;
+
+ // draw time-bar
+ SingDrawTimeBar();
+
+ // draw note-lines
+
+ if (PlayersPlay = 1) and (Ini.NoteLines = 1) then
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+
+ if ((PlayersPlay = 2) or (PlayersPlay = 4)) and (Ini.NoteLines = 1) then
+ begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ end;
+
+ if ((PlayersPlay = 3) or (PlayersPlay = 6)) and (Ini.NoteLines = 1) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ end;
+
+ // draw Lyrics
+ LyricEngine.Draw(LyricsState.MidBeat);
+ SingDrawLyricHelper(NR.Left, NR.WMid);
+
+ // oscilloscope
+ if Ini.Oscilloscope = 1 then begin
+ if PlayersPlay = 1 then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+
+ if PlayersPlay = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
+ end;
+ end;
+
+ if PlayersPlay = 3 then begin
+ SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
+ end;
+ end;
+
+ end;
+
+ // Set the note heights according to the difficulty level
+ case Ini.Difficulty of
+ 0:
+ begin
+ NotesH := 11; // 9
+ NotesW := 6; // 5
+ end;
+ 1:
+ begin
+ NotesH := 8; // 7
+ NotesW := 4; // 4
+ end;
+ 2:
+ begin
+ NotesH := 5;
+ NotesW := 3;
+ end;
+ end;
+
+ // Draw the Notes
+ if PlayersPlay = 1 then begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes
+ end;
+
+ if (PlayersPlay = 2) then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+
+ SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
+
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+
+ if PlayersPlay = 3 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+
+ SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
+ SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
+
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
+ SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 3, 12);
+ SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 4, 12);
+ SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 5, 12);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ end;
+ end;
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+// q'n'd for using the game mode dll's
+procedure SingModiDraw (PlayerInfo: TPlayerInfo);
+var
+ Count: integer;
+ Pet2: integer;
+ TempR: real;
+ Rec: TRecR;
+ TexRec: TRecR;
+ NR: TRecR;
+ FS: real;
+ BarFrom: integer;
+ BarAlpha: real;
+ BarWspol: real;
+ TempCol: real;
+ Tekst: string;
+ PetCz: integer;
+begin
+ // positions
+ if Ini.SingWindow = 0 then begin
+ NR.Left := 120;
+ end else begin
+ NR.Left := 20;
+ end;
+
+ NR.Right := 780;
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ // time bar
+ SingDrawTimeBar();
+
+ if DLLMan.Selected.ShowNotes then
+ begin
+ if PlayersPlay = 1 then
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ end;
+
+ if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ end;
+ end;
+
+ // Draw Lyrics
+ ScreenSingModi.Lyrics.Draw(LyricsState.MidBeat);
+
+ // todo: Lyrics
+{ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
+ FS := 1.3;
+ BarFrom := Lines[0].Line[Lines[0].Current].StartNote - Lines[0].Line[Lines[0].Current].Start;
+ if BarFrom > 40 then BarFrom := 40;
+ if (Lines[0].Line[Lines[0].Current].StartNote - Lines[0].Line[Lines[0].Current].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
+ (Lines[0].Line[Lines[0].Current].StartNote - LyricsState.MidBeat > 0) and // przed tekstem
+ (Lines[0].Line[Lines[0].Current].StartNote - LyricsState.MidBeat < 40) then begin // ale nie za wczesnie
+ BarWspol := (LyricsState.MidBeat - (Lines[0].Line[Lines[0].Current].StartNote - BarFrom)) / BarFrom;
+ Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
+ Rec.Right := Rec.Left + 50;
+ Rec.Top := Skin_LyricsT + 3;
+ Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
+ glBegin(GL_QUADS);
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glColor4f(1, 1, 1, 0.5);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ }
+
+ // oscilloscope | the thing that moves when you yell into your mic (imho)
+ if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin
+ if PlayersPlay = 1 then
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+
+ if PlayersPlay = 2 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
+ end;
+ end;
+
+ if PlayersPlay = 3 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
+ if PlayerInfo.Playerinfo[4].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
+ if PlayerInfo.Playerinfo[5].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
+ end;
+ end;
+
+ end;
+
+// resize the notes according to the difficulty level
+ case Ini.Difficulty of
+ 0:
+ begin
+ NotesH := 11; // 9
+ NotesW := 6; // 5
+ end;
+ 1:
+ begin
+ NotesH := 8; // 7
+ NotesW := 4; // 4
+ end;
+ 2:
+ begin
+ NotesH := 5;
+ NotesW := 3;
+ end;
+ end;
+
+ if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then
+ begin
+ if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
+ end;
+
+ if (PlayersPlay = 2) then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ end;
+ if PlayerInfo.Playerinfo[1].Enabled then
+ begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+
+ end;
+
+ if PlayersPlay = 3 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if PlayerInfo.Playerinfo[0].Enabled then
+ begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ end;
+
+ if PlayerInfo.Playerinfo[1].Enabled then
+ begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ end;
+
+ if PlayerInfo.Playerinfo[2].Enabled then
+ begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ end;
+
+ SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
+ SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ end;
+
+ SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
+ SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
+ SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ end;
+ end;
+ end;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+
+{//SingBar Mod
+procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
+var
+ R: Real;
+ G: Real;
+ B: Real;
+ A: cardinal;
+ I: Integer;
+
+begin;
+
+ //SingBar Background
+ glColor4f(1, 1, 1, 0.8);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+W, Y);
+ glEnd;
+
+ //SingBar coloured Bar
+ Case Percent of
+ 0..22: begin
+ R := 1;
+ G := 0;
+ B := 0;
+ end;
+ 23..42: begin
+ R := 1;
+ G := ((Percent-23)/100)*5;
+ B := 0;
+ end;
+ 43..57: begin
+ R := 1;
+ G := 1;
+ B := 0;
+ end;
+ 58..77: begin
+ R := 1-(Percent - 58)/100*5;
+ G := 1;
+ B := 0;
+ end;
+ 78..99: begin
+ R := 0;
+ G := 1;
+ B := 0;
+ end;
+ End; //Case
+
+ glColor4f(R, G, B, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum);
+ //Size= Player[PlayerNum].ScorePercent of W
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y);
+ glEnd;
+
+ //SingBar Front
+ glColor4f(1, 1, 1, 0.6);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+W, Y);
+ glEnd;
+end;
+//end Singbar Mod
+
+//PhrasenBonus - Line Bonus Pop Up
+procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
+var
+Length, X2: Real; //Length of Text
+Size: Integer; //Size of Popup
+begin
+if Alpha <> 0 then
+begin
+
+//Set Font Propertys
+SetFontStyle(2); //Font: Outlined1
+if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6);
+SetFontItalic(False);
+
+//Check Font Size
+Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^
+
+//Text
+SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
+
+
+if Age < 5 then Size := Age * 10 else Size := 50;
+
+ //Draw Background
+ //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
+ glColor4f(1, 1, 1, Alpha);
+
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+
+ //New Method, Not Variable
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
+ glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
+ glEnd;
+
+ glColor4f(1, 1, 1, Alpha); //Set Color
+ //Draw Text
+ glPrint (PChar(Text));
+end;
+end;
+//PhrasenBonus - Line Bonus Mod}
+
+// Draw Note Bars for Editor
+//There are 11 Resons for a new Procdedure: (nice binary :D )
+// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor
+// 2. You can see the Freestyle Notes in the Editor SemiTransparent
+// 3. Its easier and Faster then changing the old Procedure
+procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
+var
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
+begin
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
+ with Lines[NrLines].Line[Lines[NrLines].Current] do begin
+ for Count := 0 to HighNote do begin
+ with Note[Count] do begin
+
+ // Golden Note Patch
+ case NoteType of
+ ntFreestyle: glColor4f(1, 1, 1, 0.35);
+ ntNormal: glColor4f(1, 1, 1, 0.85);
+ ntGolden: Glcolor4f(1, 1, 0.3, 0.85);
+ end; // case
+
+
+
+ // lewa czesc - left part
+ Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+ Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
+ Rec.Bottom := Rec.Top + 2 * NotesH;
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // srodkowa czesc - middle part
+ Rec.Left := Rec.Right;
+ Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc - right part
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+procedure SingDrawTimeBar();
+var
+ x,y: real;
+ width, height: real;
+ LyricsProgress: real;
+ CurLyricsTime: real;
+begin
+ x := Theme.Sing.StaticTimeProgress.x;
+ y := Theme.Sing.StaticTimeProgress.y;
+
+ width := Theme.Sing.StaticTimeProgress.w;
+ height := Theme.Sing.StaticTimeProgress.h;
+
+ glColor4f(Theme.Sing.StaticTimeProgress.ColR,
+ Theme.Sing.StaticTimeProgress.ColG,
+ Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0);
+ glVertex2f(x, y);
+
+ CurLyricsTime := LyricsState.GetCurrentTime();
+ if (CurLyricsTime > 0) and
+ (LyricsState.TotalTime > 0) then
+ begin
+ LyricsProgress := CurLyricsTime / LyricsState.TotalTime;
+ glTexCoord2f((width * LyricsProgress) / 8, 0);
+ glVertex2f(x + width * LyricsProgress, y);
+
+ glTexCoord2f((width * LyricsProgress) / 8, 1);
+ glVertex2f(x + width * LyricsProgress, y + height);
+ end;
+
+ glTexCoord2f(0, 1);
+ glVertex2f(x, y + height);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glcolor4f(1, 1, 1, 1);
+end;
+
+end.
+
diff --git a/src/Classes/UEditorLyrics.pas b/src/Classes/UEditorLyrics.pas
new file mode 100644
index 00000000..25e8423e
--- /dev/null
+++ b/src/Classes/UEditorLyrics.pas
@@ -0,0 +1,229 @@
+unit UEditorLyrics;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ gl,
+ UMusic,
+ UTexture;
+
+type
+ TWord = record
+ X: real;
+ Y: real;
+ Size: real;
+ Width: real;
+ Text: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ FontStyle: integer;
+ Italic: boolean;
+ Selected: boolean;
+ end;
+
+ TEditorLyrics = class
+ private
+ AlignI: integer;
+ XR: real;
+ YR: real;
+ SizeR: real;
+ SelectedI: integer;
+ FontStyleI: integer; // font number
+ Word: array of TWord;
+
+ procedure SetX(Value: real);
+ procedure SetY(Value: real);
+ function GetClientX: real;
+ procedure SetAlign(Value: integer);
+ function GetSize: real;
+ procedure SetSize(Value: real);
+ procedure SetSelected(Value: integer);
+ procedure SetFStyle(Value: integer);
+ procedure AddWord(Text: string);
+ procedure Refresh;
+ public
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ ColSR: real;
+ ColSG: real;
+ ColSB: real;
+ Italic: boolean;
+
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure AddLine(NrLine: integer);
+
+ procedure Clear;
+ procedure Draw;
+ published
+ property X: real write SetX;
+ property Y: real write SetY;
+ property ClientX: real read GetClientX;
+ property Align: integer write SetAlign;
+ property Size: real read GetSize write SetSize;
+ property Selected: integer read SelectedI write SetSelected;
+ property FontStyle: integer write SetFStyle;
+ end;
+
+implementation
+
+uses
+ TextGL, UGraphic, UDrawTexture, Math, USkins;
+
+constructor TEditorLyrics.Create;
+begin
+ inherited;
+end;
+
+destructor TEditorLyrics.Destroy;
+begin
+ SetLength(Word, 0);
+ inherited;
+end;
+
+procedure TEditorLyrics.SetX(Value: real);
+begin
+ XR := Value;
+end;
+
+procedure TEditorLyrics.SetY(Value: real);
+begin
+ YR := Value;
+end;
+
+function TEditorLyrics.GetClientX: real;
+begin
+ Result := Word[0].X;
+end;
+
+procedure TEditorLyrics.SetAlign(Value: integer);
+begin
+ AlignI := Value;
+end;
+
+function TEditorLyrics.GetSize: real;
+begin
+ Result := SizeR;
+end;
+
+procedure TEditorLyrics.SetSize(Value: real);
+begin
+ SizeR := Value;
+end;
+
+procedure TEditorLyrics.SetSelected(Value: integer);
+var
+ W: integer;
+begin
+ if (SelectedI > -1) and (SelectedI <= High(Word)) then
+ begin
+ Word[SelectedI].Selected := false;
+ Word[SelectedI].ColR := ColR;
+ Word[SelectedI].ColG := ColG;
+ Word[SelectedI].ColB := ColB;
+ end;
+
+ SelectedI := Value;
+ if (Value > -1) and (Value <= High(Word)) then
+ begin
+ Word[Value].Selected := true;
+ Word[Value].ColR := ColSR;
+ Word[Value].ColG := ColSG;
+ Word[Value].ColB := ColSB;
+ end;
+
+ Refresh;
+end;
+
+procedure TEditorLyrics.SetFStyle(Value: integer);
+begin
+ FontStyleI := Value;
+end;
+
+procedure TEditorLyrics.AddWord(Text: string);
+var
+ WordNum: integer;
+begin
+ WordNum := Length(Word);
+ SetLength(Word, WordNum + 1);
+ if WordNum = 0 then begin
+ Word[WordNum].X := XR;
+ end else begin
+ Word[WordNum].X := Word[WordNum - 1].X + Word[WordNum - 1].Width;
+ end;
+
+ Word[WordNum].Y := YR;
+ Word[WordNum].Size := SizeR;
+ Word[WordNum].FontStyle := FontStyleI;
+ SetFontStyle(FontStyleI);
+ SetFontSize(SizeR);
+ Word[WordNum].Width := glTextWidth(pchar(Text));
+ Word[WordNum].Text := Text;
+ Word[WordNum].ColR := ColR;
+ Word[WordNum].ColG := ColG;
+ Word[WordNum].ColB := ColB;
+ Word[WordNum].Italic := Italic;
+
+ Refresh;
+end;
+
+procedure TEditorLyrics.AddLine(NrLine: integer);
+var
+ N: integer;
+begin
+ Clear;
+ for N := 0 to Lines[0].Line[NrLine].HighNote do begin
+ Italic := Lines[0].Line[NrLine].Note[N].NoteType = ntFreestyle;
+ AddWord(Lines[0].Line[NrLine].Note[N].Text);
+ end;
+ Selected := -1;
+end;
+
+procedure TEditorLyrics.Clear;
+begin
+ SetLength(Word, 0);
+ SelectedI := -1;
+end;
+
+procedure TEditorLyrics.Refresh;
+var
+ W: integer;
+ TotWidth: real;
+begin
+ if AlignI = 1 then begin
+ TotWidth := 0;
+ for W := 0 to High(Word) do
+ TotWidth := TotWidth + Word[W].Width;
+
+ Word[0].X := XR - TotWidth / 2;
+ for W := 1 to High(Word) do
+ Word[W].X := Word[W - 1].X + Word[W - 1].Width;
+ end;
+end;
+
+procedure TEditorLyrics.Draw;
+var
+ W: integer;
+begin
+ for W := 0 to High(Word) do
+ begin
+ SetFontStyle(Word[W].FontStyle);
+ SetFontPos(Word[W].X+ 10*ScreenX, Word[W].Y);
+ SetFontSize(Word[W].Size);
+ SetFontItalic(Word[W].Italic);
+ glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
+ glPrint(pchar(Word[W].Text));
+ end;
+end;
+
+end.
diff --git a/src/Classes/UFiles.pas b/src/Classes/UFiles.pas
new file mode 100644
index 00000000..ca43bb21
--- /dev/null
+++ b/src/Classes/UFiles.pas
@@ -0,0 +1,150 @@
+unit UFiles;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+{$I switches.inc}
+
+uses SysUtils,
+ ULog,
+ UMusic,
+ USongs,
+ USong;
+
+procedure ResetSingTemp;
+function SaveSong(Song: TSong; Lines: TLines; Name: string; Relative: boolean): boolean;
+
+var
+ SongFile: TextFile; // all procedures in this unit operates on this file
+ FileLineNo: integer; //Line which is readed at Last, for error reporting
+
+ // variables available for all procedures
+ Base : array[0..1] of integer;
+ Rel : array[0..1] of integer;
+ Mult : integer = 1;
+ MultBPM : integer = 4;
+
+implementation
+
+uses TextGL,
+ UIni,
+ UPlatform,
+ UMain;
+
+//--------------------
+// Resets the temporary Sentence Arrays for each Player and some other Variables
+//--------------------
+procedure ResetSingTemp;
+var
+ Count: integer;
+begin
+ SetLength(Lines, Length(Player));
+ for Count := 0 to High(Player) do begin
+ SetLength(Lines[Count].Line, 1);
+ SetLength(Lines[Count].Line[0].Note, 0);
+ Lines[Count].Line[0].Lyric := '';
+ Lines[Count].Line[0].LyricWidth := 0;
+ Player[Count].Score := 0;
+ Player[Count].LengthNote := 0;
+ Player[Count].HighNote := -1;
+ end;
+
+ (* FIXME
+ //Reset Path and Filename Values to Prevent Errors in Editor
+ if assigned( CurrentSong ) then
+ begin
+ SetLength(CurrentSong.BPM, 0);
+ CurrentSong.Path := '';
+ CurrentSong.FileName := '';
+ end;
+ *)
+
+// CurrentSong := nil;
+end;
+
+
+//--------------------
+// Saves a Song
+//--------------------
+function SaveSong(Song: TSong; Lines: TLines; Name: string; Relative: boolean): boolean;
+var
+ C: integer;
+ N: integer;
+ S: string;
+ B: integer;
+ RelativeSubTime: integer;
+ NoteState: String;
+
+begin
+// Relative := true; // override (idea - use shift+S to save with relative)
+ AssignFile(SongFile, Name);
+ Rewrite(SongFile);
+
+ Writeln(SongFile, '#TITLE:' + Song.Title + '');
+ Writeln(SongFile, '#ARTIST:' + Song.Artist);
+
+ if Song.Creator <> '' then Writeln(SongFile, '#CREATOR:' + Song.Creator);
+ if Song.Edition <> 'Unknown' then Writeln(SongFile, '#EDITION:' + Song.Edition);
+ if Song.Genre <> 'Unknown' then Writeln(SongFile, '#GENRE:' + Song.Genre);
+ if Song.Language <> 'Unknown' then Writeln(SongFile, '#LANGUAGE:' + Song.Language);
+
+ Writeln(SongFile, '#MP3:' + Song.Mp3);
+
+ if Song.Cover <> '' then Writeln(SongFile, '#COVER:' + Song.Cover);
+ if Song.Background <> '' then Writeln(SongFile, '#BACKGROUND:' + Song.Background);
+ if Song.Video <> '' then Writeln(SongFile, '#VIDEO:' + Song.Video);
+ if Song.VideoGAP <> 0 then Writeln(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP));
+ if Song.Resolution <> 4 then Writeln(SongFile, '#RESOLUTION:' + IntToStr(Song.Resolution));
+ if Song.NotesGAP <> 0 then Writeln(SongFile, '#NOTESGAP:' + IntToStr(Song.NotesGAP));
+ if Song.Start <> 0 then Writeln(SongFile, '#START:' + FloatToStr(Song.Start));
+ if Song.Finish <> 0 then Writeln(SongFile, '#END:' + IntToStr(Song.Finish));
+ if Relative then Writeln(SongFile, '#RELATIVE:yes');
+
+ Writeln(SongFile, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4));
+ Writeln(SongFile, '#GAP:' + FloatToStr(Song.GAP));
+
+ RelativeSubTime := 0;
+ for B := 1 to High(CurrentSong.BPM) do
+ Writeln(SongFile, 'B ' + FloatToStr(CurrentSong.BPM[B].StartBeat) + ' ' + FloatToStr(CurrentSong.BPM[B].BPM/4));
+
+ for C := 0 to Lines.High do begin
+ for N := 0 to Lines.Line[C].HighNote do begin
+ with Lines.Line[C].Note[N] do begin
+
+
+ //Golden + Freestyle Note Patch
+ case Lines.Line[C].Note[N].NoteType of
+ ntFreestyle: NoteState := 'F ';
+ ntNormal: NoteState := ': ';
+ ntGolden: NoteState := '* ';
+ end; // case
+ S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Length) + ' ' + IntToStr(Tone) + ' ' + Text;
+
+
+ Writeln(SongFile, S);
+ end; // with
+ end; // N
+
+ if C < Lines.High then begin // don't write end of last sentence
+ if not Relative then
+ S := '- ' + IntToStr(Lines.Line[C+1].Start)
+ else begin
+ S := '- ' + IntToStr(Lines.Line[C+1].Start - RelativeSubTime) +
+ ' ' + IntToStr(Lines.Line[C+1].Start - RelativeSubTime);
+ RelativeSubTime := Lines.Line[C+1].Start;
+ end;
+ Writeln(SongFile, S);
+ end;
+
+ end; // C
+
+
+ Writeln(SongFile, 'E');
+ CloseFile(SongFile);
+
+ Result := true;
+end;
+
+end.
diff --git a/src/Classes/UGraphic.pas b/src/Classes/UGraphic.pas
new file mode 100644
index 00000000..2432503c
--- /dev/null
+++ b/src/Classes/UGraphic.pas
@@ -0,0 +1,760 @@
+unit UGraphic;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SDL,
+ gl,
+ glext,
+ UTexture,
+ TextGL,
+ ULog,
+ SysUtils,
+ ULyrics,
+ UImage,
+ UMusic,
+ UScreenLoading,
+ UScreenWelcome,
+ UScreenMain,
+ UScreenName,
+ UScreenLevel,
+ UScreenOptions,
+ UScreenOptionsGame,
+ UScreenOptionsGraphics,
+ UScreenOptionsSound,
+ UScreenOptionsLyrics,
+ UScreenOptionsThemes,
+ UScreenOptionsRecord,
+ UScreenOptionsAdvanced,
+ UScreenSong,
+ UScreenSing,
+ UScreenScore,
+ UScreenTop5,
+ UScreenEditSub,
+ UScreenEdit,
+ UScreenEditConvert,
+ UScreenEditHeader,
+ UScreenOpen,
+ UThemes,
+ USkins,
+ UScreenSongMenu,
+ UScreenSongJumpto,
+ {Party Screens}
+ UScreenSingModi,
+ UScreenPartyNewRound,
+ UScreenPartyScore,
+ UScreenPartyOptions,
+ UScreenPartyWin,
+ UScreenPartyPlayer,
+ {Stats Screens}
+ UScreenStatMain,
+ UScreenStatDetail,
+ {CreditsScreen}
+ UScreenCredits,
+ {Popup for errors, etc.}
+ UScreenPopup;
+
+type
+ TRecR = record
+ Top: real;
+ Left: real;
+ Right: real;
+ Bottom: real;
+ end;
+
+var
+ Screen: PSDL_Surface;
+ LoadingThread: PSDL_Thread;
+ Mutex: PSDL_Mutex;
+
+ RenderW: integer;
+ RenderH: integer;
+ ScreenW: integer;
+ ScreenH: integer;
+ Screens: integer;
+ ScreenAct: integer;
+ ScreenX: integer;
+
+ ScreenLoading: TScreenLoading;
+ ScreenWelcome: TScreenWelcome;
+ ScreenMain: TScreenMain;
+ ScreenName: TScreenName;
+ ScreenLevel: TScreenLevel;
+ ScreenSong: TScreenSong;
+ ScreenSing: TScreenSing;
+ ScreenScore: TScreenScore;
+ ScreenTop5: TScreenTop5;
+ ScreenOptions: TScreenOptions;
+ ScreenOptionsGame: TScreenOptionsGame;
+ ScreenOptionsGraphics: TScreenOptionsGraphics;
+ ScreenOptionsSound: TScreenOptionsSound;
+ ScreenOptionsLyrics: TScreenOptionsLyrics;
+ ScreenOptionsThemes: TScreenOptionsThemes;
+ ScreenOptionsRecord: TScreenOptionsRecord;
+ ScreenOptionsAdvanced: TScreenOptionsAdvanced;
+ ScreenEditSub: TScreenEditSub;
+ ScreenEdit: TScreenEdit;
+ ScreenEditConvert: TScreenEditConvert;
+ ScreenEditHeader: TScreenEditHeader;
+ ScreenOpen: TScreenOpen;
+
+ ScreenSongMenu: TScreenSongMenu;
+ ScreenSongJumpto: TScreenSongJumpto;
+
+ //Party Screens
+ ScreenSingModi: TScreenSingModi;
+ ScreenPartyNewRound: TScreenPartyNewRound;
+ ScreenPartyScore: TScreenPartyScore;
+ ScreenPartyWin: TScreenPartyWin;
+ ScreenPartyOptions: TScreenPartyOptions;
+ ScreenPartyPlayer: TScreenPartyPlayer;
+
+ //StatsScreens
+ ScreenStatMain: TScreenStatMain;
+ ScreenStatDetail: TScreenStatDetail;
+
+ //CreditsScreen
+ ScreenCredits: TScreenCredits;
+
+ //popup mod
+ ScreenPopupCheck: TScreenPopupCheck;
+ ScreenPopupError: TScreenPopupError;
+
+ //Notes
+ Tex_Left: array[0..6] of TTexture; //rename to tex_note_left
+ Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid
+ Tex_Right: array[0..6] of TTexture; //rename to tex_note_right
+
+ Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left
+ Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid
+ Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right
+
+ Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left
+ Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid
+ Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right
+
+ Tex_Note_Star: TTexture;
+ Tex_Note_Perfect_Star: TTexture;
+
+
+ Tex_Ball: TTexture;
+ Tex_Lyric_Help_Bar: TTexture;
+ FullScreen: boolean;
+
+ Tex_TimeProgress: TTexture;
+
+ //Sing Bar Mod
+ Tex_SingBar_Back: TTexture;
+ Tex_SingBar_Bar: TTexture;
+ Tex_SingBar_Front: TTexture;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ Tex_SingLineBonusBack: array[0..8] of TTexture;
+ //End PhrasenBonus - Line Bonus Mod
+
+ //ScoreBG Texs
+ Tex_ScoreBG: array [0..5] of TTexture;
+
+ //Score Screen Textures
+ Tex_Score_NoteBarLevel_Dark : array [1..6] of TTexture;
+ Tex_Score_NoteBarRound_Dark : array [1..6] of TTexture;
+
+ Tex_Score_NoteBarLevel_Light : array [1..6] of TTexture;
+ Tex_Score_NoteBarRound_Light : array [1..6] of TTexture;
+
+ Tex_Score_NoteBarLevel_Lightest : array [1..6] of TTexture;
+ Tex_Score_NoteBarRound_Lightest : array [1..6] of TTexture;
+
+ Tex_Score_Ratings : array [0..7] of TTexture;
+
+const
+ Skin_BGColorR = 1;
+ Skin_BGColorG = 1;
+ Skin_BGColorB = 1;
+
+ Skin_SpectrumR = 0;
+ Skin_SpectrumG = 0;
+ Skin_SpectrumB = 0;
+
+ Skin_Spectograph1R = 0.6;
+ Skin_Spectograph1G = 0.8;
+ Skin_Spectograph1B = 1;
+
+ Skin_Spectograph2R = 0;
+ Skin_Spectograph2G = 0;
+ Skin_Spectograph2B = 0.2;
+
+ Skin_SzczytR = 0.8;
+ Skin_SzczytG = 0;
+ Skin_SzczytB = 0;
+
+ Skin_SzczytLimitR = 0;
+ Skin_SzczytLimitG = 0.8;
+ Skin_SzczytLimitB = 0;
+
+ Skin_FontR = 0;
+ Skin_FontG = 0;
+ Skin_FontB = 0;
+
+ Skin_FontHighlightR = 0.3; // 0.3
+ Skin_FontHighlightG = 0.3; // 0.3
+ Skin_FontHighlightB = 1; // 1
+
+ Skin_TimeR = 0.25; //0,0,0
+ Skin_TimeG = 0.25;
+ Skin_TimeB = 0.25;
+
+ Skin_OscR = 0;
+ Skin_OscG = 0;
+ Skin_OscB = 0;
+
+ Skin_LyricsT = 494; // 500 / 510 / 400
+ Skin_SpectrumT = 470;
+ Skin_SpectrumBot = 570;
+ Skin_SpectrumH = 100;
+
+ Skin_P1_LinesR = 0.5; // 0.6 0.6 1
+ Skin_P1_LinesG = 0.5;
+ Skin_P1_LinesB = 0.5;
+
+ Skin_P2_LinesR = 0.5; // 1 0.6 0.6
+ Skin_P2_LinesG = 0.5;
+ Skin_P2_LinesB = 0.5;
+
+ Skin_P1_NotesB = 250;
+ Skin_P2_NotesB = 430; // 430 / 300
+
+ Skin_P1_ScoreT = 50;
+ Skin_P1_ScoreL = 20;
+
+ Skin_P2_ScoreT = 50;
+ Skin_P2_ScoreL = 640;
+
+procedure Initialize3D (Title: string);
+procedure Reinitialize3D;
+procedure SwapBuffers;
+
+procedure LoadTextures;
+procedure InitializeScreen;
+procedure LoadLoadingScreen;
+procedure LoadScreens;
+procedure UnLoadScreens;
+
+function LoadingThreadFunction: integer;
+
+
+implementation
+
+uses
+ UMain,
+ UIni,
+ UDisplay,
+ UCommandLine,
+ Classes;
+
+procedure LoadFontTextures;
+begin
+ Log.LogStatus('Building Fonts', 'LoadTextures');
+ BuildFont;
+end;
+
+procedure LoadTextures;
+
+
+var
+ P: integer;
+ R, G, B: real;
+ Col: integer;
+begin
+ // zaladowanie tekstur
+ Log.LogStatus('Loading Textures', 'LoadTextures');
+
+ Tex_Left[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
+ Tex_Mid[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_PLAIN, 0); //brauch man die noch?
+ Tex_Right[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
+
+ Log.LogStatus('Loading Textures - A', 'LoadTextures');
+
+ // P1-6
+ // TODO... do it once for each player... this is a bit crappy !!
+ // can we make it any better !?
+ for P := 1 to 6 do
+ begin
+ LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+
+ Tex_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_COLORIZED, Col);
+
+ Tex_plain_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainLeft'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_plain_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainMid'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_plain_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('NotePlainRight'), TEXTURE_TYPE_COLORIZED, Col);
+
+ Tex_BG_Left[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGLeft'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_BG_Mid[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGMid'), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_BG_Right[P] := Texture.LoadTexture(Skin.GetTextureFileName('NoteBGRight'), TEXTURE_TYPE_COLORIZED, Col);
+ end;
+
+ Log.LogStatus('Loading Textures - B', 'LoadTextures');
+
+ Tex_Note_Perfect_Star := Texture.LoadTexture(Skin.GetTextureFileName('NotePerfectStar'), TEXTURE_TYPE_TRANSPARENT, 0);
+ Tex_Note_Star := Texture.LoadTexture(Skin.GetTextureFileName('NoteStar') , TEXTURE_TYPE_TRANSPARENT, $FFFFFF);
+ Tex_Ball := Texture.LoadTexture(Skin.GetTextureFileName('Ball'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ Tex_Lyric_Help_Bar := Texture.LoadTexture(Skin.GetTextureFileName('LyricHelpBar'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+
+
+ //TimeBar mod
+ Tex_TimeProgress := Texture.LoadTexture(Skin.GetTextureFileName('TimeBar'));
+ //eoa TimeBar mod
+
+ //SingBar Mod
+ Tex_SingBar_Back := Texture.LoadTexture(Skin.GetTextureFileName('SingBarBack'), TEXTURE_TYPE_PLAIN, 0);
+ Tex_SingBar_Bar := Texture.LoadTexture(Skin.GetTextureFileName('SingBarBar'), TEXTURE_TYPE_PLAIN, 0);
+ Tex_SingBar_Front := Texture.LoadTexture(Skin.GetTextureFileName('SingBarFront'), TEXTURE_TYPE_PLAIN, 0);
+ //end Singbar Mod
+
+ Log.LogStatus('Loading Textures - C', 'LoadTextures');
+
+ //Line Bonus PopUp
+ for P := 0 to 8 do
+ begin
+ Case P of
+ 0: begin
+ R := 1;
+ G := 0;
+ B := 0;
+ end;
+ 1..3: begin
+ R := 1;
+ G := (P * 0.25);
+ B := 0;
+ end;
+ 4: begin
+ R := 1;
+ G := 1;
+ B := 0;
+ end;
+ 5..7: begin
+ R := 1-((P-4)*0.25);
+ G := 1;
+ B := 0;
+ end;
+ 8: begin
+ R := 0;
+ G := 1;
+ B := 0;
+ end;
+ End;
+
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), TEXTURE_TYPE_COLORIZED, Col);
+ end;
+
+//## backgrounds for the scores ##
+ for P := 0 to 5 do begin
+ LoadColor(R, G, B, 'P' + IntToStr(P+1) + 'Light');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_ScoreBG[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreBG')), TEXTURE_TYPE_COLORIZED, Col);
+ end;
+
+
+ Log.LogStatus('Loading Textures - D', 'LoadTextures');
+
+// ######################
+// Score screen textures
+// ######################
+
+//## the bars that visualize the score ##
+ for P := 1 to 6 do begin
+//NoteBar ScoreBar
+ LoadColor(R, G, B, 'P' + IntToStr(P) + 'Dark');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_Score_NoteBarLevel_Dark[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Dark')), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_Score_NoteBarRound_Dark[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Dark_Round')), TEXTURE_TYPE_COLORIZED, Col);
+//LineBonus ScoreBar
+ LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_Score_NoteBarLevel_Light[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Light')), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_Score_NoteBarRound_Light[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Light_Round')), TEXTURE_TYPE_COLORIZED, Col);
+//GoldenNotes ScoreBar
+ LoadColor(R, G, B, 'P' + IntToStr(P) + 'Lightest');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_Score_NoteBarLevel_Lightest[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Lightest')), TEXTURE_TYPE_COLORIZED, Col);
+ Tex_Score_NoteBarRound_Lightest[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreLevel_Lightest_Round')), TEXTURE_TYPE_COLORIZED, Col);
+ end;
+
+//## rating pictures that show a picture according to your rate ##
+ for P := 0 to 7 do begin
+ Tex_Score_Ratings[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Rating_'+IntToStr(P))), TEXTURE_TYPE_TRANSPARENT, 0);
+ end;
+
+ Log.LogStatus('Loading Textures - Done', 'LoadTextures');
+end;
+
+(*
+ * Load OpenGL extensions. Must be called after SDL_SetVideoMode() and each
+ * time the pixel-format or render-context (RC) changes.
+ *)
+procedure LoadOpenGLExtensions;
+begin
+ // Load OpenGL 1.2 extensions for OpenGL 1.2 compatibility
+ if (not Load_GL_version_1_2()) then
+ begin
+ Log.LogCritical('Failed loading OpenGL 1.2', 'UGraphic.Initialize3D');
+ end;
+
+ // Other extensions e.g. OpenGL 1.3-2.0 or Framebuffer-Object might be loaded here
+ // ...
+ //Load_GL_EXT_framebuffer_object();
+end;
+
+procedure Initialize3D (Title: string);
+var
+ Icon: PSDL_Surface;
+begin
+ Log.LogStatus('SDL_Init', 'UGraphic.Initialize3D');
+ if ( SDL_InitSubSystem(SDL_INIT_VIDEO) = -1 ) then
+ begin
+ Log.LogError('SDL_Init Failed', 'UGraphic.Initialize3D');
+ exit;
+ end;
+
+ // load icon image (must be 32x32 for win32)
+ Icon := LoadImage('WINDOWICON');
+ if (Icon <> nil) then
+ SDL_WM_SetIcon(Icon, 0);
+
+ SDL_WM_SetCaption(PChar(Title), nil);
+
+ //Log.BenchmarkStart(2);
+
+ InitializeScreen;
+
+ //Log.BenchmarkEnd(2);
+ //Log.LogBenchmark('--> Setting Screen', 2);
+
+ //Log.BenchmarkStart(2);
+ Texture := TTextureUnit.Create;
+ // FIXME: this does not seem to be correct as Limit is the max. of either
+ // width or height.
+ Texture.Limit := 1024*1024;
+
+ //LoadTextures;
+ //Log.BenchmarkEnd(2);
+ //Log.LogBenchmark('--> Loading Textures', 2);
+
+ {
+ Log.BenchmarkStart(2);
+ Lyric:= TLyric.Create;
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Loading Fonts', 2);
+ }
+
+ // Note: do not initialize video modules earlier. They might depend on some
+ // SDL video functions or OpenGL extensions initialized in InitializeScreen()
+ InitializeVideo();
+
+ //Log.BenchmarkStart(2);
+
+ Log.LogStatus('TDisplay.Create', 'UGraphic.Initialize3D');
+ Display := TDisplay.Create;
+
+ //Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2);
+
+ //Log.LogStatus('Loading Screens', 'Initialize3D');
+ //Log.BenchmarkStart(3);
+
+ Log.LogStatus('Loading Font Textures', 'UGraphic.Initialize3D');
+ LoadFontTextures();
+
+ // Show the Loading Screen -------------
+ Log.LogStatus('Loading Loading Screen', 'UGraphic.Initialize3D');
+ LoadLoadingScreen;
+
+
+ Log.LogStatus(' Loading Textures', 'UGraphic.Initialize3D');
+ LoadTextures; // jb
+
+
+
+ // now that we have something to display while loading,
+ // start thread that loads the rest of ultrastar
+ //Mutex := SDL_CreateMutex;
+ //SDL_UnLockMutex(Mutex);
+
+ // does not work this way because the loading thread tries to access opengl.
+ // See comment below
+ //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
+
+ // this would be run in the loadingthread
+ Log.LogStatus(' Loading Screens', 'UGraphic.Initialize3D');
+ LoadScreens;
+
+
+ // TODO:
+ // here should be a loop which
+ // * draws the loading screen (form time to time)
+ // * controlls the "process of the loading screen
+ // * checks if the loadingthread has loaded textures (check mutex) and
+ // * load the textures into opengl
+ // * tells the loadingthread, that the memory for the texture can be reused
+ // to load the netx texture (over another mutex)
+ // * runs as long as the loadingthread tells, that everything is loaded and ready (using a third mutex)
+ //
+ // therefor loadtexture have to be changed, that it, instat of caling some opengl functions
+ // for itself, it should change mutex
+ // the mainthread have to know somehow what opengl function have to be called with which parameters like
+ // texturetype, textureobjekt, textur-buffer-adress, ...
+
+ // wait for loading thread to finish
+ // currently does not work this way
+ // SDL_WaitThread(LoadingThread, I);
+ // SDL_DestroyMutex(Mutex);
+
+ Display.CurrentScreen^.FadeTo( @ScreenMain );
+
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Loading Screens', 2);
+
+ Log.LogStatus('Finish', 'Initialize3D');
+end;
+
+procedure SwapBuffers;
+begin
+ SDL_GL_SwapBuffers;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity;
+ glOrtho(0, RenderW, RenderH, 0, -1, 100);
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure Reinitialize3D;
+begin
+ InitializeScreen;
+end;
+
+procedure InitializeScreen;
+var
+ S: string;
+ I: integer;
+ W, H: integer;
+ Depth: Integer;
+begin
+ if (Params.Screens <> -1) then
+ Screens := Params.Screens + 1
+ else
+ Screens := Ini.Screens + 1;
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); // Z-Buffer depth
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ // VSYNC works for windows only at the moment. SDL_GL_SWAP_CONTROL under
+ // linux uses GLX_MESA_swap_control which is not supported by nvidea cards.
+ // Maybe use glXSwapIntervalSGI(1) from the GLX_SGI_swap_control extension instead.
+ //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); // VSYNC (currently Windows only)
+
+ // If there is a resolution in Parameters, use it, else use the Ini value
+ I := Params.Resolution;
+ if (I <> -1) then
+ S := IResolution[I]
+ else
+ S := IResolution[Ini.Resolution];
+
+ I := Pos('x', S);
+ W := StrToInt(Copy(S, 1, I-1)) * Screens;
+ H := StrToInt(Copy(S, I+1, 1000));
+
+ if (Params.Depth <> -1) then
+ Depth := Params.Depth
+ else
+ Depth := Ini.Depth;
+
+ Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
+ //SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+ if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
+ begin
+ Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Windowed');
+ screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE)
+ end
+ else
+ begin
+ Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Full Screen');
+ screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN );
+ SDL_ShowCursor(0);
+ end;
+
+ if (screen = nil) then
+ begin
+ Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D');
+ exit;
+ end;
+
+ LoadOpenGLExtensions();
+
+ // define virtual (Render) and real (Screen) screen size
+ RenderW := 800;
+ RenderH := 600;
+ ScreenW := W;
+ ScreenH := H;
+
+ // clear screen once window is being shown
+ // Note: SwapBuffers uses RenderW/H, so they must be defined before
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ SwapBuffers;
+end;
+
+procedure LoadLoadingScreen;
+begin
+ ScreenLoading := TScreenLoading.Create;
+ ScreenLoading.onShow;
+
+ Display.CurrentScreen := @ScreenLoading;
+
+ swapbuffers;
+
+ ScreenLoading.Draw;
+ Display.Draw;
+
+ SwapBuffers;
+end;
+
+procedure LoadScreens;
+begin
+{ ScreenLoading := TScreenLoading.Create;
+ ScreenLoading.onShow;
+ Display.CurrentScreen := @ScreenLoading;
+ ScreenLoading.Draw;
+ Display.Draw;
+ SwapBuffers;
+}
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
+{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
+ ScreenMain := TScreenMain.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3);
+ ScreenName := TScreenName.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3);
+ ScreenLevel := TScreenLevel.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3);
+ ScreenSong := TScreenSong.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3);
+ ScreenSongMenu := TScreenSongMenu.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3);
+ ScreenSing := TScreenSing.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3);
+ ScreenScore := TScreenScore.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3);
+ ScreenTop5 := TScreenTop5.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3);
+ ScreenOptions := TScreenOptions.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3);
+ ScreenOptionsGame := TScreenOptionsGame.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3);
+ ScreenOptionsGraphics := TScreenOptionsGraphics.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3);
+ ScreenOptionsSound := TScreenOptionsSound.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3);
+ ScreenOptionsLyrics := TScreenOptionsLyrics.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3);
+ ScreenOptionsThemes := TScreenOptionsThemes.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3);
+ ScreenOptionsRecord := TScreenOptionsRecord.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3);
+ ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3);
+ ScreenEditSub := TScreenEditSub.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3);
+ ScreenEdit := TScreenEdit.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3);
+ ScreenEditConvert := TScreenEditConvert.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3);
+// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG);
+// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3);
+ ScreenOpen := TScreenOpen.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3);
+ ScreenSingModi := TScreenSingModi.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3);
+ ScreenSongMenu := TScreenSongMenu.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3);
+ ScreenSongJumpto := TScreenSongJumpto.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3);
+ ScreenPopupCheck := TScreenPopupCheck.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3);
+ ScreenPopupError := TScreenPopupError.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3);
+ ScreenPartyNewRound := TScreenPartyNewRound.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3);
+ ScreenPartyScore := TScreenPartyScore.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3);
+ ScreenPartyWin := TScreenPartyWin.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3);
+ ScreenPartyOptions := TScreenPartyOptions.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
+ ScreenPartyPlayer := TScreenPartyPlayer.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
+ ScreenStatMain := TScreenStatMain.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
+ ScreenStatDetail := TScreenStatDetail.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
+ ScreenCredits := TScreenCredits.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3);
+
+end;
+
+function LoadingThreadFunction: integer;
+begin
+ LoadScreens;
+ Result:= 1;
+end;
+
+procedure UnLoadScreens;
+begin
+ freeandnil( ScreenMain );
+ freeandnil( ScreenName );
+ freeandnil( ScreenLevel);
+ freeandnil( ScreenSong );
+ freeandnil( ScreenSongMenu );
+ freeandnil( ScreenSing );
+ freeandnil( ScreenScore);
+ freeandnil( ScreenTop5 );
+ freeandnil( ScreenOptions );
+ freeandnil( ScreenOptionsGame );
+ freeandnil( ScreenOptionsGraphics );
+ freeandnil( ScreenOptionsSound );
+ freeandnil( ScreenOptionsLyrics );
+// freeandnil( ScreenOptionsThemes );
+ freeandnil( ScreenOptionsRecord );
+ freeandnil( ScreenOptionsAdvanced );
+ freeandnil( ScreenEditSub );
+ freeandnil( ScreenEdit );
+ freeandnil( ScreenEditConvert );
+ freeandnil( ScreenOpen );
+ freeandnil( ScreenSingModi );
+ freeandnil( ScreenSongMenu );
+ freeandnil( ScreenSongJumpto);
+ freeandnil( ScreenPopupCheck );
+ freeandnil( ScreenPopupError );
+ freeandnil( ScreenPartyNewRound );
+ freeandnil( ScreenPartyScore );
+ freeandnil( ScreenPartyWin );
+ freeandnil( ScreenPartyOptions );
+ freeandnil( ScreenPartyPlayer );
+ freeandnil( ScreenStatMain );
+ freeandnil( ScreenStatDetail );
+end;
+
+end.
diff --git a/src/Classes/UGraphicClasses.pas b/src/Classes/UGraphicClasses.pas
new file mode 100644
index 00000000..b7174991
--- /dev/null
+++ b/src/Classes/UGraphicClasses.pas
@@ -0,0 +1,673 @@
+// notes:
+unit UGraphicClasses;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses UTexture,SDL;
+
+const DelayBetweenFrames : Cardinal = 60;
+type
+
+ TParticleType=(GoldenNote, PerfectNote, NoteHitTwinkle, PerfectLineTwinkle, ColoredStar, Flare);
+
+ TColour3f = Record
+ r, g, b: Real;
+ end;
+
+ TParticle = Class
+ X, Y : Real; //Position
+ Screen : Integer;
+ W, H : Cardinal; //dimensions of particle
+ Col : array of TColour3f; // Colour(s) of particle
+ Scale : array of Real; // Scaling factors of particle layers
+ Frame : Byte; //act. Frame
+ Tex : Cardinal; //Tex num from Textur Manager
+ Live : Byte; //How many Cycles before Kill
+ RecIndex : Integer; //To which rectangle this particle belongs (only GoldenNote)
+ StarType : TParticleType; // GoldenNote | PerfectNote | NoteHitTwinkle | PerfectLineTwinkle
+ Alpha : Real; // used for fading...
+ mX, mY : Real; // movement-vector for PerfectLineTwinkle
+ SizeMod : Real; // experimental size modifier
+ SurviveSentenceChange : Boolean;
+
+ Constructor Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
+ Destructor Destroy(); override;
+ procedure Draw;
+ procedure LiveOn;
+ end;
+
+ RectanglePositions = Record
+ xTop, yTop, xBottom, yBottom : Real;
+ TotalStarCount : Integer;
+ CurrentStarCount : Integer;
+ Screen : Integer;
+ end;
+
+ PerfectNotePositions = Record
+ xPos, yPos : Real;
+ Screen : Integer;
+ end;
+
+ TEffectManager = Class
+ Particle : array of TParticle;
+ LastTime : Cardinal;
+ RecArray : Array of RectanglePositions;
+ TwinkleArray : Array[0..5] of Real; // store x-position of last twinkle for every player
+ PerfNoteArray : Array of PerfectNotePositions;
+
+ FlareTex: TTexture;
+
+ constructor Create;
+ destructor Destroy; override;
+ procedure Draw;
+ function Spawn(X, Y: Real;
+ Screen: Integer;
+ Live: Byte;
+ StartFrame: Integer;
+ RecArrayIndex: Integer; // this is only used with GoldenNotes
+ StarType: TParticleType;
+ Player: Cardinal // for PerfectLineTwinkle
+ ): Cardinal;
+ procedure SpawnRec();
+ procedure Kill(index: Cardinal);
+ procedure KillAll();
+ procedure SentenceChange();
+ procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
+ procedure SavePerfectNotePos(Xtop, Ytop: Real);
+ procedure GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
+ procedure SpawnPerfectLineTwinkle();
+ end;
+
+var GoldenRec : TEffectManager;
+
+implementation
+
+uses sysutils,
+ gl,
+ UIni,
+ UMain,
+ UThemes,
+ USkins,
+ UGraphic,
+ UDrawTexture,
+ UCommon,
+ math;
+
+//TParticle
+Constructor TParticle.Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
+begin
+ inherited Create;
+ // in this constructor we set all initial values for our particle
+ X := cX;
+ Y := cY;
+ Screen := cScreen;
+ Live := cLive;
+ Frame:= cFrame;
+ RecIndex := cRecArrayIndex;
+ StarType := cStarType;
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ SetLength(Scale,1);
+ Scale[0] := 1;
+ SurviveSentenceChange := False;
+ SizeMod := 1;
+ case cStarType of
+ GoldenNote:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := 20;
+ H := 20;
+ SetLength(Scale,4);
+ Scale[1]:=0.8;
+ Scale[2]:=0.4;
+ Scale[3]:=0.3;
+ SetLength(Col,4);
+ Col[0].r := 1;
+ Col[0].g := 0.7;
+ Col[0].b := 0.1;
+
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+
+ Col[2].r := 1;
+ Col[2].g := 1;
+ Col[2].b := 1;
+
+ Col[3].r := 1;
+ Col[3].g := 1;
+ Col[3].b := 1;
+ end;
+ PerfectNote:
+ begin
+ Tex := Tex_Note_Perfect_Star.TexNum;
+ W := 30;
+ H := 30;
+ SetLength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := 0.95;
+ end;
+ NoteHitTwinkle:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ Alpha := (Live/16); // linear fade-out
+ W := 15;
+ H := 15;
+ Setlength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := RandomRange(10*Live,100)/90; //0.9;
+ end;
+ PerfectLineTwinkle:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := RandomRange(10,20);
+ H := W;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ SurviveSentenceChange:=True;
+ // assign colours according to player given
+ SetLength(Scale,3);
+ Scale[1]:=0.3;
+ Scale[2]:=0.2;
+ SetLength(Col,3);
+ case Player of
+ 0: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
+ 1: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P2Light');
+ 2: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P3Light');
+ 3: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P4Light');
+ 4: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P5Light');
+ 5: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P6Light');
+ else LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
+ end;
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+ Col[2].r:=Col[0].r+0.5;
+ Col[2].g:=Col[0].g+0.5;
+ Col[2].b:=Col[0].b+0.5;
+ mX := RandomRange(-5,5);
+ mY := RandomRange(-5,5);
+ end;
+ ColoredStar:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := RandomRange(10,20);
+ H := W;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ SurviveSentenceChange:=True;
+ // assign colours according to player given
+ SetLength(Scale,1);
+ SetLength(Col,1);
+ Col[0].b := (Player and $ff)/255;
+ Col[0].g := ((Player shr 8) and $ff)/255;
+ Col[0].r := ((Player shr 16) and $ff)/255;
+ mX := 0;
+ mY := 0;
+ end;
+ Flare:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := 7;
+ H := 7;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ mX := RandomRange(-5,5);
+ mY := RandomRange(-5,5);
+ SetLength(Scale,4);
+ Scale[1]:=0.8;
+ Scale[2]:=0.4;
+ Scale[3]:=0.3;
+ SetLength(Col,4);
+ Col[0].r := 1;
+ Col[0].g := 0.7;
+ Col[0].b := 0.1;
+
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+
+ Col[2].r := 1;
+ Col[2].g := 1;
+ Col[2].b := 1;
+
+ Col[3].r := 1;
+ Col[3].g := 1;
+ Col[3].b := 1;
+
+ end;
+ else // just some random default values
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ Alpha := 1;
+ W := 20;
+ H := 20;
+ SetLength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := 1;
+ end;
+ end;
+end;
+
+Destructor TParticle.Destroy();
+begin
+ SetLength(Scale,0);
+ SetLength(Col,0);
+ inherited;
+end;
+
+procedure TParticle.LiveOn;
+begin
+ //Live = 0 => Live forever ?? but if this is 0 they would be killed in the Manager at Draw
+ if (Live > 0) then
+ Dec(Live);
+
+ // animate frames
+ Frame := ( Frame + 1 ) mod 16;
+
+ // make our particles do funny stuff (besides being animated)
+ // changes of any particle-values throughout its life are done here
+ case StarType of
+ GoldenNote:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ PerfectNote:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ NoteHitTwinkle:
+ begin
+ Alpha := (Live/10); // linear fade-out
+ end;
+ PerfectLineTwinkle:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ // move around
+ X := X + mX;
+ Y := Y + mY;
+ end;
+ ColoredStar:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ Flare:
+ begin
+ Alpha := (-cos((Frame+1)/16*1.7*pi+0.3*pi)+1); // neat fade-in-and-out
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ // move around
+ X := X + mX;
+ Y := Y + mY;
+ mY:=mY+1.8;
+// mX:=mX/2;
+ end;
+ end;
+end;
+
+procedure TParticle.Draw;
+var L: Cardinal;
+begin
+ if ScreenAct = Screen then
+ // this draws (multiple) texture(s) of our particle
+ for L:=0 to High(Col) do
+ begin
+ glColor4f(Col[L].r, Col[L].g, Col[L].b, Alpha);
+
+ glBindTexture(GL_TEXTURE_2D, Tex);
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ begin
+ glBegin(GL_QUADS);
+ glTexCoord2f((1/16) * Frame, 0); glVertex2f(X-W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame, 1); glVertex2f(X+W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
+ glEnd;
+ end;
+ end;
+ glcolor4f(1,1,1,1);
+end;
+// end of TParticle
+
+// TEffectManager
+
+constructor TEffectManager.Create;
+var c: Cardinal;
+begin
+ inherited;
+ LastTime := SDL_GetTicks();
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0;
+ end;
+end;
+
+destructor TEffectManager.Destroy;
+begin
+ Killall;
+ inherited;
+end;
+
+
+procedure TEffectManager.Draw;
+var
+ I: Integer;
+ CurrentTime: Cardinal;
+//const
+// DelayBetweenFrames : Cardinal = 100;
+begin
+
+ CurrentTime := SDL_GetTicks();
+ //Manage particle life
+ if (CurrentTime - LastTime) > DelayBetweenFrames then
+ begin
+ LastTime := CurrentTime;
+ for I := 0 to high(Particle) do
+ Particle[I].LiveOn;
+ end;
+
+ I := 0;
+ //Kill dead particles
+ while (I <= High(Particle)) do
+ begin
+ if (Particle[I].Live <= 0) then
+ begin
+ kill(I);
+ end
+ else
+ begin
+ inc(I);
+ end;
+ end;
+
+ //Draw
+ for I := 0 to high(Particle) do
+ begin
+ Particle[I].Draw;
+ end;
+end;
+
+// this method creates just one particle
+function TEffectManager.Spawn(X, Y: Real; Screen: Integer; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : TParticleType; Player: Cardinal): Cardinal;
+begin
+ Result := Length(Particle);
+ SetLength(Particle, (Result + 1));
+ Particle[Result] := TParticle.Create(X, Y, Screen, Live, StartFrame, RecArrayIndex, StarType, Player);
+end;
+
+// manage Sparkling of GoldenNote Bars
+procedure TEffectManager.SpawnRec();
+Var
+ Xkatze, Ykatze : Real;
+ RandomFrame : Integer;
+ P : Integer; // P as seen on TV as Positionman
+begin
+//Spawn a random amount of stars within the given coordinates
+//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame
+for P:= 0 to high(RecArray) do
+ begin
+ while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do
+ begin
+ Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom));
+ Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom));
+ RandomFrame := RandomRange(0,14);
+ // Spawn a GoldenNote Particle
+ Spawn(Xkatze, Ykatze, RecArray[P].Screen, 16 - RandomFrame, RandomFrame, P, GoldenNote, 0);
+ inc(RecArray[P].CurrentStarCount);
+ end;
+ end;
+ draw;
+end;
+
+// kill one particle (with given index in our particle array)
+procedure TEffectManager.Kill(Index: Cardinal);
+var
+ LastParticleIndex : Integer;
+begin
+// delete particle indexed by Index,
+// overwrite it's place in our particle-array with the particle stored at the last array index,
+// shorten array
+ LastParticleIndex := high(Particle);
+ if not(LastParticleIndex = -1) then // is there still a particle to delete?
+ begin
+ if not(Particle[Index].RecIndex = -1) then // if it is a GoldenNote particle...
+ dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); // take care of its associated GoldenRec
+ // now get rid of that particle
+ Particle[Index].Destroy;
+ Particle[Index] := Particle[LastParticleIndex];
+ SetLength(Particle, LastParticleIndex);
+ end;
+end;
+
+// clean up all particles and management structures
+procedure TEffectManager.KillAll();
+var c: Cardinal;
+begin
+//It's the kill all kennies rotuine
+ while Length(Particle) > 0 do // kill all existing particles
+ Kill(0);
+ SetLength(RecArray,0); // remove GoldenRec positions
+ SetLength(PerfNoteArray,0); // remove PerfectNote positions
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0; // reset GoldenNoteHit memory
+ end;
+end;
+
+procedure TEffectManager.SentenceChange();
+var c: Cardinal;
+begin
+ c:=0;
+ while c <= High(Particle) do
+ begin
+ if Particle[c].SurviveSentenceChange then
+ inc(c)
+ else
+ Kill(c);
+ end;
+ SetLength(RecArray,0); // remove GoldenRec positions
+ SetLength(PerfNoteArray,0); // remove PerfectNote positions
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0; // reset GoldenNoteHit memory
+ end;
+end;
+
+procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
+//Twinkle stars while golden note hit
+// this is called from UDraw.pas, SingDrawPlayerCzesc
+var
+ C, P, XKatze, YKatze, LKatze: Integer;
+ H: Real;
+begin
+ // make sure we spawn only one time at one position
+ if (TwinkleArray[Player] < Right) then
+ For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle?
+ begin
+ H := (Top+Bottom)/2; // helper...
+ with RecArray[P] do
+ if ((xBottom >= Right) and (xTop <= Right) and
+ (yTop <= H) and (yBottom >= H))
+ and (Screen = ScreenAct) then
+ begin
+ TwinkleArray[Player] := Right; // remember twinkle position for this player
+ for C := 1 to 10 do
+ begin
+ Ykatze := RandomRange(ceil(Top) , ceil(Bottom));
+ XKatze := RandomRange(-7,3);
+ LKatze := RandomRange(7,13);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Top)-6 , ceil(Top));
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(4,7);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Bottom), ceil(Bottom)+6);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(4,7);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Top)-10 , ceil(Top)-6);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(1,4);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Bottom)+6 , ceil(Bottom)+10);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(1,4);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+
+ exit; // found a matching GoldenRec, did spawning stuff... done
+ end;
+ end;
+end;
+
+procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
+var
+ P : Integer; // P like used in Positions
+ NewIndex : Integer;
+begin
+ For P := 0 to high(RecArray) do // Do we already have that "new" position?
+ begin
+ if (ceil(RecArray[P].xTop) = ceil(Xtop)) and
+ (ceil(RecArray[P].yTop) = ceil(Ytop)) and
+ (ScreenAct = RecArray[p].Screen) then
+ exit; // it's already in the array, so we don't have to create a new one
+ end;
+
+ // we got a new position, add the new positions to our array
+ NewIndex := Length(RecArray);
+ SetLength(RecArray, NewIndex + 1);
+ RecArray[NewIndex].xTop := Xtop;
+ RecArray[NewIndex].yTop := Ytop;
+ RecArray[NewIndex].xBottom := Xbottom;
+ RecArray[NewIndex].yBottom := Ybottom;
+ RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3;
+ RecArray[NewIndex].CurrentStarCount := 0;
+ RecArray[NewIndex].Screen := ScreenAct;
+end;
+
+procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real);
+var
+ P : Integer; // P like used in Positions
+ NewIndex : Integer;
+ RandomFrame : Integer;
+ Xkatze, Ykatze : Integer;
+begin
+ For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position?
+ begin
+ with PerfNoteArray[P] do
+ if (ceil(xPos) = ceil(Xtop)) and (ceil(yPos) = ceil(Ytop)) and
+ (Screen = ScreenAct) then
+ exit; // it's already in the array, so we don't have to create a new one
+ end; //for
+
+ // we got a new position, add the new positions to our array
+ NewIndex := Length(PerfNoteArray);
+ SetLength(PerfNoteArray, NewIndex + 1);
+ PerfNoteArray[NewIndex].xPos := Xtop;
+ PerfNoteArray[NewIndex].yPos := Ytop;
+ PerfNoteArray[NewIndex].Screen := ScreenAct;
+
+ for P:= 0 to 2 do
+ begin
+ Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10);
+ Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10);
+ RandomFrame := RandomRange(0,14);
+ Spawn(Xkatze, Ykatze, ScreenAct, 16 - RandomFrame, RandomFrame, -1, PerfectNote, 0);
+ end; //for
+
+end;
+
+procedure TEffectManager.SpawnPerfectLineTwinkle();
+var
+ P,I,Life: Cardinal;
+ Left, Right, Top, Bottom: Cardinal;
+ cScreen: Integer;
+begin
+// calculation of coordinates done with hardcoded values like in UDraw.pas
+// might need to be adjusted if drawing of SingScreen is modified
+// coordinates may still be a bit weird and need adjustment
+ if Ini.SingWindow = 0 then begin
+ Left := 130;
+ end else begin
+ Left := 30;
+ end;
+ Right := 770;
+ // spawn effect for every player with a perfect line
+ for P:=0 to PlayersPlay-1 do
+ if Player[P].LastSentencePerfect then
+ begin
+ // calculate area where notes of this player are drawn
+ case PlayersPlay of
+ 1: begin
+ Bottom:=Skin_P2_NotesB+10;
+ Top:=Bottom-105;
+ cScreen:=1;
+ end;
+ 2,4: begin
+ case P of
+ 0,2: begin
+ Bottom:=Skin_P1_NotesB+10;
+ Top:=Bottom-105;
+ end;
+ else begin
+ Bottom:=Skin_P2_NotesB+10;
+ Top:=Bottom-105;
+ end;
+ end;
+ case P of
+ 0,1: cScreen:=1;
+ else cScreen:=2;
+ end;
+ end;
+ 3,6: begin
+ case P of
+ 0,3: begin
+ Top:=130;
+ Bottom:=Top+85;
+ end;
+ 1,4: begin
+ Top:=255;
+ Bottom:=Top+85;
+ end;
+ 2,5: begin
+ Top:=380;
+ Bottom:=Top+85;
+ end;
+ end;
+ case P of
+ 0,1,2: cScreen:=1;
+ else cScreen:=2;
+ end;
+ end;
+ end;
+ // spawn Sparkling Stars inside calculated coordinates
+ for I:= 0 to 80 do
+ begin
+ Life:=RandomRange(8,16);
+ Spawn(RandomRange(Left,Right), RandomRange(Top,Bottom), cScreen, Life, 16-Life, -1, PerfectLineTwinkle, P);
+ end;
+ end;
+end;
+
+end.
+
diff --git a/src/Classes/UHooks.pas b/src/Classes/UHooks.pas
new file mode 100644
index 00000000..f0ba3276
--- /dev/null
+++ b/src/Classes/UHooks.pas
@@ -0,0 +1,434 @@
+unit UHooks;
+
+{*********************
+ THookManager
+ Class for saving, managing and calling of Hooks.
+ Saves all hookable events and their subscribers
+*********************}
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses uPluginDefs,
+ SysUtils;
+
+type
+ //Record that saves info from Subscriber
+ PSubscriberInfo = ^TSubscriberInfo;
+ TSubscriberInfo = record
+ Self: THandle; //ID of this Subscription (First Word: ID of Subscription; 2nd Word: ID of Hook)
+ Next: PSubscriberInfo; //Pointer to next Item in HookChain
+
+ Owner: Integer; //For Error Handling and Plugin Unloading.
+
+ //Here is s/t tricky
+ //To avoid writing of Wrapping Functions to Hook an Event with a Class
+ //We save a Normal Proc or a Method of a Class
+ Case isClass: boolean of
+ False: (Proc: TUS_Hook); //Proc that will be called on Event
+ True: (ProcOfClass: TUS_Hook_of_Object);
+ end;
+
+ TEventInfo = record
+ Name: String[60]; //Name of Event
+ FirstSubscriber: PSubscriberInfo; //First subscriber in chain
+ LastSubscriber: PSubscriberInfo; //Last " (for easier subscriber adding
+ end;
+
+ THookManager = class
+ private
+ Events: array of TEventInfo;
+ SpaceinEvents: Word; //Number of empty Items in Events Array. (e.g. Deleted Items)
+
+ Procedure FreeSubscriber(const EventIndex: Word; const Last, Cur: PSubscriberInfo);
+ public
+ constructor Create(const SpacetoAllocate: Word);
+
+ Function AddEvent (const EventName: PChar): THandle;
+ Function DelEvent (hEvent: THandle): Integer;
+
+ Function AddSubscriber (const EventName: PChar; const Proc: TUS_Hook = nil; const ProcOfClass: TUS_Hook_of_Object = nil): THandle;
+ Function DelSubscriber (const hSubscriber: THandle): Integer;
+
+ Function CallEventChain (const hEvent: THandle; const wParam: TwParam; lParam: TlParam): Integer;
+ Function EventExists (const EventName: PChar): Integer;
+
+ Procedure DelbyOwner(const Owner: Integer);
+ end;
+
+function HookTest(wParam: TwParam; lParam: TlParam): integer; stdcall;
+
+var
+ HookManager: THookManager;
+
+implementation
+uses
+ ULog,
+ UCore;
+
+//------------
+// Create - Creates Class and Set Standard Values
+//------------
+constructor THookManager.Create(const SpacetoAllocate: Word);
+var I: Integer;
+begin
+ inherited Create();
+
+ //Get the Space and "Zero" it
+ SetLength (Events, SpacetoAllocate);
+ For I := 0 to SpacetoAllocate-1 do
+ Events[I].Name[1] := chr(0);
+
+ SpaceinEvents := SpacetoAllocate;
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Succesful Created.');
+ {$ENDIF}
+end;
+
+//------------
+// AddEvent - Adds an Event and return the Events Handle or 0 on Failure
+//------------
+Function THookManager.AddEvent (const EventName: PChar): THandle;
+var I: Integer;
+begin
+ Result := 0;
+
+ if (EventExists(EventName) = 0) then
+ begin
+ If (SpaceinEvents > 0) then
+ begin
+ //There is already Space available
+ //Go Search it!
+ For I := 0 to High(Events) do
+ If (Events[I].Name[1] = chr(0)) then
+ begin //Found Space
+ Result := I;
+ Dec(SpaceinEvents);
+ Break;
+ end;
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Found Space for Event at Handle: ''' + InttoStr(Result+1) + '');
+ {$ENDIF}
+ end
+ else
+ begin //There is no Space => Go make some!
+ Result := Length(Events);
+ SetLength(Events, Result + 1);
+ end;
+
+ //Set Events Data
+ Events[Result].Name := EventName;
+ Events[Result].FirstSubscriber := nil;
+ Events[Result].LastSubscriber := nil;
+
+ //Handle is Index + 1
+ Inc(Result);
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Add Event succesful: ''' + EventName + '');
+ {$ENDIF}
+ end
+ {$IFDEF DEBUG}
+ else
+ debugWriteLn('HookManager: Trying to ReAdd Event: ''' + EventName + '');
+ {$ENDIF}
+end;
+
+//------------
+// DelEvent - Deletes an Event by Handle Returns False on Failure
+//------------
+Function THookManager.DelEvent (hEvent: THandle): Integer;
+var
+ Cur, Last: PSubscriberInfo;
+begin
+ hEvent := hEvent - 1; //Arrayindex is Handle - 1
+ Result := -1;
+
+
+ If (Length(Events) > hEvent) AND (Events[hEvent].Name[1] <> chr(0)) then
+ begin //Event exists
+ //Free the Space for all Subscribers
+ Cur := Events[hEvent].FirstSubscriber;
+
+ While (Cur <> nil) do
+ begin
+ Last := Cur;
+ Cur := Cur.Next;
+ FreeMem(Last, SizeOf(TSubscriberInfo));
+ end;
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Removed Event succesful: ''' + Events[hEvent].Name + '');
+ {$ENDIF}
+
+ //Free the Event
+ Events[hEvent].Name[1] := chr(0);
+ Inc(SpaceinEvents); //There is one more space for new events
+ end
+
+ {$IFDEF DEBUG}
+ else
+ debugWriteLn('HookManager: Try to Remove not Existing Event. Handle: ''' + InttoStr(hEvent) + '');
+ {$ENDIF}
+end;
+
+//------------
+// AddSubscriber - Adds an Subscriber to the Event by Name
+// Returns Handle of the Subscribtion or 0 on Failure
+//------------
+Function THookManager.AddSubscriber (const EventName: PChar; const Proc: TUS_Hook; const ProcOfClass: TUS_Hook_of_Object): THandle;
+var
+ EventHandle: THandle;
+ EventIndex: Cardinal;
+ Cur: PSubscriberInfo;
+begin
+ Result := 0;
+
+ If (@Proc <> nil) or (@ProcOfClass <> nil) then
+ begin
+ EventHandle := EventExists(EventName);
+
+ If (EventHandle <> 0) then
+ begin
+ EventIndex := EventHandle - 1;
+
+ //Get Memory
+ GetMem(Cur, SizeOf(TSubscriberInfo));
+
+ //Fill it with Data
+ Cur.Next := nil;
+
+ //Add Owner
+ Cur.Owner := Core.CurExecuted;
+
+ If (@Proc = nil) then
+ begin //Use the ProcofClass Method
+ Cur.isClass := True;
+ Cur.ProcOfClass := ProcofClass;
+ end
+ else //Use the normal Proc
+ begin
+ Cur.isClass := False;
+ Cur.Proc := Proc;
+ end;
+
+ //Create Handle (1st Word: Handle of Event; 2nd Word: unique ID
+ If (Events[EventIndex].LastSubscriber = nil) then
+ begin
+ If (Events[EventIndex].FirstSubscriber = nil) then
+ begin
+ Result := (EventHandle SHL 16);
+ Events[EventIndex].FirstSubscriber := Cur;
+ end
+ Else
+ begin
+ Result := Events[EventIndex].FirstSubscriber.Self + 1;
+ end;
+ end
+ Else
+ begin
+ Result := Events[EventIndex].LastSubscriber.Self + 1;
+ Events[EventIndex].LastSubscriber.Next := Cur;
+ end;
+
+ Cur.Self := Result;
+
+ //Add to Chain
+ Events[EventIndex].LastSubscriber := Cur;
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Add Subscriber to Event ''' + Events[EventIndex].Name + ''' succesful. Handle: ''' + InttoStr(Result) + ''' Owner: ' + InttoStr(Cur.Owner));
+ {$ENDIF}
+ end;
+ end;
+end;
+
+//------------
+// FreeSubscriber - Helper for DelSubscriber. Prevents Loss of Chain Items. Frees Memory.
+//------------
+Procedure THookManager.FreeSubscriber(const EventIndex: Word; const Last, Cur: PSubscriberInfo);
+begin
+ //Delete from Chain
+ If (Last <> nil) then
+ begin
+ Last.Next := Cur.Next;
+ end
+ else //Was first Popup
+ begin
+ Events[EventIndex].FirstSubscriber := Cur.Next;
+ end;
+
+ //Was this Last subscription ?
+ If (Cur = Events[EventIndex].LastSubscriber) then
+ begin //Change Last Subscriber
+ Events[EventIndex].LastSubscriber := Last;
+ end;
+
+ //Free Space:
+ FreeMem(Cur, SizeOf(TSubscriberInfo));
+end;
+
+//------------
+// DelSubscriber - Deletes a Subscribtion by Handle, return non Zero on Failure
+//------------
+Function THookManager.DelSubscriber (const hSubscriber: THandle): Integer;
+var
+ EventIndex: Cardinal;
+ Cur, Last: PSubscriberInfo;
+begin
+ Result := -1;
+ EventIndex := ((hSubscriber AND (High(THandle) xor High(Word))) SHR 16) - 1;
+
+ //Existing Event ?
+ If (EventIndex < Length(Events)) AND (Events[EventIndex].Name[1] <> chr(0)) then
+ begin
+ Result := -2; //Return -1 on not existing Event, -2 on not existing Subscription
+
+ //Search for Subscription
+ Cur := Events[EventIndex].FirstSubscriber;
+ Last := nil;
+
+ //go through the chain ...
+ While (Cur <> nil) do
+ begin
+ If (Cur.Self = hSubscriber) then
+ begin //Found Subscription we searched for
+ FreeSubscriber(EventIndex, Last, Cur);
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Del Subscriber from Event ''' + Events[EventIndex].Name + ''' succesful. Handle: ''' + InttoStr(hSubscriber) + '');
+ {$ENDIF}
+
+ //Set Result and Break the Loop
+ Result := 0;
+ Break;
+ end;
+
+ Last := Cur;
+ Cur := Cur.Next;
+ end;
+
+ end;
+end;
+
+
+//------------
+// CallEventChain - Calls the Chain of a specified EventHandle
+// Returns: -1: Handle doesn't Exist, 0 Chain is called until the End
+//------------
+Function THookManager.CallEventChain (const hEvent: THandle; const wParam: TwParam; lParam: TlParam): Integer;
+var
+ EventIndex: Cardinal;
+ Cur: PSubscriberInfo;
+ CurExecutedBackup: Integer; //backup of Core.CurExecuted Attribute
+begin
+ Result := -1;
+ EventIndex := hEvent - 1;
+
+ If ((EventIndex <= High(Events)) AND (Events[EventIndex].Name[1] <> chr(0))) then
+ begin //Existing Event
+ //Backup CurExecuted
+ CurExecutedBackup := Core.CurExecuted;
+
+ //Start calling the Chain !!!11
+ Cur := Events[EventIndex].FirstSubscriber;
+ Result := 0;
+ //Call Hooks until the Chain is at the End or breaked
+ While ((Cur <> nil) AND (Result = 0)) do
+ begin
+ //Set CurExecuted
+ Core.CurExecuted := Cur.Owner;
+ if (Cur.isClass) then
+ Result := Cur.ProcOfClass(wParam, lParam)
+ else
+ Result := Cur.Proc(wParam, lParam);
+
+ Cur := Cur.Next;
+ end;
+
+ //Restore CurExecuted
+ Core.CurExecuted := CurExecutedBackup;
+ end;
+
+ {$IFDEF DEBUG}
+ debugWriteLn('HookManager: Called Chain from Event ''' + Events[EventIndex].Name + ''' succesful. Result: ''' + InttoStr(Result) + '');
+ {$ENDIF}
+end;
+
+//------------
+// EventExists - Returns non Zero if an Event with the given Name exists
+//------------
+Function THookManager.EventExists (const EventName: PChar): Integer;
+var
+ I: Integer;
+ Name: String[60];
+begin
+ Result := 0;
+ //If (Length(EventName) <
+ Name := String(EventName);
+
+ //Sure not to search for empty space
+ If (Name[1] <> chr(0)) then
+ begin
+ //Search for Event
+ For I := 0 to High(Events) do
+ If (Events[I].Name = Name) then
+ begin //Event found
+ Result := I + 1;
+ Break;
+ end;
+ end;
+end;
+
+//------------
+// DelbyOwner - Dels all Subscriptions by a specific Owner. (For Clean Plugin/Module unloading)
+//------------
+Procedure THookManager.DelbyOwner(const Owner: Integer);
+var
+ I: Integer;
+ Cur, Last: PSubscriberInfo;
+begin
+ //Search for Owner in all Hooks Chains
+ For I := 0 to High(Events) do
+ begin
+ If (Events[I].Name[1] <> chr(0)) then
+ begin
+
+ Last := nil;
+ Cur := Events[I].FirstSubscriber;
+ //Went Through Chain
+ While (Cur <> nil) do
+ begin
+ If (Cur.Owner = Owner) then
+ begin //Found Subscription by Owner -> Delete
+ FreeSubscriber(I, Last, Cur);
+ If (Last <> nil) then
+ Cur := Last.Next
+ else
+ Cur := Events[I].FirstSubscriber;
+ end
+ Else
+ begin
+ //Next Item:
+ Last := Cur;
+ Cur := Cur.Next;
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+function HookTest(wParam: TwParam; lParam: TlParam): integer; stdcall;
+begin
+ Result := 0; //Don't break the chain
+ Core.ShowMessage(CORE_SM_INFO, PChar(String(PChar(Pointer(lParam))) + ': ' + String(PChar(Pointer(wParam)))));
+end;
+
+end.
diff --git a/src/Classes/UImage.pas b/src/Classes/UImage.pas
new file mode 100644
index 00000000..d33c0d38
--- /dev/null
+++ b/src/Classes/UImage.pas
@@ -0,0 +1,993 @@
+unit UImage;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SDL;
+
+{$DEFINE HavePNG}
+{$DEFINE HaveBMP}
+{$DEFINE HaveJPG}
+
+const
+ PixelFmt_RGBA: TSDL_Pixelformat = (
+ palette: nil;
+ BitsPerPixel: 32;
+ BytesPerPixel: 4;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 0;
+ Gshift: 8;
+ Bshift: 16;
+ Ashift: 24;
+ Rmask: $000000ff;
+ Gmask: $0000ff00;
+ Bmask: $00ff0000;
+ Amask: $ff000000;
+ ColorKey: 0;
+ Alpha: 255
+ );
+
+ PixelFmt_RGB: TSDL_Pixelformat = (
+ palette: nil;
+ BitsPerPixel: 24;
+ BytesPerPixel: 3;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 0;
+ Gshift: 8;
+ Bshift: 16;
+ Ashift: 0;
+ Rmask: $000000ff;
+ Gmask: $0000ff00;
+ Bmask: $00ff0000;
+ Amask: $00000000;
+ ColorKey: 0;
+ Alpha: 255
+ );
+
+ PixelFmt_BGRA: TSDL_Pixelformat = (
+ palette: nil;
+ BitsPerPixel: 32;
+ BytesPerPixel: 4;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 16;
+ Gshift: 8;
+ Bshift: 0;
+ Ashift: 24;
+ Rmask: $00ff0000;
+ Gmask: $0000ff00;
+ Bmask: $000000ff;
+ Amask: $ff000000;
+ ColorKey: 0;
+ Alpha: 255
+ );
+
+ PixelFmt_BGR: TSDL_Pixelformat = (
+ palette: nil;
+ BitsPerPixel: 24;
+ BytesPerPixel: 3;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 16;
+ Gshift: 8;
+ Bshift: 0;
+ Ashift: 0;
+ Rmask: $00ff0000;
+ Gmask: $0000ff00;
+ Bmask: $000000ff;
+ Amask: $00000000;
+ ColorKey: 0;
+ Alpha: 255
+ );
+
+type
+ TImagePixelFmt = (
+ ipfRGBA, ipfRGB, ipfBGRA, ipfBGR
+ );
+
+(*******************************************************
+ * Image saving
+ *******************************************************)
+
+{$IFDEF HavePNG}
+function WritePNGImage(const FileName: string; Surface: PSDL_Surface): boolean;
+{$ENDIF}
+{$IFDEF HaveBMP}
+function WriteBMPImage(const FileName: string; Surface: PSDL_Surface): boolean;
+{$ENDIF}
+{$IFDEF HaveJPG}
+function WriteJPGImage(const FileName: string; Surface: PSDL_Surface; Quality: integer): boolean;
+{$ENDIF}
+
+(*******************************************************
+ * Image loading
+ *******************************************************)
+
+function LoadImage(const Identifier: string): PSDL_Surface;
+
+(*******************************************************
+ * Image manipulation
+ *******************************************************)
+
+function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
+procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
+
+
+implementation
+
+uses
+ SysUtils,
+ Classes,
+ Math,
+ {$IFDEF MSWINDOWS}
+ Windows,
+ {$ENDIF}
+ {$IFDEF HaveJPG}
+ {$IFDEF Delphi}
+ Graphics,
+ jpeg,
+ {$ELSE}
+ jpeglib,
+ jerror,
+ jcparam,
+ jdatadst, jcapimin, jcapistd,
+ {$ENDIF}
+ {$ENDIF}
+ {$IFDEF HavePNG}
+ png,
+ {$ENDIF}
+ zlib,
+ sdl_image,
+ sdlutils,
+ UCommon,
+ ULog;
+
+
+function IsRGBSurface(pixelFmt: PSDL_PixelFormat): boolean;
+begin
+ Result := (pixelFmt.BitsPerPixel = 24) and
+ (pixelFmt.RMask = $0000FF) and
+ (pixelFmt.GMask = $00FF00) and
+ (pixelFmt.BMask = $FF0000);
+end;
+
+function IsRGBASurface(pixelFmt: PSDL_PixelFormat): boolean;
+begin
+ Result := (pixelFmt.BitsPerPixel = 32) and
+ (pixelFmt.RMask = $000000FF) and
+ (pixelFmt.GMask = $0000FF00) and
+ (pixelFmt.BMask = $00FF0000) and
+ (pixelFmt.AMask = $FF000000);
+end;
+
+function IsBGRSurface(pixelFmt: PSDL_PixelFormat): boolean;
+begin
+ Result := (pixelFmt.BitsPerPixel = 24) and
+ (pixelFmt.BMask = $0000FF) and
+ (pixelFmt.GMask = $00FF00) and
+ (pixelFmt.RMask = $FF0000);
+end;
+
+function IsBGRASurface(pixelFmt: PSDL_PixelFormat): boolean;
+begin
+ Result := (pixelFmt.BitsPerPixel = 32) and
+ (pixelFmt.BMask = $000000FF) and
+ (pixelFmt.GMask = $0000FF00) and
+ (pixelFmt.RMask = $00FF0000) and
+ (pixelFmt.AMask = $FF000000);
+end;
+
+// Converts alpha-formats to BGRA, non-alpha to BGR, and leaves BGR(A) as is
+// sets converted to true if the surface needed to be converted
+function ConvertToBGR_BGRASurface(Surface: PSDL_Surface; out Converted: boolean): PSDL_Surface;
+var
+ pixelFmt: PSDL_PixelFormat;
+begin
+ pixelFmt := Surface.format;
+ if (IsBGRSurface(pixelFmt) or IsBGRASurface(pixelFmt)) then
+ begin
+ Converted := false;
+ Result := Surface;
+ end
+ else
+ begin
+ // invalid format -> needs conversion
+ if (pixelFmt.AMask <> 0) then
+ Result := SDL_ConvertSurface(Surface, @PixelFmt_BGRA, SDL_SWSURFACE)
+ else
+ Result := SDL_ConvertSurface(Surface, @PixelFmt_BGR, SDL_SWSURFACE);
+ Converted := true;
+ end;
+end;
+
+// Converts alpha-formats to RGBA, non-alpha to RGB, and leaves RGB(A) as is
+// sets converted to true if the surface needed to be converted
+function ConvertToRGB_RGBASurface(Surface: PSDL_Surface; out Converted: boolean): PSDL_Surface;
+var
+ pixelFmt: PSDL_PixelFormat;
+begin
+ pixelFmt := Surface.format;
+ if (IsRGBSurface(pixelFmt) or IsRGBASurface(pixelFmt)) then
+ begin
+ Converted := false;
+ Result := Surface;
+ end
+ else
+ begin
+ // invalid format -> needs conversion
+ if (pixelFmt.AMask <> 0) then
+ Result := SDL_ConvertSurface(Surface, @PixelFmt_RGBA, SDL_SWSURFACE)
+ else
+ Result := SDL_ConvertSurface(Surface, @PixelFmt_RGB, SDL_SWSURFACE);
+ Converted := true;
+ end;
+end;
+
+
+(*******************************************************
+ * Image saving
+ *******************************************************)
+
+(***************************
+ * PNG section
+ *****************************)
+
+{$IFDEF HavePNG}
+
+// delphi does not support setjmp()/longjmp() -> define our own error-handler
+procedure user_error_fn(png_ptr: png_structp; error_msg: png_const_charp); cdecl;
+begin
+ raise Exception.Create(error_msg);
+end;
+
+procedure user_read_data(png_ptr: png_structp; data: png_bytep; length: png_size_t); cdecl;
+var
+ inFile: TFileStream;
+begin
+ inFile := TFileStream(png_get_io_ptr(png_ptr));
+ inFile.Read(data^, length);
+end;
+
+procedure user_write_data(png_ptr: png_structp; data: png_bytep; length: png_size_t); cdecl;
+var
+ outFile: TFileStream;
+begin
+ outFile := TFileStream(png_get_io_ptr(png_ptr));
+ outFile.Write(data^, length);
+end;
+
+procedure user_flush_data(png_ptr: png_structp); cdecl;
+//var
+// outFile: TFileStream;
+begin
+ // binary files are flushed automatically, Flush() works with Text-files only
+ //outFile := TFileStream(png_get_io_ptr(png_ptr));
+ //outFile.Flush();
+end;
+
+procedure DateTimeToPngTime(time: TDateTime; var pngTime: png_time);
+var
+ year, month, day: word;
+ hour, minute, second, msecond: word;
+begin
+ DecodeDate(time, year, month, day);
+ pngTime.year := year;
+ pngTime.month := month;
+ pngTime.day := day;
+ DecodeTime(time, hour, minute, second, msecond);
+ pngTime.hour := hour;
+ pngTime.minute := minute;
+ pngTime.second := second;
+end;
+
+(*
+ * ImageData must be in RGB-format
+ *)
+function WritePNGImage(const FileName: string; Surface: PSDL_Surface): boolean;
+var
+ png_ptr: png_structp;
+ info_ptr: png_infop;
+ pngFile: TFileStream;
+ row: integer;
+ rowData: array of png_bytep;
+// rowStride: integer;
+ converted: boolean;
+ colorType: integer;
+// time: png_time;
+begin
+ Result := false;
+
+ // open file for writing
+ try
+ pngFile := TFileStream.Create(FileName, fmCreate);
+ except
+ Log.LogError('Could not open file: "' + FileName + '"', 'WritePngImage');
+ Exit;
+ end;
+
+ // only 24bit (RGB) or 32bit (RGBA) data is supported, so convert to it
+ Surface := ConvertToRGB_RGBASurface(Surface, converted);
+
+ png_ptr := nil;
+
+ try
+ // initialize png (and enable a user-defined error-handler that throws an exception on error)
+ png_ptr := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, @user_error_fn, nil);
+ // the error-handler is called if png_create_write_struct() fails, so png_ptr should always be <> nil
+ if (png_ptr = nil) then
+ begin
+ Log.LogError('png_create_write_struct() failed', 'WritePngImage');
+ if (converted) then
+ SDL_FreeSurface(Surface);
+ Exit;
+ end;
+
+ info_ptr := png_create_info_struct(png_ptr);
+
+ if (Surface^.format^.BitsPerPixel = 24) then
+ colorType := PNG_COLOR_TYPE_RGB
+ else
+ colorType := PNG_COLOR_TYPE_RGBA;
+
+ // define write IO-functions (POSIX-style FILE-pointers are not available in Delphi)
+ png_set_write_fn(png_ptr, pngFile, @user_write_data, @user_flush_data);
+ png_set_IHDR(
+ png_ptr, info_ptr,
+ Surface.w, Surface.h,
+ 8,
+ colorType,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT
+ );
+
+ // TODO: do we need the modification time?
+ //DateTimeToPngTime(Now, time);
+ //png_set_tIME(png_ptr, info_ptr, @time);
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_LockSurface(Surface);
+
+ // setup data
+ SetLength(rowData, Surface.h);
+ for row := 0 to Surface.h-1 do
+ begin
+ // set rowData-elements to beginning of each image row
+ // Note: the byte-count of a row is pitch (which is not width*bitsPerPixel if the image is aligned)
+ rowData[row] := @PChar(Surface.pixels)[(Surface.h-row-1) * Surface.pitch];
+ end;
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_UnlockSurface(Surface);
+
+ png_write_info(png_ptr, info_ptr);
+ png_write_image(png_ptr, png_bytepp(rowData));
+ png_write_end(png_ptr, nil);
+
+ Result := true;
+ except on E: Exception do
+ Log.LogError(E.message, 'WritePngImage');
+ end;
+
+ // free row-data
+ SetLength(rowData, 0);
+
+ // free png-resources
+ if (png_ptr <> nil) then
+ png_destroy_write_struct(@png_ptr, nil);
+
+ if (converted) then
+ SDL_FreeSurface(Surface);
+
+ // close file
+ pngFile.Free;
+end;
+
+{$ENDIF}
+
+(***************************
+ * BMP section
+ *****************************)
+
+{$IFDEF HaveBMP}
+
+{$IFNDEF MSWINDOWS}
+const
+ (* constants for the biCompression field *)
+ BI_RGB = 0;
+ BI_RLE8 = 1;
+ BI_RLE4 = 2;
+ BI_BITFIELDS = 3;
+ BI_JPEG = 4;
+ BI_PNG = 5;
+
+type
+ BITMAPINFOHEADER = record
+ biSize: longword;
+ biWidth: longint;
+ biHeight: longint;
+ biPlanes: word;
+ biBitCount: word;
+ biCompression: longword;
+ biSizeImage: longword;
+ biXPelsPerMeter: longint;
+ biYPelsPerMeter: longint;
+ biClrUsed: longword;
+ biClrImportant: longword;
+ end;
+ LPBITMAPINFOHEADER = ^BITMAPINFOHEADER;
+ TBITMAPINFOHEADER = BITMAPINFOHEADER;
+ PBITMAPINFOHEADER = ^BITMAPINFOHEADER;
+
+ RGBTRIPLE = record
+ rgbtBlue: byte;
+ rgbtGreen: byte;
+ rgbtRed: byte;
+ end;
+ tagRGBTRIPLE = RGBTRIPLE;
+ TRGBTRIPLE = RGBTRIPLE;
+ PRGBTRIPLE = ^RGBTRIPLE;
+
+ RGBQUAD = record
+ rgbBlue: byte;
+ rgbGreen: byte;
+ rgbRed: byte;
+ rgbReserved: byte;
+ end;
+ tagRGBQUAD = RGBQUAD;
+ TRGBQUAD = RGBQUAD;
+ PRGBQUAD = ^RGBQUAD;
+
+ BITMAPINFO = record
+ bmiHeader: BITMAPINFOHEADER;
+ bmiColors: array[0..0] of RGBQUAD;
+ end;
+ LPBITMAPINFO = ^BITMAPINFO;
+ PBITMAPINFO = ^BITMAPINFO;
+ TBITMAPINFO = BITMAPINFO;
+
+ {$PACKRECORDS 2}
+ BITMAPFILEHEADER = record
+ bfType: word;
+ bfSize: longword;
+ bfReserved1: word;
+ bfReserved2: word;
+ bfOffBits: longword;
+ end;
+ {$PACKRECORDS DEFAULT}
+{$ENDIF}
+
+(*
+ * ImageData must be in BGR-format
+ *)
+function WriteBMPImage(const FileName: string; Surface: PSDL_Surface): boolean;
+var
+ bmpFile: TFileStream;
+ FileInfo: BITMAPINFOHEADER;
+ FileHeader: BITMAPFILEHEADER;
+ Converted: boolean;
+ Row: integer;
+ RowSize: integer;
+begin
+ Result := false;
+
+ // open file for writing
+ try
+ bmpFile := TFileStream.Create(FileName, fmCreate);
+ except
+ Log.LogError('Could not open file: "' + FileName + '"', 'WriteBMPImage');
+ Exit;
+ end;
+
+ // only 24bit (BGR) or 32bit (BGRA) data is supported, so convert to it
+ Surface := ConvertToBGR_BGRASurface(Surface, Converted);
+
+ // aligned (4-byte) row-size in bytes
+ RowSize := ((Surface.w * Surface.format.BytesPerPixel + 3) div 4) * 4;
+
+ // initialize bitmap info
+ FillChar(FileInfo, SizeOf(BITMAPINFOHEADER), 0);
+ with FileInfo do
+ begin
+ biSize := SizeOf(BITMAPINFOHEADER);
+ biWidth := Surface.w;
+ biHeight := Surface.h;
+ biPlanes := 1;
+ biBitCount := Surface^.format^.BitsPerPixel;
+ biCompression := BI_RGB;
+ biSizeImage := RowSize * Surface.h;
+ end;
+
+ // initialize header-data
+ FillChar(FileHeader, SizeOf(BITMAPFILEHEADER), 0);
+ with FileHeader do
+ begin
+ bfType := $4D42; // = 'BM'
+ bfOffBits := SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER);
+ bfSize := bfOffBits + FileInfo.biSizeImage;
+ end;
+
+ // and move the whole stuff into the file ;-)
+ try
+ // write headers
+ bmpFile.Write(FileHeader, SizeOf(BITMAPFILEHEADER));
+ bmpFile.Write(FileInfo, SizeOf(BITMAPINFOHEADER));
+
+ // write image-data
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_LockSurface(Surface);
+
+ // BMP needs 4-byte alignment
+ if (Surface.pitch mod 4 = 0) then
+ begin
+ // aligned correctly -> write whole image at once
+ bmpFile.Write(Surface.pixels^, FileInfo.biSizeImage);
+ end
+ else
+ begin
+ // misaligned -> write each line separately
+ // Note: for the last line unassigned memory (> last Surface.pixels element)
+ // will be copied to the padding area (last bytes of a row),
+ // but we do not care because the content of padding data is ignored anyhow.
+ for Row := 0 to Surface.h do
+ bmpFile.Write(PChar(Surface.pixels)[Row * Surface.pitch], RowSize);
+ end;
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_UnlockSurface(Surface);
+
+ Result := true;
+ finally
+ Log.LogError('Could not write file: "' + FileName + '"', 'WriteBMPImage');
+ end;
+
+ if (Converted) then
+ SDL_FreeSurface(Surface);
+
+ // close file
+ bmpFile.Free;
+end;
+
+{$ENDIF}
+
+(***************************
+ * JPG section
+ *****************************)
+
+{$IFDEF HaveJPG}
+
+function WriteJPGImage(const FileName: string; Surface: PSDL_Surface; Quality: integer): boolean;
+var
+ {$IFDEF Delphi}
+ Bitmap: TBitmap;
+ BitmapInfo: TBitmapInfo;
+ Jpeg: TJpegImage;
+ row: integer;
+ {$ELSE}
+ cinfo: jpeg_compress_struct;
+ jerr : jpeg_error_mgr;
+ jpgFile: TFileStream;
+ rowPtr: array[0..0] of JSAMPROW;
+ {$ENDIF}
+ converted: boolean;
+begin
+ Result := false;
+
+ {$IFDEF Delphi}
+ // only 24bit (BGR) data is supported, so convert to it
+ if (IsBGRSurface(Surface.format)) then
+ converted := false
+ else
+ begin
+ Surface := SDL_ConvertSurface(Surface, @PixelFmt_BGR, SDL_SWSURFACE);
+ converted := true;
+ end;
+
+ // create and setup bitmap
+ Bitmap := TBitmap.Create;
+ Bitmap.PixelFormat := pf24bit;
+ Bitmap.Width := Surface.w;
+ Bitmap.Height := Surface.h;
+
+ // setup bitmap info on source image (Surface parameter)
+ ZeroMemory(@BitmapInfo, SizeOf(BitmapInfo));
+ with BitmapInfo.bmiHeader do
+ begin
+ biSize := SizeOf(BITMAPINFOHEADER);
+ biWidth := Surface.w;
+ biHeight := Surface.h;
+ biPlanes := 1;
+ biBitCount := 24;
+ biCompression := BI_RGB;
+ end;
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_LockSurface(Surface);
+
+ // use fast Win32-API functions to copy data instead of Bitmap.Canvas.Pixels
+ if (Surface.pitch mod 4 = 0) then
+ begin
+ // if the image is aligned (to a 4-byte boundary) -> copy all data at once
+ // Note: surfaces created with SDL (e.g. with SDL_ConvertSurface) are aligned
+ SetDIBits(0, Bitmap.Handle, 0, Bitmap.Height, Surface.pixels, BitmapInfo, DIB_RGB_COLORS);
+ end
+ else
+ begin
+ // wrong alignment -> copy each line separately.
+ // Note: for the last line unassigned memory (> last Surface.pixels element)
+ // will be copied to the padding area (last bytes of a row),
+ // but we do not care because the content of padding data is ignored anyhow.
+ for row := 0 to Surface.h do
+ begin
+ SetDIBits(0, Bitmap.Handle, row, 1, @PChar(Surface.pixels)[row * Surface.pitch],
+ BitmapInfo, DIB_RGB_COLORS);
+ end;
+ end;
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_UnlockSurface(Surface);
+
+ // assign Bitmap to JPEG and store the latter
+ Jpeg := TJPEGImage.Create;
+ Jpeg.Assign(Bitmap);
+ Bitmap.Free;
+ Jpeg.CompressionQuality := Quality;
+ try
+ // compress image (don't forget this line, otherwise it won't be compressed)
+ Jpeg.Compress();
+ Jpeg.SaveToFile(FileName);
+ except
+ Log.LogError('Could not save file: "' + FileName + '"', 'WriteJPGImage');
+ Exit;
+ end;
+ Jpeg.Free;
+ {$ELSE}
+ // based on example.pas in FPC's packages/base/pasjpeg directory
+
+ // only 24bit (RGB) data is supported, so convert to it
+ if (IsRGBSurface(Surface.format)) then
+ converted := false
+ else
+ begin
+ Surface := SDL_ConvertSurface(Surface, @PixelFmt_RGB, SDL_SWSURFACE);
+ converted := true;
+ end;
+
+ // allocate and initialize JPEG compression object
+ cinfo.err := jpeg_std_error(jerr);
+ // msg_level that will be displayed. (Nomssi)
+ //jerr.trace_level := 3;
+ // initialize the JPEG compression object
+ jpeg_create_compress(@cinfo);
+
+ // open file for writing
+ try
+ jpgFile := TFileStream.Create(FileName, fmCreate);
+ except
+ Log.LogError('Could not open file: "' + FileName + '"', 'WriteJPGImage');
+ Exit;
+ end;
+
+ // specify data destination
+ jpeg_stdio_dest(@cinfo, @jpgFile);
+
+ // set parameters for compression
+ cinfo.image_width := Surface.w;
+ cinfo.image_height := Surface.h;
+ cinfo.in_color_space := JCS_RGB;
+ cinfo.input_components := 3;
+ cinfo.data_precision := 8;
+
+ // set default compression parameters
+ jpeg_set_defaults(@cinfo);
+ jpeg_set_quality(@cinfo, quality, true);
+
+ // start compressor
+ jpeg_start_compress(@cinfo, true);
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_LockSurface(Surface);
+
+ while (cinfo.next_scanline < cinfo.image_height) do
+ begin
+ // Note: the byte-count of a row is pitch (which is not width*bitsPerPixel if the image is aligned)
+ rowPtr[0] := JSAMPROW(@PChar(Surface.pixels)[(Surface.h-cinfo.next_scanline-1) * Surface.pitch]);
+ jpeg_write_scanlines(@cinfo, JSAMPARRAY(@rowPtr), 1);
+ end;
+
+ if (SDL_MUSTLOCK(Surface)) then
+ SDL_UnlockSurface(Surface);
+
+ // finish compression
+ jpeg_finish_compress(@cinfo);
+ // close the output file
+ jpgFile.Free;
+
+ // release JPEG compression object
+ jpeg_destroy_compress(@cinfo);
+ {$ENDIF}
+
+ if (converted) then
+ SDL_FreeSurface(Surface);
+
+ Result := true;
+end;
+
+{$ENDIF}
+
+
+(*******************************************************
+ * Image loading
+ *******************************************************)
+
+
+(*
+ * Loads an image from the given file or resource
+ *)
+function LoadImage(const Identifier: string): PSDL_Surface;
+var
+ TexRWops: PSDL_RWops;
+ TexStream: TStream;
+ FileName: string;
+begin
+ Result := nil;
+ TexRWops := nil;
+
+ if Identifier = '' then
+ exit;
+
+ //Log.LogStatus( Identifier, 'LoadImage' );
+
+ FileName := Identifier;
+
+ if (FileExistsInsensitive(FileName)) then
+ begin
+ // load from file
+ //Log.LogStatus( 'Is File ( Loading : '+FileName+')', ' LoadImage' );
+ try
+ Result := IMG_Load(PChar(FileName));
+ //Log.LogStatus( ' '+inttostr( integer( Result ) ), ' LoadImage' );
+ except
+ Log.LogError('Could not load from file "'+FileName+'"', 'LoadImage');
+ Exit;
+ end;
+ end
+ else
+ begin
+ //Log.LogStatus( 'IS Resource, because file does not exist.('+Identifier+')', ' LoadImage' );
+
+ TexStream := GetResourceStream(Identifier, 'TEX');
+ if (not assigned(TexStream)) then
+ begin
+ Log.LogError( 'Invalid file or resource "'+ Identifier+'"', 'LoadImage');
+ Exit;
+ end;
+
+ TexRWops := RWopsFromStream(TexStream);
+ if (TexRWops = nil) then
+ begin
+ Log.LogError( 'Could not assign resource "'+Identifier+'"', 'LoadImage');
+ TexStream.Free();
+ Exit;
+ end;
+
+ //Log.LogStatus( 'resource Assigned....' , Identifier);
+ try
+ Result := IMG_Load_RW(TexRWops, 0);
+ except
+ Log.LogError( 'Could not read resource "'+Identifier+'"', 'LoadImage');
+ end;
+
+ SDL_FreeRW(TexRWops);
+ TexStream.Free();
+ end;
+end;
+
+
+(*******************************************************
+ * Image manipulation
+ *******************************************************)
+
+
+function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
+begin
+ if (fmt1^.BitsPerPixel = fmt2^.BitsPerPixel) and
+ (fmt1^.BytesPerPixel = fmt2^.BytesPerPixel) and
+ (fmt1^.Rloss = fmt2^.Rloss) and (fmt1^.Gloss = fmt2^.Gloss) and
+ (fmt1^.Bloss = fmt2^.Bloss) and (fmt1^.Rmask = fmt2^.Rmask) and
+ (fmt1^.Gmask = fmt2^.Gmask) and (fmt1^.Bmask = fmt2^.Bmask) and
+ (fmt1^.Rshift = fmt2^.Rshift) and (fmt1^.Gshift = fmt2^.Gshift) and
+ (fmt1^.Bshift = fmt2^.Bshift)
+ then
+ Result := true
+ else
+ Result := false;
+end;
+
+procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+var
+ TempSurface: PSDL_Surface;
+begin
+ TempSurface := ImgSurface;
+ ImgSurface := SDL_ScaleSurfaceRect(TempSurface,
+ 0, 0, TempSurface^.W,TempSurface^.H,
+ Width, Height);
+ SDL_FreeSurface(TempSurface);
+end;
+
+procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+var
+ TempSurface: PSDL_Surface;
+ ImgFmt: PSDL_PixelFormat;
+begin
+ TempSurface := ImgSurface;
+
+ // create a new surface with given width and height
+ ImgFmt := TempSurface^.format;
+ ImgSurface := SDL_CreateRGBSurface(
+ SDL_SWSURFACE, Width, Height, ImgFmt^.BitsPerPixel,
+ ImgFmt^.RMask, ImgFmt^.GMask, ImgFmt^.BMask, ImgFmt^.AMask);
+
+ // copy image from temp- to new surface
+ SDL_SetAlpha(ImgSurface, 0, 255);
+ SDL_SetAlpha(TempSurface, 0, 255);
+ SDL_BlitSurface(TempSurface, nil, ImgSurface, nil);
+
+ SDL_FreeSurface(TempSurface);
+end;
+
+(*
+// Old slow floating point version of ColorizeTexture.
+// For an easier understanding of the faster fixed point version below.
+procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal);
+var
+ clr: array[0..2] of Double; // [0: R, 1: G, 2: B]
+ hsv: array[0..2] of Double; // [0: H(ue), 1: S(aturation), 2: V(alue)]
+ delta, f, p, q, t: Double;
+ max: Double;
+begin
+ clr[0] := PixelColors[0]/255;
+ clr[1] := PixelColors[1]/255;
+ clr[2] := PixelColors[2]/255;
+ max := maxvalue(clr);
+ delta := max - minvalue(clr);
+
+ hsv[0] := DestinationHue; // set H(ue)
+ hsv[2] := max; // set V(alue)
+ // calc S(aturation)
+ if (max = 0.0) then
+ hsv[1] := 0.0
+ else
+ hsv[1] := delta/max;
+
+ //ColorizePixel(PByteArray(Pixel), DestinationHue);
+ h_int := trunc(hsv[0]); // h_int = |_h_|
+ f := hsv[0]-h_int; // f = h-h_int
+ p := hsv[2]*(1.0-hsv[1]); // p = v*(1-s)
+ q := hsv[2]*(1.0-(hsv[1]*f)); // q = v*(1-s*f)
+ t := hsv[2]*(1.0-(hsv[1]*(1.0-f))); // t = v*(1-s*(1-f))
+ case h_int of
+ 0: begin clr[0] := hsv[2]; clr[1] := t; clr[2] := p; end; // (v,t,p)
+ 1: begin clr[0] := q; clr[1] := hsv[2]; clr[2] := p; end; // (q,v,p)
+ 2: begin clr[0] := p; clr[1] := hsv[2]; clr[2] := t; end; // (p,v,t)
+ 3: begin clr[0] := p; clr[1] := q; clr[2] := hsv[2]; end; // (p,q,v)
+ 4: begin clr[0] := t; clr[1] := p; clr[2] := hsv[2]; end; // (t,p,v)
+ 5: begin clr[0] := hsv[2]; clr[1] := p; clr[2] := q; end; // (v,p,q)
+ end;
+
+ // and store new rgb back into the image
+ PixelColors[0] := trunc(255*clr[0]);
+ PixelColors[1] := trunc(255*clr[1]);
+ PixelColors[2] := trunc(255*clr[2]);
+end;
+*)
+
+procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
+
+ //returns hue within range [0.0-6.0)
+ function col2hue(Color:Cardinal): double;
+ var
+ clr: array[0..2] of double;
+ hue, max, delta: double;
+ begin
+ clr[0] := ((Color and $ff0000) shr 16)/255; // R
+ clr[1] := ((Color and $ff00) shr 8)/255; // G
+ clr[2] := (Color and $ff) /255; // B
+ max := maxvalue(clr);
+ delta := max - minvalue(clr);
+ // calc hue
+ if (delta = 0.0) then hue := 0
+ else if (clr[0] = max) then hue := (clr[1]-clr[2])/delta
+ else if (clr[1] = max) then hue := 2.0+(clr[2]-clr[0])/delta
+ else if (clr[2] = max) then hue := 4.0+(clr[0]-clr[1])/delta;
+ if (hue < 0.0) then
+ hue := hue + 6.0;
+ Result := hue;
+ end;
+
+var
+ DestinationHue: Double;
+ PixelIndex: Cardinal;
+ Pixel: PByte;
+ PixelColors: PByteArray;
+ clr: array[0..2] of UInt32; // [0: R, 1: G, 2: B]
+ hsv: array[0..2] of UInt32; // [0: H(ue), 1: S(aturation), 2: V(alue)]
+ dhue: UInt32;
+ h_int: Cardinal;
+ delta, f, p, q, t: Longint;
+ max: Uint32;
+begin
+ DestinationHue := col2hue(NewColor);
+
+ dhue := Trunc(DestinationHue*1024);
+
+ Pixel := ImgSurface^.Pixels;
+
+ for PixelIndex := 0 to (ImgSurface^.W * ImgSurface^.H)-1 do
+ begin
+ PixelColors := PByteArray(Pixel);
+ // inlined colorize per pixel
+
+ // uses fixed point math
+ // get color values
+ clr[0] := PixelColors[0] shl 10;
+ clr[1] := PixelColors[1] shl 10;
+ clr[2] := PixelColors[2] shl 10;
+ //calculate luminance and saturation from rgb
+
+ max := clr[0];
+ if clr[1] > max then max := clr[1];
+ if clr[2] > max then max := clr[2];
+ delta := clr[0];
+ if clr[1] < delta then delta := clr[1];
+ if clr[2] < delta then delta := clr[2];
+ delta := max-delta;
+ hsv[0] := dhue; // shl 8
+ hsv[2] := max; // shl 8
+ if (max = 0) then
+ hsv[1] := 0
+ else
+ hsv[1] := (delta shl 10) div max; // shl 8
+ h_int := hsv[0] and $fffffC00;
+ f := hsv[0]-h_int; //shl 10
+ p := (hsv[2]*(1024-hsv[1])) shr 10;
+ q := (hsv[2]*(1024-(hsv[1]*f) shr 10)) shr 10;
+ t := (hsv[2]*(1024-(hsv[1]*(1024-f)) shr 10)) shr 10;
+ h_int := h_int shr 10;
+ case h_int of
+ 0: begin clr[0] := hsv[2]; clr[1] := t; clr[2] := p; end; // (v,t,p)
+ 1: begin clr[0] := q; clr[1] := hsv[2]; clr[2] := p; end; // (q,v,p)
+ 2: begin clr[0] := p; clr[1] := hsv[2]; clr[2] := t; end; // (p,v,t)
+ 3: begin clr[0] := p; clr[1] := q; clr[2] := hsv[2]; end; // (p,q,v)
+ 4: begin clr[0] := t; clr[1] := p; clr[2] := hsv[2]; end; // (t,p,v)
+ 5: begin clr[0] := hsv[2]; clr[1] := p; clr[2] := q; end; // (v,p,q)
+ end;
+
+ PixelColors[0] := clr[0] shr 10;
+ PixelColors[1] := clr[1] shr 10;
+ PixelColors[2] := clr[2] shr 10;
+
+ Inc(Pixel, ImgSurface^.format.BytesPerPixel);
+ end;
+end;
+
+end.
diff --git a/src/Classes/UIni.pas b/src/Classes/UIni.pas
new file mode 100644
index 00000000..b286c917
--- /dev/null
+++ b/src/Classes/UIni.pas
@@ -0,0 +1,928 @@
+unit UIni;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes,
+ IniFiles,
+ ULog,
+ SysUtils;
+
+type
+ // TInputDeviceConfig stores the configuration for an input device.
+ // Configurations will be stored in the InputDeviceConfig array.
+ // Note that not all devices listed in InputDeviceConfig are active devices.
+ // Some might be unplugged and hence unavailable.
+ // Available devices are held in TAudioInputProcessor.DeviceList. Each
+ // TAudioInputDevice listed there has a CfgIndex field which is the index to
+ // its configuration in the InputDeviceConfig array.
+ // Name:
+ // the name of the input device
+ // Input:
+ // the index of the input source to use for recording
+ // ChannelToPlayerMap:
+ // mapping of recording channels to players, e.g. ChannelToPlayerMap[0] = 2
+ // maps the channel 0 (left) to player 2. A player index of 0 means that
+ // the channel is not assigned to a player.
+ PInputDeviceConfig = ^TInputDeviceConfig;
+ TInputDeviceConfig = record
+ Name: string;
+ Input: integer;
+ ChannelToPlayerMap: array of integer;
+ end;
+
+type
+
+//Options
+
+ TVisualizerOption = (voOff, voWhenNoVideo, voOn);
+ TBackgroundMusicOption = (bmoOff, bmoOn);
+ TIni = class
+ private
+ function RemoveFileExt(FullName: string): string;
+ function ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
+ function GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
+ function GetArrayIndex(const SearchArray: array of string; Value: string; CaseInsensitiv: Boolean = False): integer;
+ function ReadArrayIndex(const SearchArray: array of string; IniFile: TCustomIniFile;
+ IniSection: string; IniProperty: string; Default: integer): integer;
+
+ procedure LoadInputDeviceCfg(IniFile: TMemIniFile);
+ procedure SaveInputDeviceCfg(IniFile: TIniFile);
+ procedure LoadThemes(IniFile: TCustomIniFile);
+ procedure LoadPaths(IniFile: TCustomIniFile);
+ procedure LoadScreenModes(IniFile: TCustomIniFile);
+
+ public
+ Name: array[0..11] of string;
+
+ // Templates for Names Mod
+ NameTeam: array[0..2] of string;
+ NameTemplate: array[0..11] of string;
+
+ //Filename of the opened iniFile
+ Filename: string;
+
+ // Game
+ Players: integer;
+ Difficulty: integer;
+ Language: integer;
+ Tabs: integer;
+ Tabs_at_startup:integer; //Tabs at Startup fix
+ Sorting: integer;
+ Debug: integer;
+
+ // Graphics
+ Screens: integer;
+ Resolution: integer;
+ Depth: integer;
+ VisualizerOption:integer;
+ FullScreen: integer;
+ TextureSize: integer;
+ SingWindow: integer;
+ Oscilloscope: integer;
+ Spectrum: integer;
+ Spectrograph: integer;
+ MovieSize: integer;
+
+ // Sound
+ MicBoost: integer;
+ ClickAssist: integer;
+ BeatClick: integer;
+ SavePlayback: integer;
+ ThresholdIndex: integer;
+ AudioOutputBufferSizeIndex:integer;
+ VoicePassthrough:integer;
+
+ //Song Preview
+ PreviewVolume: integer;
+ PreviewFading: integer;
+
+ // Lyrics
+ LyricsFont: integer;
+ LyricsEffect: integer;
+ Solmization: integer;
+ NoteLines: integer;
+
+ // Themes
+ Theme: integer;
+ SkinNo: integer;
+ Color: integer;
+ BackgroundMusicOption:integer;
+
+ // Record
+ InputDeviceConfig: array of TInputDeviceConfig;
+
+ // Advanced
+ LoadAnimation: integer;
+ EffectSing: integer;
+ ScreenFade: integer;
+ AskBeforeDel: integer;
+ OnSongClick: integer;
+ LineBonus: integer;
+ PartyPopup: integer;
+
+ // Controller
+ Joypad: integer;
+
+ procedure Load();
+ procedure Save();
+ procedure SaveNames;
+ procedure SaveLevel;
+ end;
+
+var
+ Ini: TIni;
+ IResolution: array of string;
+ ILanguage: array of string;
+ ITheme: array of string;
+ ISkin: array of string;
+
+
+
+const
+ IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
+ IPlayersVals: array[0..4] of integer = ( 1 , 2 , 3 , 4 , 6 );
+
+ IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
+ ITabs: array[0..1] of string = ('Off', 'On');
+
+ ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
+ sEdition = 0;
+ sGenre = 1;
+ sLanguage = 2;
+ sFolder = 3;
+ sTitle = 4;
+ sArtist = 5;
+ sTitle2 = 6;
+ sArtist2 = 7;
+
+ IDebug: array[0..1] of string = ('Off', 'On');
+
+ IScreens: array[0..1] of string = ('1', '2');
+ IFullScreen: array[0..1] of string = ('Off', 'On');
+ IDepth: array[0..1] of string = ('16 bit', '32 bit');
+ IVisualizer: array[0..2] of string = ('Off', 'WhenNoVideo','On');
+
+ IBackgroundMusic: array[0..1] of string = ('Off', 'On');
+
+
+ ITextureSize: array[0..2] of string = ('128', '256', '512');
+ ITextureSizeVals: array[0..2] of integer = ( 128, 256, 512);
+
+ ISingWindow: array[0..1] of string = ('Small', 'Big');
+
+ //SingBar Mod
+ IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
+//IOscilloscope: array[0..1] of string = ('Off', 'On');
+
+ ISpectrum: array[0..1] of string = ('Off', 'On');
+ ISpectrograph: array[0..1] of string = ('Off', 'On');
+ IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]');
+
+ IClickAssist: array[0..1] of string = ('Off', 'On');
+ IBeatClick: array[0..1] of string = ('Off', 'On');
+ ISavePlayback: array[0..1] of string = ('Off', 'On');
+
+ IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
+ IThresholdVals: array[0..3] of single = (0.05, 0.10, 0.15, 0.20);
+
+ IVoicePassthrough: array[0..1] of string = ('Off', 'On');
+
+ IAudioOutputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
+ IAudioOutputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
+
+ IAudioInputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
+ IAudioInputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
+
+ //Song Preview
+ IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%');
+ IPreviewVolumeVals: array[0..10] of single = ( 0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00 );
+
+ IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs');
+ IPreviewFadingVals: array[0..5] of integer = ( 0, 1, 2, 3, 4, 5 );
+
+
+ ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2');
+ ILyricsEffect: array[0..4] of string = ('Simple', 'Zoom', 'Slide', 'Ball', 'Shift');
+ ISolmization: array[0..3] of string = ('Off', 'Euro', 'Jap', 'American');
+ INoteLines: array[0..1] of string = ('Off', 'On');
+
+ IColor: array[0..8] of string = ('Blue', 'Green', 'Pink', 'Red', 'Violet', 'Orange', 'Yellow', 'Brown', 'Black');
+
+ // Advanced
+ ILoadAnimation: array[0..1] of string = ('Off', 'On');
+ IEffectSing: array[0..1] of string = ('Off', 'On');
+ IScreenFade: array[0..1] of string =('Off', 'On');
+ IAskbeforeDel: array[0..1] of string = ('Off', 'On');
+ IOnSongClick: array[0..2] of string = ('Sing', 'Select Players', 'Open Menu');
+ ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes');
+ IPartyPopup: array[0..1] of string = ('Off', 'On');
+
+ IJoypad: array[0..1] of string = ('Off', 'On');
+
+ // Recording options
+ IChannelPlayer: array[0..6] of string = ('Off', '1', '2', '3', '4', '5', '6');
+ IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
+
+implementation
+
+uses
+ StrUtils,
+ UMain,
+ SDL,
+ ULanguage,
+ UPlatform,
+ USkins,
+ URecord,
+ UCommandLine;
+
+(**
+ * Returns the filename without its fileextension
+ *)
+function TIni.RemoveFileExt(FullName: string): string;
+begin
+ Result := ChangeFileExt(FullName, '');
+end;
+
+(**
+ * Extracts an index of a key that is surrounded by a Prefix/Suffix pair.
+ * Example: ExtractKeyIndex('MyKey[1]', '[', ']') will return 1.
+ *)
+function TIni.ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
+var
+ Value: string;
+ Start: integer;
+begin
+ Result := -1;
+
+ if Pos(Prefix, Key) > -1 then
+ begin
+ Start := Pos(Prefix, Key) + Length(Prefix);
+
+ // copy all between prefix and suffix
+ Value := Copy(Key, Start, Pos(Suffix, Key)-1 - Start);
+ Result := StrToIntDef(Value, -1);
+ end;
+end;
+
+(**
+ * Finds the maximum key-index in a key-list.
+ * The indexes of the list are surrounded by Prefix/Suffix,
+ * e.g. MyKey[1] (Prefix='[', Suffix=']')
+ *)
+function TIni.GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
+var
+ i: integer;
+ KeyIndex: integer;
+begin
+ Result := -1;
+
+ for i := 0 to Keys.Count-1 do
+ begin
+ KeyIndex := ExtractKeyIndex(Keys[i], Prefix, Suffix);
+ if (KeyIndex > Result) then
+ Result := KeyIndex;
+ end;
+end;
+
+(**
+ * Returns the index of Value in SearchArray
+ * or -1 if Value is not in SearchArray.
+ *)
+function TIni.GetArrayIndex(const SearchArray: array of string; Value: string;
+ CaseInsensitiv: Boolean = False): integer;
+var
+ i: integer;
+begin
+ Result := -1;
+
+ for i := 0 to High(SearchArray) do
+ begin
+ if (SearchArray[i] = Value) or
+ (CaseInsensitiv and (UpperCase(SearchArray[i]) = UpperCase(Value))) then
+ begin
+ Result := i;
+ Break;
+ end;
+ end;
+end;
+
+(**
+ * Reads the property IniSeaction:IniProperty from IniFile and
+ * finds its corresponding index in SearchArray.
+ * If SearchArray does not contain the property value, the default value is
+ * returned.
+ *)
+function TIni.ReadArrayIndex(const SearchArray: array of string; IniFile: TCustomIniFile;
+ IniSection: string; IniProperty: string; Default: integer): integer;
+var
+ StrValue: string;
+begin
+ StrValue := IniFile.ReadString(IniSection, IniProperty, SearchArray[Default]);
+ Result := GetArrayIndex(SearchArray, StrValue);
+ if (Result = -1) then
+ begin
+ Result := Default;
+ end;
+end;
+
+
+procedure TIni.LoadInputDeviceCfg(IniFile: TMemIniFile);
+var
+ DeviceCfg: PInputDeviceConfig;
+ DeviceIndex: integer;
+ ChannelCount: integer;
+ ChannelIndex: integer;
+ RecordKeys: TStringList;
+ i: integer;
+begin
+ RecordKeys := TStringList.Create();
+
+ // read all record-keys for filtering
+ IniFile.ReadSection('Record', RecordKeys);
+
+ SetLength(InputDeviceConfig, 0);
+
+ for i := 0 to RecordKeys.Count-1 do
+ begin
+ // find next device-name
+ DeviceIndex := ExtractKeyIndex(RecordKeys[i], 'DeviceName[', ']');
+ if (DeviceIndex >= 0) then
+ begin
+ if not IniFile.ValueExists('Record', Format('DeviceName[%d]', [DeviceIndex])) then
+ break;
+
+ // resize list
+ SetLength(InputDeviceConfig, Length(InputDeviceConfig)+1);
+
+ // read an input device's config.
+ // Note: All devices are appended to the list whether they exist or not.
+ // Otherwise an external device's config will be lost if it is not
+ // connected (e.g. singstar mics or USB-Audio devices).
+ DeviceCfg := @InputDeviceConfig[High(InputDeviceConfig)];
+ DeviceCfg.Name := IniFile.ReadString('Record', Format('DeviceName[%d]', [DeviceIndex]), '');
+ DeviceCfg.Input := IniFile.ReadInteger('Record', Format('Input[%d]', [DeviceIndex]), 0);
+
+ // find the largest channel-number of the current device in the ini-file
+ ChannelCount := GetMaxKeyIndex(RecordKeys, 'Channel', Format('[%d]', [DeviceIndex]));
+ if (ChannelCount < 0) then
+ ChannelCount := 0;
+
+ SetLength(DeviceCfg.ChannelToPlayerMap, ChannelCount);
+
+ // read channel-to-player mapping for every channel of the current device
+ // or set non-configured channels to no player (=0).
+ for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
+ begin
+ DeviceCfg.ChannelToPlayerMap[ChannelIndex] :=
+ IniFile.ReadInteger('Record', Format('Channel%d[%d]', [ChannelIndex+1, DeviceIndex]), 0);
+ end;
+ end;
+ end;
+
+ RecordKeys.Free();
+
+ // MicBoost
+ //MicBoost := GetArrayIndex(IMicBoost, IniFile.ReadString('Record', 'MicBoost', 'Off'));
+ // Threshold
+ // ThresholdIndex := GetArrayIndex(IThreshold, IniFile.ReadString('Record', 'Threshold', IThreshold[1]));
+end;
+
+procedure TIni.SaveInputDeviceCfg(IniFile: TIniFile);
+var
+ DeviceIndex: integer;
+ ChannelIndex: integer;
+begin
+ for DeviceIndex := 0 to High(InputDeviceConfig) do
+ begin
+ // DeviceName and DeviceInput
+ IniFile.WriteString('Record', Format('DeviceName[%d]', [DeviceIndex+1]),
+ InputDeviceConfig[DeviceIndex].Name);
+ IniFile.WriteInteger('Record', Format('Input[%d]', [DeviceIndex+1]),
+ InputDeviceConfig[DeviceIndex].Input);
+
+ // Channel-to-Player Mapping
+ for ChannelIndex := 0 to High(InputDeviceConfig[DeviceIndex].ChannelToPlayerMap) do
+ begin
+ IniFile.WriteInteger('Record',
+ Format('Channel%d[%d]', [ChannelIndex+1, DeviceIndex+1]),
+ InputDeviceConfig[DeviceIndex].ChannelToPlayerMap[ChannelIndex]);
+ end;
+ end;
+
+ // MicBoost
+ //IniFile.WriteString('Record', 'MicBoost', IMicBoost[MicBoost]);
+ // Threshold
+ //IniFile.WriteString('Record', 'Threshold', IThreshold[ThresholdIndex]);
+end;
+
+procedure TIni.LoadPaths(IniFile: TCustomIniFile);
+var
+ PathStrings: TStringList;
+ I: integer;
+begin
+ PathStrings := TStringList.Create;
+ IniFile.ReadSection('Directories', PathStrings);
+
+ // Load song-paths
+ for I := 0 to PathStrings.Count-1 do
+ begin
+ if (AnsiStartsText('SongDir', PathStrings[I])) then
+ begin
+ AddSongPath(IniFile.ReadString('Directories', PathStrings[I], ''));
+ end;
+ end;
+
+ PathStrings.Free;
+end;
+
+procedure TIni.LoadThemes(IniFile: TCustomIniFile);
+var
+ SearchResult: TSearchRec;
+ ThemeIni: TMemIniFile;
+ ThemeName: string;
+ I: integer;
+begin
+ // Theme
+ SetLength(ITheme, 0);
+ Log.LogStatus('Searching for Theme : ' + ThemePath + '*.ini', 'Theme');
+
+ FindFirst(ThemePath + '*.ini',faAnyFile, SearchResult);
+ Repeat
+ Log.LogStatus('Found Theme: ' + SearchResult.Name, 'Theme');
+
+ //Read Themename from Theme
+ ThemeIni := TMemIniFile.Create(SearchResult.Name);
+ ThemeName := UpperCase(ThemeIni.ReadString('Theme','Name', RemoveFileExt(SearchResult.Name)));
+ ThemeIni.Free;
+
+ //Search for Skins for this Theme
+ for I := Low(Skin.Skin) to High(Skin.Skin) do
+ begin
+ if UpperCase(Skin.Skin[I].Theme) = ThemeName then
+ begin
+ SetLength(ITheme, Length(ITheme)+1);
+ ITheme[High(ITheme)] := RemoveFileExt(SearchResult.Name);
+ break;
+ end;
+ end;
+ until FindNext(SearchResult) <> 0;
+ FindClose(SearchResult);
+
+ // No Theme Found
+ if (Length(ITheme) = 0) then
+ begin
+ Log.CriticalError('Could not find any valid Themes.');
+ end;
+
+ Theme := GetArrayIndex(ITheme, IniFile.ReadString('Themes', 'Theme', 'DELUXE'), true);
+ if (Theme = -1) then
+ Theme := 0;
+
+ // Skin
+ Skin.onThemeChange;
+
+ SkinNo := GetArrayIndex(ISkin, IniFile.ReadString('Themes', 'Skin', ISkin[0]));
+end;
+
+procedure TIni.LoadScreenModes(IniFile: TCustomIniFile);
+
+ // swap two strings
+ procedure swap(var s1, s2: string);
+ var
+ s3: string;
+ begin
+ s3 := s1;
+ s1 := s2;
+ s2 := s3;
+ end;
+
+var
+ Modes: PPSDL_Rect;
+ I: integer;
+begin
+ // Screens
+ Screens := GetArrayIndex(IScreens, IniFile.ReadString('Graphics', 'Screens', IScreens[0]));
+
+ // FullScreen
+ FullScreen := GetArrayIndex(IFullScreen, IniFile.ReadString('Graphics', 'FullScreen', 'On'));
+
+ // Resolution
+ SetLength(IResolution, 0);
+
+ // Check if there are any modes available
+ // TODO: we should seperate windowed and fullscreen modes. Otherwise it is not
+ // possible to select a reasonable fullscreen mode when in windowed mode
+ if IFullScreen[FullScreen] = 'On' then
+ Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN or SDL_RESIZABLE)
+ else
+ Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_RESIZABLE) ;
+
+ if (Modes = nil) then
+ begin
+ Log.LogStatus( 'No resolutions Found' , 'Video');
+ end
+ else if (Modes = PPSDL_Rect(-1)) then
+ begin
+ // Fallback to some standard resolutions
+ SetLength(IResolution, 10);
+ IResolution[0] := '640x480';
+ IResolution[1] := '800x600';
+ IResolution[2] := '1024x768';
+ IResolution[3] := '1152x864';
+ IResolution[4] := '1280x800';
+ IResolution[5] := '1280x960';
+ IResolution[6] := '1400x1050';
+ IResolution[7] := '1440x900';
+ IResolution[8] := '1600x1200';
+ IResolution[9] := '1680x1050';
+
+ Resolution := GetArrayIndex(IResolution, IniFile.ReadString('Graphics', 'Resolution', '800x600'));
+ if Resolution = -1 then
+ begin
+ SetLength(IResolution, Length(IResolution) + 1);
+ IResolution[High(IResolution)] := IniFile.ReadString('Graphics', 'Resolution', '800x600');
+ Resolution := High(IResolution);
+ end;
+ end
+ else
+ begin
+ while assigned( Modes^ ) do //this should solve the biggest wine problem | THANKS Linnex (11.11.07)
+ begin
+ Log.LogStatus( 'Found Video Mode : ' + IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h) , 'Video');
+ SetLength(IResolution, Length(IResolution) + 1);
+ IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h);
+ Inc(Modes);
+ end;
+
+ // reverse order
+ for I := 0 to (Length(IResolution) div 2) - 1 do
+ begin
+ swap(IResolution[I], IResolution[High(IResolution)-I]);
+ end;
+ Resolution := GetArrayIndex(IResolution, IniFile.ReadString('Graphics', 'Resolution', '800x600'));
+
+ if Resolution = -1 then
+ begin
+ Resolution := GetArrayIndex(IResolution, '800x600');
+ if Resolution = -1 then
+ Resolution := 0;
+ end;
+ end;
+
+ // if no modes were set, then failback to 800x600
+ // as per http://sourceforge.net/forum/message.php?msg_id=4544965
+ // THANKS : linnex at users.sourceforge.net
+ if Length(IResolution) < 1 then
+ begin
+ Log.LogStatus( 'Found Video Mode : NONE !!! ( Defaulted to 800 x 600 )', 'Video');
+ SetLength(IResolution, 1);
+ IResolution[0] := '800x600';
+ Resolution := 0;
+ Log.LogStatus('SDL_ListModes Defaulted Res To : ' + IResolution[0] , 'Graphics - Resolutions');
+
+ // Default to fullscreen OFF, in this case !
+ FullScreen := 0;
+ end;
+
+ // Depth
+ Depth := GetArrayIndex(IDepth, IniFile.ReadString('Graphics', 'Depth', '32 bit'));
+end;
+
+procedure TIni.Load();
+var
+ IniFile: TMemIniFile;
+ I: integer;
+begin
+ GamePath := Platform.GetGameUserPath;
+
+ Log.LogStatus( 'GamePath : ' +GamePath , '' );
+
+ if (Params.ConfigFile <> '') then
+ try
+ FileName := Params.ConfigFile;
+ except
+ FileName := GamePath + 'config.ini';
+ end
+ else
+ FileName := GamePath + 'config.ini';
+
+ Log.LogStatus( 'Using config : ' + FileName , 'Ini');
+ IniFile := TMemIniFile.Create( FileName );
+
+ // Name
+ for I := 0 to 11 do
+ Name[I] := IniFile.ReadString('Name', 'P'+IntToStr(I+1), 'Player'+IntToStr(I+1));
+
+ // Templates for Names Mod
+ for I := 0 to 2 do
+ NameTeam[I] := IniFile.ReadString('NameTeam', 'T'+IntToStr(I+1), 'Team'+IntToStr(I+1));
+ for I := 0 to 11 do
+ NameTemplate[I] := IniFile.ReadString('NameTemplate', 'Name'+IntToStr(I+1), 'Template'+IntToStr(I+1));
+
+ // Players
+ Players := GetArrayIndex(IPlayers, IniFile.ReadString('Game', 'Players', IPlayers[0]));
+
+ // Difficulty
+ Difficulty := GetArrayIndex(IDifficulty, IniFile.ReadString('Game', 'Difficulty', 'Easy'));
+
+ // Language
+ Language := GetArrayIndex(ILanguage, IniFile.ReadString('Game', 'Language', 'English'));
+ //Language.ChangeLanguage(ILanguage[Language]);
+
+ // Tabs
+ Tabs := GetArrayIndex(ITabs, IniFile.ReadString('Game', 'Tabs', ITabs[0]));
+ Tabs_at_startup := Tabs; //Tabs at Startup fix
+
+ // Song Sorting
+ Sorting := GetArrayIndex(ISorting, IniFile.ReadString('Game', 'Sorting', ISorting[0]));
+
+ // Debug
+ Debug := GetArrayIndex(IDebug, IniFile.ReadString('Game', 'Debug', IDebug[0]));
+
+ LoadScreenModes(IniFile);
+
+ // TextureSize
+ TextureSize := GetArrayIndex(ITextureSize, IniFile.ReadString('Graphics', 'TextureSize', ITextureSize[1]));
+
+ // SingWindow
+ SingWindow := GetArrayIndex(ISingWindow, IniFile.ReadString('Graphics', 'SingWindow', 'Big'));
+
+ // Oscilloscope
+ Oscilloscope := GetArrayIndex(IOscilloscope, IniFile.ReadString('Graphics', 'Oscilloscope', 'Bar'));
+
+ // Spectrum
+ Spectrum := GetArrayIndex(ISpectrum, IniFile.ReadString('Graphics', 'Spectrum', 'Off'));
+
+ // Spectrograph
+ Spectrograph := GetArrayIndex(ISpectrograph, IniFile.ReadString('Graphics', 'Spectrograph', 'Off'));
+
+ // MovieSize
+ MovieSize := GetArrayIndex(IMovieSize, IniFile.ReadString('Graphics', 'MovieSize', IMovieSize[2]));
+
+ // ClickAssist
+ ClickAssist := GetArrayIndex(IClickAssist, IniFile.ReadString('Sound', 'ClickAssist', 'Off'));
+
+ // BeatClick
+ BeatClick := GetArrayIndex(IBeatClick, IniFile.ReadString('Sound', 'BeatClick', IBeatClick[0]));
+
+ // SavePlayback
+ SavePlayback := GetArrayIndex(ISavePlayback, IniFile.ReadString('Sound', 'SavePlayback', ISavePlayback[0]));
+
+ // AudioOutputBufferSize
+ AudioOutputBufferSizeIndex := ReadArrayIndex(IAudioOutputBufferSize, IniFile, 'Sound', 'AudioOutputBufferSize', 0);
+
+ //Preview Volume
+ PreviewVolume := GetArrayIndex(IPreviewVolume, IniFile.ReadString('Sound', 'PreviewVolume', IPreviewVolume[7]));
+
+ //Preview Fading
+ PreviewFading := GetArrayIndex(IPreviewFading, IniFile.ReadString('Sound', 'PreviewFading', IPreviewFading[1]));
+
+ //AudioRepeat aka VoicePassthrough
+ VoicePassthrough := GetArrayIndex(IVoicePassthrough, IniFile.ReadString('Sound', 'VoicePassthrough', IVoicePassthrough[0]));
+
+ // Lyrics Font
+ LyricsFont := GetArrayIndex(ILyricsFont, IniFile.ReadString('Lyrics', 'LyricsFont', ILyricsFont[1]));
+
+ // Lyrics Effect
+ LyricsEffect := GetArrayIndex(ILyricsEffect, IniFile.ReadString('Lyrics', 'LyricsEffect', ILyricsEffect[1]));
+
+ // Solmization
+ Solmization := GetArrayIndex(ISolmization, IniFile.ReadString('Lyrics', 'Solmization', ISolmization[0]));
+
+ // NoteLines
+ NoteLines := GetArrayIndex(INoteLines, IniFile.ReadString('Lyrics', 'NoteLines', INoteLines[1]));
+
+ LoadThemes(IniFile);
+
+ // Color
+ Color := GetArrayIndex(IColor, IniFile.ReadString('Themes', 'Color', IColor[0]));
+
+ LoadInputDeviceCfg(IniFile);
+
+ // LoadAnimation
+ LoadAnimation := GetArrayIndex(ILoadAnimation, IniFile.ReadString('Advanced', 'LoadAnimation', 'On'));
+
+ // ScreenFade
+ ScreenFade := GetArrayIndex(IScreenFade, IniFile.ReadString('Advanced', 'ScreenFade', 'On'));
+
+ // Visualizations
+ // this could be of use later..
+ // VisualizerOption :=
+ // TVisualizerOption(GetEnumValue(TypeInfo(TVisualizerOption),
+ // IniFile.ReadString('Graphics', 'Visualization', 'Off')));
+ // || VisualizerOption := TVisualizerOption(GetArrayIndex(IVisualizer, IniFile.ReadString('Graphics', 'Visualization', 'Off')));
+ VisualizerOption := GetArrayIndex(IVisualizer, IniFile.ReadString('Graphics', 'Visualization', 'Off'));
+
+{**
+ * Background music
+ *}
+ BackgroundMusicOption := GetArrayIndex(IBackgroundMusic, IniFile.ReadString('Sound', 'BackgroundMusic', 'Off'));
+
+ // EffectSing
+ EffectSing := GetArrayIndex(IEffectSing, IniFile.ReadString('Advanced', 'EffectSing', 'On'));
+
+ // AskbeforeDel
+ AskBeforeDel := GetArrayIndex(IAskbeforeDel, IniFile.ReadString('Advanced', 'AskbeforeDel', 'On'));
+
+ // OnSongClick
+ OnSongClick := GetArrayIndex(IOnSongClick, IniFile.ReadString('Advanced', 'OnSongClick', 'Sing'));
+
+ // Linebonus
+ LineBonus := GetArrayIndex(ILineBonus, IniFile.ReadString('Advanced', 'LineBonus', 'At Score'));
+
+ // PartyPopup
+ PartyPopup := GetArrayIndex(IPartyPopup, IniFile.ReadString('Advanced', 'PartyPopup', 'On'));
+
+ // Joypad
+ Joypad := GetArrayIndex(IJoypad, IniFile.ReadString('Controller', 'Joypad', IJoypad[0]));
+
+ LoadPaths(IniFile);
+
+ IniFile.Free;
+end;
+
+procedure TIni.Save;
+var
+ IniFile: TIniFile;
+begin
+ if (FileExists(Filename) and FileIsReadOnly(Filename)) then
+ begin
+ Log.LogError('Config-file is read-only', 'TIni.Save');
+ Exit;
+ end;
+
+ IniFile := TIniFile.Create(Filename);
+
+ // Players
+ IniFile.WriteString('Game', 'Players', IPlayers[Players]);
+
+ // Difficulty
+ IniFile.WriteString('Game', 'Difficulty', IDifficulty[Difficulty]);
+
+ // Language
+ IniFile.WriteString('Game', 'Language', ILanguage[Language]);
+
+ // Tabs
+ IniFile.WriteString('Game', 'Tabs', ITabs[Tabs]);
+
+ // Sorting
+ IniFile.WriteString('Game', 'Sorting', ISorting[Sorting]);
+
+ // Debug
+ IniFile.WriteString('Game', 'Debug', IDebug[Debug]);
+
+ // Screens
+ IniFile.WriteString('Graphics', 'Screens', IScreens[Screens]);
+
+ // FullScreen
+ IniFile.WriteString('Graphics', 'FullScreen', IFullScreen[FullScreen]);
+
+ // Visualization
+ IniFile.WriteString('Graphics', 'Visualization', IVisualizer[VisualizerOption]);
+
+ // Resolution
+ IniFile.WriteString('Graphics', 'Resolution', IResolution[Resolution]);
+
+ // Depth
+ IniFile.WriteString('Graphics', 'Depth', IDepth[Depth]);
+
+ // TextureSize
+ IniFile.WriteString('Graphics', 'TextureSize', ITextureSize[TextureSize]);
+
+ // Sing Window
+ IniFile.WriteString('Graphics', 'SingWindow', ISingWindow[SingWindow]);
+
+ // Oscilloscope
+ IniFile.WriteString('Graphics', 'Oscilloscope', IOscilloscope[Oscilloscope]);
+
+ // Spectrum
+ IniFile.WriteString('Graphics', 'Spectrum', ISpectrum[Spectrum]);
+
+ // Spectrograph
+ IniFile.WriteString('Graphics', 'Spectrograph', ISpectrograph[Spectrograph]);
+
+ // Movie Size
+ IniFile.WriteString('Graphics', 'MovieSize', IMovieSize[MovieSize]);
+
+ // ClickAssist
+ IniFile.WriteString('Sound', 'ClickAssist', IClickAssist[ClickAssist]);
+
+ // BeatClick
+ IniFile.WriteString('Sound', 'BeatClick', IBeatClick[BeatClick]);
+
+ // AudioOutputBufferSize
+ IniFile.WriteString('Sound', 'AudioOutputBufferSize', IAudioOutputBufferSize[AudioOutputBufferSizeIndex]);
+
+ // Background music
+ IniFile.WriteString('Sound', 'BackgroundMusic', IBackgroundMusic[BackgroundMusicOption]);
+
+ // Song Preview
+ IniFile.WriteString('Sound', 'PreviewVolume', IPreviewVolume[PreviewVolume]);
+
+ // PreviewFading
+ IniFile.WriteString('Sound', 'PreviewFading', IPreviewFading[PreviewFading]);
+
+ // SavePlayback
+ IniFile.WriteString('Sound', 'SavePlayback', ISavePlayback[SavePlayback]);
+
+ // VoicePasstrough
+ IniFile.WriteString('Sound', 'VoicePassthrough', IVoicePassthrough[VoicePassthrough]);
+
+ // Lyrics Font
+ IniFile.WriteString('Lyrics', 'LyricsFont', ILyricsFont[LyricsFont]);
+
+ // Lyrics Effect
+ IniFile.WriteString('Lyrics', 'LyricsEffect', ILyricsEffect[LyricsEffect]);
+
+ // Solmization
+ IniFile.WriteString('Lyrics', 'Solmization', ISolmization[Solmization]);
+
+ // NoteLines
+ IniFile.WriteString('Lyrics', 'NoteLines', INoteLines[NoteLines]);
+
+ // Theme
+ IniFile.WriteString('Themes', 'Theme', ITheme[Theme]);
+
+ // Skin
+ IniFile.WriteString('Themes', 'Skin', ISkin[SkinNo]);
+
+ // Color
+ IniFile.WriteString('Themes', 'Color', IColor[Color]);
+
+ SaveInputDeviceCfg(IniFile);
+
+ //LoadAnimation
+ IniFile.WriteString('Advanced', 'LoadAnimation', ILoadAnimation[LoadAnimation]);
+
+ //EffectSing
+ IniFile.WriteString('Advanced', 'EffectSing', IEffectSing[EffectSing]);
+
+ //ScreenFade
+ IniFile.WriteString('Advanced', 'ScreenFade', IScreenFade[ScreenFade]);
+
+ //AskbeforeDel
+ IniFile.WriteString('Advanced', 'AskbeforeDel', IAskbeforeDel[AskBeforeDel]);
+
+ //OnSongClick
+ IniFile.WriteString('Advanced', 'OnSongClick', IOnSongClick[OnSongClick]);
+
+ //Line Bonus
+ IniFile.WriteString('Advanced', 'LineBonus', ILineBonus[LineBonus]);
+
+ //Party Popup
+ IniFile.WriteString('Advanced', 'PartyPopup', IPartyPopup[PartyPopup]);
+
+ // Joypad
+ IniFile.WriteString('Controller', 'Joypad', IJoypad[Joypad]);
+
+ // Directories (add a template if section is missing)
+ if (not IniFile.SectionExists('Directories')) then
+ IniFile.WriteString('Directories', 'SongDir1', '');
+
+ IniFile.Free;
+end;
+
+procedure TIni.SaveNames;
+var
+ IniFile: TIniFile;
+ I: integer;
+begin
+ if not FileIsReadOnly(Filename) then
+ begin
+ IniFile := TIniFile.Create(Filename);
+
+ //Name Templates for Names Mod
+ for I := 1 to 12 do
+ IniFile.WriteString('Name', 'P' + IntToStr(I), Name[I-1]);
+ for I := 1 to 3 do
+ IniFile.WriteString('NameTeam', 'T' + IntToStr(I), NameTeam[I-1]);
+ for I := 1 to 12 do
+ IniFile.WriteString('NameTemplate', 'Name' + IntToStr(I), NameTemplate[I-1]);
+
+ IniFile.Free;
+ end;
+end;
+
+procedure TIni.SaveLevel;
+var
+ IniFile: TIniFile;
+begin
+ if not FileIsReadOnly(Filename) then
+ begin
+ IniFile := TIniFile.Create(Filename);
+
+ // Difficulty
+ IniFile.WriteString('Game', 'Difficulty', IDifficulty[Difficulty]);
+
+ IniFile.Free;
+ end;
+end;
+
+end.
diff --git a/src/Classes/UJoystick.pas b/src/Classes/UJoystick.pas
new file mode 100644
index 00000000..0ca7ba09
--- /dev/null
+++ b/src/Classes/UJoystick.pas
@@ -0,0 +1,282 @@
+unit UJoystick;
+
+interface
+
+{$I switches.inc}
+
+
+uses SDL;
+
+type
+ TJoyButton = record
+ State: integer;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyHatState = record
+ State: Boolean;
+ LastTick: Cardinal;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyUnit = record
+ Button: array[0..15] of TJoyButton;
+ HatState: Array[0..3] of TJoyHatState;
+ end;
+
+ TJoy = class
+ constructor Create;
+ procedure Update;
+ end;
+
+var
+ Joy: TJoy;
+ JoyUnit: TJoyUnit;
+ SDL_Joy: PSDL_Joystick;
+ JoyEvent: TSDL_Event;
+
+implementation
+
+uses SysUtils,
+ ULog;
+
+constructor TJoy.Create;
+var
+ B, N: integer;
+begin
+ inherited;
+
+ //Old Corvus5 Method
+ {// joystick support
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks <> 1 then
+ Log.LogStatus('Joystick count <> 1', 'TJoy.Create');
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then
+ Log.LogError('SDL_JoystickOpen failed', 'TJoy.Create');
+
+ if SDL_JoystickNumButtons(SDL_Joy) <> 16 then
+ Log.LogStatus('Joystick button count <> 16', 'TJoy.Create');
+
+// SDL_JoystickEventState(SDL_ENABLE);
+ // Events don't work - thay hang the whole application with SDL_JoystickEventState(SDL_ENABLE)
+
+ // clear states
+ for B := 0 to 15 do
+ JoyUnit.Button[B].State := 1;
+
+ // mapping
+ JoyUnit.Button[1].Enabled := true;
+ JoyUnit.Button[1].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[1].Sym := SDLK_RETURN;
+ JoyUnit.Button[2].Enabled := true;
+ JoyUnit.Button[2].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[2].Sym := SDLK_ESCAPE;
+
+ JoyUnit.Button[12].Enabled := true;
+ JoyUnit.Button[12].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[12].Sym := SDLK_LEFT;
+ JoyUnit.Button[13].Enabled := true;
+ JoyUnit.Button[13].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[13].Sym := SDLK_DOWN;
+ JoyUnit.Button[14].Enabled := true;
+ JoyUnit.Button[14].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[14].Sym := SDLK_RIGHT;
+ JoyUnit.Button[15].Enabled := true;
+ JoyUnit.Button[15].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[15].Sym := SDLK_UP;
+ }
+ //New Sarutas method
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks < 1 then
+ begin
+ Log.LogError('No Joystick found');
+ exit;
+ end;
+
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then
+ begin
+ Log.LogError('Could not Init Joystick');
+ exit;
+ end;
+ N := SDL_JoystickNumButtons(SDL_Joy);
+ //if N < 6 then Log.LogStatus('Joystick button count < 6', 'TJoy.Create');
+
+ for B := 0 to 5 do begin
+ JoyUnit.Button[B].Enabled := true;
+ JoyUnit.Button[B].State := 1;
+ JoyUnit.Button[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.Button[0].Sym := SDLK_Return;
+ JoyUnit.Button[1].Sym := SDLK_Escape;
+ JoyUnit.Button[2].Sym := SDLK_M;
+ JoyUnit.Button[3].Sym := SDLK_R;
+
+ JoyUnit.Button[4].Sym := SDLK_RETURN;
+ JoyUnit.Button[5].Sym := SDLK_ESCAPE;
+
+ //Set HatState
+ for B := 0 to 3 do begin
+ JoyUnit.HatState[B].Enabled := true;
+ JoyUnit.HatState[B].State := False;
+ JoyUnit.HatState[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.HatState[0].Sym := SDLK_UP;
+ JoyUnit.HatState[1].Sym := SDLK_RIGHT;
+ JoyUnit.HatState[2].Sym := SDLK_DOWN;
+ JoyUnit.HatState[3].Sym := SDLK_LEFT;
+end;
+
+procedure TJoy.Update;
+var
+ B: integer;
+ State: UInt8;
+ Tick: Cardinal;
+ Axes: Smallint;
+begin
+ SDL_JoystickUpdate;
+
+ //Manage Buttons
+ for B := 0 to 15 do begin
+ if (JoyUnit.Button[B].Enabled) and (JoyUnit.Button[B].State <> SDL_JoystickGetButton(SDL_Joy, B)) and (JoyUnit.Button[B].State = 0) then begin
+ JoyEvent.type_ := JoyUnit.Button[B].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.Button[B].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end;
+
+
+ for B := 0 to 15 do begin
+ JoyUnit.Button[B].State := SDL_JoystickGetButton(SDL_Joy, B);
+ end;
+
+ //Get Tick
+ Tick := SDL_GetTicks();
+
+ //Get CoolieHat
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) then
+ State := SDL_JoystickGetHat(SDL_Joy, 0)
+ else
+ State := 0;
+
+ //Get Axis
+ if (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+ //Down - Up (X- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 1);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Down
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_UP;
+
+ //Left - Right (Y- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 0);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Right
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_Left;
+ end;
+
+ //Manage Hat and joystick Events
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) OR (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+
+ //Up Button
+ If (JoyUnit.HatState[0].Enabled) and ((SDL_HAT_UP AND State) = SDL_HAT_UP) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[0].State = False) OR (JoyUnit.HatState[0].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[0].State then
+ JoyUnit.HatState[0].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[0].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[0].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[0].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[0].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[0].State := False;
+
+ //Right Button
+ If (JoyUnit.HatState[1].Enabled) and ((SDL_HAT_RIGHT AND State) = SDL_HAT_RIGHT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[1].State = False) OR (JoyUnit.HatState[1].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[1].State then
+ JoyUnit.HatState[1].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[1].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[1].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[1].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[1].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[1].State := False;
+
+ //Down button
+ If (JoyUnit.HatState[2].Enabled) and ((SDL_HAT_DOWN AND State) = SDL_HAT_DOWN) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[2].State = False) OR (JoyUnit.HatState[2].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[2].State then
+ JoyUnit.HatState[2].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[2].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[2].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[2].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[2].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[2].State := False;
+
+ //Left Button
+ If (JoyUnit.HatState[3].Enabled) and ((SDL_HAT_LEFT AND State) = SDL_HAT_LEFT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[3].State = False) OR (JoyUnit.HatState[3].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[3].State then
+ JoyUnit.HatState[3].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[3].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[3].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[3].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[3].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[3].State := False;
+ end;
+
+end;
+
+end.
diff --git a/src/Classes/ULCD.pas b/src/Classes/ULCD.pas
new file mode 100644
index 00000000..82f7ba2f
--- /dev/null
+++ b/src/Classes/ULCD.pas
@@ -0,0 +1,304 @@
+unit ULCD;
+
+interface
+
+{$I switches.inc}
+
+type
+ TLCD = class
+ private
+ Enabled: boolean;
+ Text: array[1..6] of string;
+ StartPos: integer;
+ LineBR: integer;
+ Position: integer;
+ procedure WriteCommand(B: byte);
+ procedure WriteData(B: byte);
+ procedure WriteString(S: string);
+ public
+ HalfInterface: boolean;
+ constructor Create;
+ procedure Enable;
+ procedure Clear;
+ procedure WriteText(Line: integer; S: string);
+ procedure MoveCursor(Line, Pos: integer);
+ procedure ShowCursor;
+ procedure HideCursor;
+
+ // for 2x16
+ procedure AddTextBR(S: string);
+ procedure MoveCursorBR(Pos: integer);
+ procedure ScrollUpBR;
+ procedure AddTextArray(Line:integer; S: string);
+ end;
+
+var
+ LCD: TLCD;
+
+const
+ Data = $378; // domyœlny adres portu
+ Status = Data + 1;
+ Control = Data + 2;
+
+implementation
+
+uses
+ SysUtils,
+ {$IFDEF UseSerialPort}
+ zlportio,
+ {$ENDIF}
+ SDL,
+ UTime;
+
+procedure TLCD.WriteCommand(B: Byte);
+// Wysylanie komend sterujacych
+begin
+{$IFDEF UseSerialPort}
+ if not HalfInterface then
+ begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $03);
+ end
+ else
+ begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $03);
+
+ SDL_Delay( 100 );
+
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $03);
+ end;
+
+ if (B=1) or (B=2) then
+ Sleep(2)
+ else
+ SDL_Delay( 100 );
+{$ENDIF}
+end;
+
+procedure TLCD.WriteData(B: Byte);
+// Wysylanie danych
+begin
+{$IFDEF UseSerialPort}
+ if not HalfInterface then
+ begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $07);
+ end
+ else
+ begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $07);
+
+ SDL_Delay( 100 );
+
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $07);
+ end;
+
+ SDL_Delay( 100 );
+ Inc(Position);
+{$ENDIF}
+end;
+
+procedure TLCD.WriteString(S: string);
+// Wysylanie slow
+var
+ I: integer;
+begin
+ for I := 1 to Length(S) do
+ WriteData(Ord(S[I]));
+end;
+
+constructor TLCD.Create;
+begin
+ inherited;
+end;
+
+procedure TLCD.Enable;
+{var
+ A: byte;
+ B: byte;}
+begin
+ Enabled := true;
+ if not HalfInterface then
+ WriteCommand($38)
+ else begin
+ WriteCommand($33);
+ WriteCommand($32);
+ WriteCommand($28);
+ end;
+
+// WriteCommand($06);
+// WriteCommand($0C);
+// sleep(10);
+end;
+
+procedure TLCD.Clear;
+begin
+ if Enabled then begin
+ WriteCommand(1);
+ WriteCommand(2);
+ Text[1] := '';
+ Text[2] := '';
+ Text[3] := '';
+ Text[4] := '';
+ Text[5] := '';
+ Text[6] := '';
+ StartPos := 1;
+ LineBR := 1;
+ end;
+end;
+
+procedure TLCD.WriteText(Line: integer; S: string);
+begin
+ if Enabled then begin
+ if Line <= 2 then begin
+ MoveCursor(Line, 1);
+ WriteString(S);
+ end;
+
+ Text[Line] := '';
+ AddTextArray(Line, S);
+ end;
+end;
+
+procedure TLCD.MoveCursor(Line, Pos: integer);
+var
+ I: integer;
+begin
+ if Enabled then begin
+ Pos := Pos + (Line-1) * 40;
+
+ if Position > Pos then begin
+ WriteCommand(2);
+ for I := 1 to Pos-1 do
+ WriteCommand(20);
+ end;
+
+ if Position < Pos then
+ for I := 1 to Pos - Position do
+ WriteCommand(20);
+
+ Position := Pos;
+ end;
+end;
+
+procedure TLCD.ShowCursor;
+begin
+ if Enabled then begin
+ WriteCommand(14);
+ end;
+end;
+
+procedure TLCD.HideCursor;
+begin
+ if Enabled then begin
+ WriteCommand(12);
+ end;
+end;
+
+procedure TLCD.AddTextBR(S: string);
+var
+ Word: string;
+// W: integer;
+ P: integer;
+ L: integer;
+begin
+ if Enabled then begin
+ if LineBR <= 6 then begin
+ L := LineBR;
+ P := Pos(' ', S);
+
+ if L <= 2 then
+ MoveCursor(L, 1);
+
+ while (L <= 6) and (P > 0) do begin
+ Word := Copy(S, 1, P);
+ if (Length(Text[L]) + Length(Word)-1) > 16 then begin
+ L := L + 1;
+ if L <= 2 then
+ MoveCursor(L, 1);
+ end;
+
+ if L <= 6 then begin
+ if L <= 2 then
+ WriteString(Word);
+ AddTextArray(L, Word);
+ end;
+
+ Delete(S, 1, P);
+ P := Pos(' ', S)
+ end;
+
+ LineBR := L + 1;
+ end;
+ end;
+end;
+
+procedure TLCD.MoveCursorBR(Pos: integer);
+{var
+ I: integer;
+ L: integer;}
+begin
+ if Enabled then begin
+ Pos := Pos - (StartPos-1);
+ if Pos <= Length(Text[1]) then
+ MoveCursor(1, Pos);
+
+ if Pos > Length(Text[1]) then begin
+ // bez zawijania
+// Pos := Pos - Length(Text[1]);
+// MoveCursor(2, Pos);
+
+ // z zawijaniem
+ Pos := Pos - Length(Text[1]);
+ ScrollUpBR;
+ MoveCursor(1, Pos);
+ end;
+ end;
+end;
+
+procedure TLCD.ScrollUpBR;
+var
+ T: array[1..5] of string;
+ SP: integer;
+ LBR: integer;
+begin
+ if Enabled then begin
+ T[1] := Text[2];
+ T[2] := Text[3];
+ T[3] := Text[4];
+ T[4] := Text[5];
+ T[5] := Text[6];
+ SP := StartPos + Length(Text[1]);
+ LBR := LineBR;
+
+ Clear;
+
+ StartPos := SP;
+ WriteText(1, T[1]);
+ WriteText(2, T[2]);
+ WriteText(3, T[3]);
+ WriteText(4, T[4]);
+ WriteText(5, T[5]);
+ LineBR := LBR-1;
+ end;
+end;
+
+procedure TLCD.AddTextArray(Line: integer; S: string);
+begin
+ if Enabled then begin
+ Text[Line] := Text[Line] + S;
+ end;
+end;
+
+end.
+
diff --git a/src/Classes/ULanguage.pas b/src/Classes/ULanguage.pas
new file mode 100644
index 00000000..d534b4e1
--- /dev/null
+++ b/src/Classes/ULanguage.pas
@@ -0,0 +1,240 @@
+unit ULanguage;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+type
+ TLanguageEntry = record
+ ID: string;
+ Text: string;
+ end;
+
+ TLanguageList = record
+ Name: string;
+ {FileName: string; }
+ end;
+
+ TLanguage = class
+ public
+ Entry: array of TLanguageEntry; //Entrys of Chosen Language
+ SEntry: array of TLanguageEntry; //Entrys of Standard Language
+ CEntry: array of TLanguageEntry; //Constant Entrys e.g. Version
+ Implode_Glue1, Implode_Glue2: String;
+ public
+ List: array of TLanguageList;
+
+ constructor Create;
+ procedure LoadList;
+ function Translate(Text: String): String;
+ procedure ChangeLanguage(Language: String);
+ procedure AddConst(ID, Text: String);
+ procedure ChangeConst(ID, Text: String);
+ function Implode(Pieces: Array of String): String;
+ end;
+
+var
+ Language: TLanguage;
+
+implementation
+
+uses UMain,
+ // UFiles,
+ UIni,
+ IniFiles,
+ Classes,
+ SysUtils,
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ ULog;
+
+//----------
+//Create - Construct Class then LoadList + Standard Language + Set Standard Implode Glues
+//----------
+constructor TLanguage.Create;
+var
+ I, J: Integer;
+begin
+ inherited;
+
+ LoadList;
+
+ //Set Implode Glues for Backward Compatibility
+ Implode_Glue1 := ', ';
+ Implode_Glue2 := ' and ';
+
+ if (Length(List) = 0) then //No Language Files Loaded -> Abort Loading
+ Log.CriticalError('Could not load any Language File');
+
+ //Standard Language (If a Language File is Incomplete)
+ //Then use English Language
+ for I := 0 to high(List) do //Search for English Language
+ begin
+ //English Language Found -> Load
+ if Uppercase(List[I].Name) = 'ENGLISH' then
+ begin
+ ChangeLanguage('English');
+
+ SetLength(SEntry, Length(Entry));
+ for J := low(Entry) to high(Entry) do
+ SEntry[J] := Entry[J];
+
+ SetLength(Entry, 0);
+
+ Break;
+ end;
+
+ if (I = high(List)) then
+ Log.LogError('English Languagefile missing! No standard Translation loaded');
+ end;
+ //Standard Language END
+
+end;
+
+//----------
+//LoadList - Parse the Language Dir searching Translations
+//----------
+procedure TLanguage.LoadList;
+var
+ SR: TSearchRec; // for parsing directory
+begin
+ SetLength(List, 0);
+ SetLength(ILanguage, 0);
+
+ if FindFirst(LanguagesPath + '*.ini', 0, SR) = 0 then begin
+ repeat
+ SetLength(List, Length(List)+1);
+ SetLength(ILanguage, Length(ILanguage)+1);
+ SR.Name := ChangeFileExt(SR.Name, '');
+
+ List[High(List)].Name := SR.Name;
+ ILanguage[High(ILanguage)] := SR.Name;
+
+ until FindNext(SR) <> 0;
+ SysUtils.FindClose(SR);
+ end; // if FindFirst
+end;
+
+//----------
+//ChangeLanguage - Load the specified LanguageFile
+//----------
+procedure TLanguage.ChangeLanguage(Language: String);
+var
+ IniFile: TIniFile;
+ E: integer; // entry
+ S: TStringList;
+begin
+ SetLength(Entry, 0);
+ IniFile := TIniFile.Create(LanguagesPath + Language + '.ini');
+ S := TStringList.Create;
+
+ IniFile.ReadSectionValues('Text', S);
+ SetLength(Entry, S.Count);
+ for E := 0 to high(Entry) do
+ begin
+ if S.Names[E] = 'IMPLODE_GLUE1' then
+ Implode_Glue1 := S.ValueFromIndex[E]+ ' '
+ else if S.Names[E] = 'IMPLODE_GLUE2' then
+ Implode_Glue2 := ' ' + S.ValueFromIndex[E] + ' ';
+
+ Entry[E].ID := S.Names[E];
+ Entry[E].Text := S.ValueFromIndex[E];
+ end;
+
+ S.Free;
+ IniFile.Free;
+end;
+
+//----------
+//Translate - Translate the Text
+//----------
+Function TLanguage.Translate(Text: String): String;
+var
+ E: integer; // entry
+begin
+ Result := Text;
+ Text := Uppercase(Result);
+
+ //Const Mod
+ for E := 0 to high(CEntry) do
+ if Text = CEntry[E].ID then
+ begin
+ Result := CEntry[E].Text;
+ exit;
+ end;
+ //Const Mod End
+
+ for E := 0 to high(Entry) do
+ if Text = Entry[E].ID then
+ begin
+ Result := Entry[E].Text;
+ exit;
+ end;
+
+ //Standard Language (If a Language File is Incomplete)
+ //Then use Standard Language
+ for E := low(SEntry) to high(SEntry) do
+ if Text = SEntry[E].ID then
+ begin
+ Result := SEntry[E].Text;
+ Break;
+ end;
+ //Standard Language END
+end;
+
+//----------
+//AddConst - Add a Constant ID that will be Translated but not Loaded from the LanguageFile
+//----------
+procedure TLanguage.AddConst (ID, Text: String);
+begin
+ SetLength (CEntry, Length(CEntry) + 1);
+ CEntry[high(CEntry)].ID := ID;
+ CEntry[high(CEntry)].Text := Text;
+end;
+
+//----------
+//ChangeConst - Change a Constant Value by ID
+//----------
+procedure TLanguage.ChangeConst(ID, Text: String);
+var
+ I: Integer;
+begin
+ for I := 0 to high(CEntry) do
+ begin
+ if CEntry[I].ID = ID then
+ begin
+ CEntry[I].Text := Text;
+ Break;
+ end;
+ end;
+end;
+
+//----------
+//Implode - Connect an Array of Strings with ' and ' or ', ' to one String
+//----------
+function TLanguage.Implode(Pieces: Array of String): String;
+var
+ I: Integer;
+begin
+ Result := '';
+ //Go through Pieces
+ for I := low(Pieces) to high(Pieces) do
+ begin
+ //Add Value
+ Result := Result + Pieces[I];
+
+ //Add Glue
+ if (I < high(Pieces) - 1) then
+ Result := Result + Implode_Glue1
+ else if (I < high(Pieces)) then
+ Result := Result + Implode_Glue2;
+ end;
+end;
+
+end.
diff --git a/src/Classes/ULight.pas b/src/Classes/ULight.pas
new file mode 100644
index 00000000..a0a399ab
--- /dev/null
+++ b/src/Classes/ULight.pas
@@ -0,0 +1,145 @@
+unit ULight;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+type
+ TLight = class
+ private
+ Enabled: boolean;
+ Light: array[0..7] of boolean;
+ LightTime: array[0..7] of real; // time to stop, need to call update to change state
+ LastTime: real;
+ public
+ constructor Create;
+ procedure Enable;
+ procedure SetState(State: integer);
+ procedure AutoSetState;
+ procedure TurnOn;
+ procedure TurnOff;
+ procedure LightOne(Number: integer; Time: real);
+ procedure Refresh;
+ end;
+
+var
+ Light: TLight;
+
+const
+ Data = $378; // default port address
+ Status = Data + 1;
+ Control = Data + 2;
+
+implementation
+
+uses
+ SysUtils,
+ {$IFDEF UseSerialPort}
+ zlportio,
+ {$ENDIF}
+ UTime;
+
+{$IFDEF FPC}
+
+ function GetTime: TDateTime;
+ var
+ SystemTime: TSystemTime;
+ begin
+ GetLocalTime(SystemTime);
+ with SystemTime do
+ begin
+ {$IFDEF UNIX}
+ Result := EncodeTime(Hour, Minute, Second, MilliSecond);
+ {$ELSE}
+ Result := EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
+ {$ENDIF}
+ end;
+ end;
+
+{$ENDIF}
+
+
+constructor TLight.Create;
+begin
+ inherited;
+ Enabled := false;
+end;
+
+procedure TLight.Enable;
+begin
+ Enabled := true;
+ LastTime := GetTime;
+end;
+
+procedure TLight.SetState(State: integer);
+begin
+ {$IFDEF UseSerialPort}
+ if Enabled then
+ PortWriteB($378, State);
+ {$ENDIF}
+end;
+
+procedure TLight.AutoSetState;
+var
+ State: integer;
+begin
+ if Enabled then begin
+ State := 0;
+ if Light[0] then State := State + 2;
+ if Light[1] then State := State + 1;
+ // etc
+ SetState(State);
+ end;
+end;
+
+procedure TLight.TurnOn;
+begin
+ if Enabled then
+ SetState(3);
+end;
+
+procedure TLight.TurnOff;
+begin
+ if Enabled then
+ SetState(0);
+end;
+
+procedure TLight.LightOne(Number: integer; Time: real);
+begin
+ if Enabled then begin
+ if Light[Number] = false then begin
+ Light[Number] := true;
+ AutoSetState;
+ end;
+
+ LightTime[Number] := GetTime + Time/1000; // [s]
+ end;
+end;
+
+procedure TLight.Refresh;
+var
+ Time: real;
+ L: integer;
+begin
+ if Enabled then begin
+ Time := GetTime;
+ for L := 0 to 7 do begin
+ if Light[L] = true then begin
+ if LightTime[L] > Time then begin
+ end else begin
+ Light[L] := false;
+ end;
+ end;
+ end;
+ LastTime := Time;
+ AutoSetState;
+ end;
+end;
+
+end.
+
+
diff --git a/src/Classes/ULog.pas b/src/Classes/ULog.pas
new file mode 100644
index 00000000..a9a2f3c4
--- /dev/null
+++ b/src/Classes/ULog.pas
@@ -0,0 +1,417 @@
+unit ULog;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes;
+
+(*
+ * LOG_LEVEL_[TYPE] defines the "minimum" index for logs of type TYPE. Each
+ * level greater than this BUT less or equal than LOG_LEVEL_[TYPE]_MAX is of this type.
+ * This means a level "LOG_LEVEL_ERROR >= Level <= LOG_LEVEL_ERROR_MAX" e.g.
+ * "Level := LOG_LEVEL_ERROR+2" is considered an error level.
+ * This is nice for debugging if you have more or less important debug messages.
+ * For example you can assign LOG_LEVEL_DEBUG+10 for the more important ones and
+ * LOG_LEVEL_DEBUG+20 for less important ones and so on. By changing the log-level
+ * you can hide the less important ones.
+ *)
+const
+ LOG_LEVEL_DEBUG_MAX = MaxInt;
+ LOG_LEVEL_DEBUG = 50;
+ LOG_LEVEL_INFO_MAX = LOG_LEVEL_DEBUG-1;
+ LOG_LEVEL_INFO = 40;
+ LOG_LEVEL_STATUS_MAX = LOG_LEVEL_INFO-1;
+ LOG_LEVEL_STATUS = 30;
+ LOG_LEVEL_WARN_MAX = LOG_LEVEL_STATUS-1;
+ LOG_LEVEL_WARN = 20;
+ LOG_LEVEL_ERROR_MAX = LOG_LEVEL_WARN-1;
+ LOG_LEVEL_ERROR = 10;
+ LOG_LEVEL_CRITICAL_MAX = LOG_LEVEL_ERROR-1;
+ LOG_LEVEL_CRITICAL = 0;
+ LOG_LEVEL_NONE = -1;
+
+ // define level that Log(File)Level is initialized with
+ LOG_LEVEL_DEFAULT = LOG_LEVEL_WARN;
+ LOG_FILE_LEVEL_DEFAULT = LOG_LEVEL_ERROR;
+
+type
+ TLog = class
+ private
+ LogFile: TextFile;
+ LogFileOpened: boolean;
+ BenchmarkFile: TextFile;
+ BenchmarkFileOpened: boolean;
+
+ LogLevel: integer;
+ // level of messages written to the log-file
+ LogFileLevel: integer;
+
+ procedure LogToFile(const Text: string);
+ public
+ BenchmarkTimeStart: array[0..31] of real;
+ BenchmarkTimeLength: array[0..31] of real;//TDateTime;
+
+ Title: String; //Application Title
+
+ // Write log message to log-file
+ FileOutputEnabled: Boolean;
+
+ constructor Create;
+
+ // destuctor
+ destructor Destroy; override;
+
+ // benchmark
+ procedure BenchmarkStart(Number: integer);
+ procedure BenchmarkEnd(Number: integer);
+ procedure LogBenchmark(const Text: string; Number: integer);
+
+ procedure SetLogLevel(Level: integer);
+ function GetLogLevel(): integer;
+
+ procedure LogMsg(const Text: string; Level: integer); overload;
+ procedure LogMsg(const Msg, Context: string; Level: integer); overload; {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogDebug(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogInfo(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogStatus(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogWarn(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogError(const Text: string); overload; {$IFDEF HasInline}inline;{$ENDIF}
+ procedure LogError(const Msg, Context: string); overload; {$IFDEF HasInline}inline;{$ENDIF}
+ //Critical Error (Halt + MessageBox)
+ procedure LogCritical(const Msg, Context: string); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure CriticalError(const Text: string); {$IFDEF HasInline}inline;{$ENDIF}
+
+ // voice
+ procedure LogVoice(SoundNr: integer);
+ // buffer
+ procedure LogBuffer(const buf : Pointer; const bufLength : Integer; const filename : string);
+ end;
+
+procedure DebugWriteln(const aString: String);
+
+var
+ Log: TLog;
+
+implementation
+
+uses
+ SysUtils,
+ DateUtils,
+ URecord,
+ UMain,
+ UTime,
+ UCommon,
+ UCommandLine;
+
+(*
+ * Write to console if in debug mode (Thread-safe).
+ * If debug-mode is disabled nothing is done.
+ *)
+procedure DebugWriteln(const aString: string);
+begin
+ {$IFNDEF DEBUG}
+ if Params.Debug then
+ begin
+ {$ENDIF}
+ ConsoleWriteLn(aString);
+ {$IFNDEF DEBUG}
+ end;
+ {$ENDIF}
+end;
+
+
+constructor TLog.Create;
+begin
+ inherited;
+ LogLevel := LOG_LEVEL_DEFAULT;
+ LogFileLevel := LOG_FILE_LEVEL_DEFAULT;
+ FileOutputEnabled := true;
+end;
+
+destructor TLog.Destroy;
+begin
+ if BenchmarkFileOpened then
+ CloseFile(BenchmarkFile);
+ //if AnalyzeFileOpened then
+ // CloseFile(AnalyzeFile);
+ if LogFileOpened then
+ CloseFile(LogFile);
+ inherited;
+end;
+
+procedure TLog.BenchmarkStart(Number: integer);
+begin
+ BenchmarkTimeStart[Number] := USTime.GetTime; //Time;
+end;
+
+procedure TLog.BenchmarkEnd(Number: integer);
+begin
+ BenchmarkTimeLength[Number] := USTime.GetTime {Time} - BenchmarkTimeStart[Number];
+end;
+
+procedure TLog.LogBenchmark(const Text: string; Number: integer);
+var
+ Minutes: integer;
+ Seconds: integer;
+ Miliseconds: integer;
+
+ MinutesS: string;
+ SecondsS: string;
+ MilisecondsS: string;
+
+ ValueText: string;
+begin
+ if (FileOutputEnabled and Params.Benchmark) then
+ begin
+ if not BenchmarkFileOpened then
+ begin
+ BenchmarkFileOpened := true;
+ AssignFile(BenchmarkFile, LogPath + 'Benchmark.log');
+ {$I-}
+ Rewrite(BenchmarkFile);
+ if IOResult = 0 then
+ BenchmarkFileOpened := true;
+ {$I+}
+
+ //If File is opened write Date to Benchmark File
+ If (BenchmarkFileOpened) then
+ begin
+ WriteLn(BenchmarkFile, Title + ' Benchmark File');
+ WriteLn(BenchmarkFile, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
+ WriteLn(BenchmarkFile, '-------------------');
+
+ Flush(BenchmarkFile);
+ end;
+ end;
+
+ if BenchmarkFileOpened then
+ begin
+ Miliseconds := Trunc(Frac(BenchmarkTimeLength[Number]) * 1000);
+ Seconds := Trunc(BenchmarkTimeLength[Number]) mod 60;
+ Minutes := Trunc((BenchmarkTimeLength[Number] - Seconds) / 60);
+ //ValueText := FloatToStr(BenchmarkTimeLength[Number]);
+
+ {
+ ValueText := FloatToStr(SecondOf(BenchmarkTimeLength[Number]) +
+ MilliSecondOf(BenchmarkTimeLength[Number])/1000);
+ if MinuteOf(BenchmarkTimeLength[Number]) >= 1 then
+ ValueText := IntToStr(MinuteOf(BenchmarkTimeLength[Number])) + ':' + ValueText;
+ WriteLn(FileBenchmark, Text + ': ' + ValueText + ' seconds');
+ }
+
+ if (Minutes = 0) and (Seconds = 0) then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ ValueText := MilisecondsS + ' miliseconds';
+ end;
+
+ if (Minutes = 0) and (Seconds >= 1) then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ while Length(MilisecondsS) < 3 do
+ MilisecondsS := '0' + MilisecondsS;
+
+ SecondsS := IntToStr(Seconds);
+
+ ValueText := SecondsS + ',' + MilisecondsS + ' seconds';
+ end;
+
+ if Minutes >= 1 then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ while Length(MilisecondsS) < 3 do
+ MilisecondsS := '0' + MilisecondsS;
+
+ SecondsS := IntToStr(Seconds);
+ while Length(SecondsS) < 2 do
+ SecondsS := '0' + SecondsS;
+
+ MinutesS := IntToStr(Minutes);
+
+ ValueText := MinutesS + ':' + SecondsS + ',' + MilisecondsS + ' minutes';
+ end;
+
+ WriteLn(BenchmarkFile, Text + ': ' + ValueText);
+ Flush(BenchmarkFile);
+ end;
+ end;
+end;
+
+procedure TLog.LogToFile(const Text: string);
+begin
+ if (FileOutputEnabled and not LogFileOpened) then
+ begin
+ AssignFile(LogFile, LogPath + 'Error.log');
+ {$I-}
+ Rewrite(LogFile);
+ if IOResult = 0 then
+ LogFileOpened := true;
+ {$I+}
+
+ //If File is opened write Date to Error File
+ if (LogFileOpened) then
+ begin
+ WriteLn(LogFile, Title + ' Error Log');
+ WriteLn(LogFile, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
+ WriteLn(LogFile, '-------------------');
+
+ Flush(LogFile);
+ end;
+ end;
+
+ if LogFileOpened then
+ begin
+ try
+ WriteLn(LogFile, Text);
+ Flush(LogFile);
+ except
+ LogFileOpened := false;
+ end;
+ end;
+end;
+
+procedure TLog.SetLogLevel(Level: integer);
+begin
+ LogLevel := Level;
+end;
+
+function TLog.GetLogLevel(): integer;
+begin
+ Result := LogLevel;
+end;
+
+procedure TLog.LogMsg(const Text: string; Level: integer);
+var
+ LogMsg: string;
+begin
+ // TODO: what if (LogFileLevel < LogLevel)? Log to file without printing to
+ // console or do not log at all? At the moment nothing is logged.
+ if (Level <= LogLevel) then
+ begin
+ if (Level <= LOG_LEVEL_CRITICAL_MAX) then
+ LogMsg := 'CRITICAL: ' + Text
+ else if (Level <= LOG_LEVEL_ERROR_MAX) then
+ LogMsg := 'ERROR: ' + Text
+ else if (Level <= LOG_LEVEL_WARN_MAX) then
+ LogMsg := 'WARN: ' + Text
+ else if (Level <= LOG_LEVEL_STATUS_MAX) then
+ LogMsg := 'STATUS: ' + Text
+ else if (Level <= LOG_LEVEL_INFO_MAX) then
+ LogMsg := 'INFO: ' + Text
+ else
+ LogMsg := 'DEBUG: ' + Text;
+
+ // output log-message
+ if (Level <= LogLevel) then
+ begin
+ DebugWriteLn(LogMsg);
+ end;
+
+ // write message to log-file
+ if (Level <= LogFileLevel) then
+ begin
+ LogToFile(LogMsg);
+ end;
+ end;
+
+ // exit application on criticial errors (cannot be turned off)
+ if (Level <= LOG_LEVEL_CRITICAL_MAX) then
+ begin
+ // Show information (window)
+ ShowMessage(Text, mtError);
+ Halt;
+ end;
+end;
+
+procedure TLog.LogMsg(const Msg, Context: string; Level: integer);
+begin
+ LogMsg(Msg + ' ['+Context+']', Level);
+end;
+
+procedure TLog.LogDebug(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_DEBUG);
+end;
+
+procedure TLog.LogInfo(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_INFO);
+end;
+
+procedure TLog.LogStatus(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_STATUS);
+end;
+
+procedure TLog.LogWarn(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_WARN);
+end;
+
+procedure TLog.LogError(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_ERROR);
+end;
+
+procedure TLog.LogError(const Text: string);
+begin
+ LogMsg(Text, LOG_LEVEL_ERROR);
+end;
+
+procedure TLog.CriticalError(const Text: string);
+begin
+ LogMsg(Text, LOG_LEVEL_CRITICAL);
+end;
+
+procedure TLog.LogCritical(const Msg, Context: string);
+begin
+ LogMsg(Msg, Context, LOG_LEVEL_CRITICAL);
+end;
+
+procedure TLog.LogVoice(SoundNr: integer);
+var
+ FS: TFileStream;
+ FileName: string;
+ Num: integer;
+begin
+ for Num := 1 to 9999 do begin
+ FileName := IntToStr(Num);
+ while Length(FileName) < 4 do
+ FileName := '0' + FileName;
+ FileName := LogPath + 'Voice' + FileName + '.raw';
+ if not FileExists(FileName) then
+ break
+ end;
+
+ FS := TFileStream.Create(FileName, fmCreate);
+
+ AudioInputProcessor.Sound[SoundNr].LogBuffer.Seek(0, soBeginning);
+ FS.CopyFrom(AudioInputProcessor.Sound[SoundNr].LogBuffer, AudioInputProcessor.Sound[SoundNr].LogBuffer.Size);
+
+ FS.Free;
+end;
+
+procedure TLog.LogBuffer(const buf: Pointer; const bufLength: Integer; const filename: string);
+var
+ f : TFileStream;
+begin
+ f := nil;
+
+ try
+ f := TFileStream.Create( filename, fmCreate);
+ f.Write( buf^, bufLength);
+ f.Free;
+ except
+ on e : Exception do begin
+ Log.LogError('TLog.LogBuffer: Failed to log buffer into file "' + filename + '". ErrMsg: ' + e.Message);
+ f.Free;
+ end;
+ end;
+end;
+
+end.
+
+
diff --git a/src/Classes/ULyrics.pas b/src/Classes/ULyrics.pas
new file mode 100644
index 00000000..305cb91f
--- /dev/null
+++ b/src/Classes/ULyrics.pas
@@ -0,0 +1,884 @@
+unit ULyrics;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ gl,
+ glext,
+ UTexture,
+ UThemes,
+ UMusic;
+
+type
+ // stores two textures for enabled/disabled states
+ TPlayerIconTex = array [0..1] of TTexture;
+
+ PLyricWord = ^TLyricWord;
+ TLyricWord = record
+ X: Real; // left corner
+ Width: Real; // width
+ Start: Cardinal; // start of the word in quarters (beats)
+ Length: Cardinal; // length of the word in quarters
+ Text: String; // text
+ Freestyle: Boolean; // is freestyle?
+ end;
+ ALyricWord = array of TLyricWord;
+
+ TLyricLine = class
+ public
+ Text: String; // text
+ Tex: glUInt; // texture of the text
+ Width: Real; // width
+ Size: Byte; // fontsize
+ Words: ALyricWord; // words in this line
+ CurWord: Integer; // current active word idx (only valid if line is active)
+ Start: Integer; // start of this line in quarters (Note: negative start values are possible due to gap)
+ StartNote: Integer; // start of the first note of this line in quarters
+ Length: Integer; // length in quarters (from start of first to the end of the last note)
+ HasFreestyle: Boolean; // one or more word are freestyle?
+ CountFreestyle: Integer; // how often there is a change from freestyle to non freestyle in this line
+ Players: Byte; // players that should sing that line (bitset, Player1: 1, Player2: 2, Player3: 4)
+ LastLine: Boolean; // is this the last line of the song?
+
+ constructor Create();
+ destructor Destroy(); override;
+ procedure Reset();
+ end;
+
+ TLyricEngine = class
+ private
+ LastDrawBeat: Real;
+ UpperLine: TLyricLine; // first line displayed (top)
+ LowerLine: TLyricLine; // second lind displayed (bottom)
+ QueueLine: TLyricLine; // third line (will be displayed when lower line is finished)
+
+ IndicatorTex: TTexture; // texture for lyric indikator
+ BallTex: TTexture; // texture of the ball for the lyric effect
+
+ QueueFull: Boolean; // set to true if the queue is full and a line will be replaced with the next AddLine
+ LCounter: Word; // line counter
+
+ // duet mode - textures for player icons
+ // FIXME: do not use a fixed player count, use MAX_PLAYERS instead
+ PlayerIconTex: array[0..5] of TPlayerIconTex;
+
+ //Some helper Procedures for Lyric Drawing
+ procedure DrawLyrics (Beat: Real);
+ procedure DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real);
+ procedure DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real);
+ procedure DrawBall(XBall, YBall, Alpha:Real);
+
+ public
+ // positions, line specific settings
+ UpperLineX: Real; //X Start Pos of UpperLine
+ UpperLineW: Real; //Width of UpperLine with Icon(s) and Text
+ UpperLineY: Real; //Y Start Pos of UpperLine
+ UpperLineSize: Byte; //Max Size of Lyrics Text in UpperLine
+
+ LowerLineX: Real; //X Start Pos of LowerLine
+ LowerLineW: Real; //Width of LowerLine with Icon(s) and Text
+ LowerLineY: Real; //Y Start Pos of LowerLine
+ LowerLineSize: Byte; //Max Size of Lyrics Text in LowerLine
+
+ // display propertys
+ LineColor_en: TRGBA; //Color of Words in an Enabled Line
+ LineColor_dis: TRGBA; //Color of Words in a Disabled Line
+ LineColor_act: TRGBA; //Color of teh active Word
+ FontStyle: Byte; //Font for the Lyric Text
+ FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen
+
+ { // currently not used
+ FadeInEffect: Byte; //Effect for Line Fading in: 0: No Effect; 1: Fade Effect; 2: Move Upwards from Bottom to Pos
+ FadeOutEffect: Byte; //Effect for Line Fading out: 0: No Effect; 1: Fade Effect; 2: Move Upwards
+ }
+
+ UseLinearFilter: Boolean; //Should Linear Tex Filter be used
+
+ // song specific settings
+ BPM: Real;
+ Resolution: Integer;
+
+ // properties to easily read options of this class
+ property IsQueueFull: Boolean read QueueFull; // line in queue?
+ property LineCounter: Word read LCounter; // lines that were progressed so far (after last clear)
+
+ procedure AddLine(Line: PLine); // adds a line to the queue, if there is space
+ procedure Draw (Beat: Real); // draw the current (active at beat) lyrics
+
+ // clears all cached song specific information
+ procedure Clear(cBPM: Real = 0; cResolution: Integer = 0);
+
+ function GetUpperLine(): TLyricLine;
+ function GetLowerLine(): TLyricLine;
+
+ function GetUpperLineIndex(): Integer;
+
+ constructor Create; overload;
+ constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS: Real); overload;
+ procedure LoadTextures;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses SysUtils,
+ USkins,
+ TextGL,
+ UGraphic,
+ UDisplay,
+ ULog,
+ math,
+ UIni;
+
+//-----------
+//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else
+//-----------
+procedure glColorRGB(Color: TRGB); overload;
+begin
+ glColor3f(Color.R, Color.G, Color.B);
+end;
+
+procedure glColorRGB(Color: TRGB; Alpha: Real); overload;
+begin
+ glColor4f(Color.R, Color.G, Color.B, Alpha);
+end;
+
+procedure glColorRGB(Color: TRGBA); overload;
+begin
+ glColor4f(Color.R, Color.G, Color.B, Color.A);
+end;
+
+procedure glColorRGB(Color: TRGBA; Alpha: Real); overload;
+begin
+ glColor4f(Color.R, Color.G, Color.B, Min(Color.A, Alpha));
+end;
+
+{ TLyricLine }
+
+constructor TLyricLine.Create();
+begin
+ inherited;
+ Reset();
+end;
+
+destructor TLyricLine.Destroy();
+begin
+ SetLength(Words, 0);
+ inherited;
+end;
+
+procedure TLyricLine.Reset();
+begin
+ Start := 0;
+ StartNote := 0;
+ Length := 0;
+ LastLine := False;
+
+ Text := '';
+ Width := 0;
+
+ // duet mode: players of that line (default: all)
+ Players := $FF;
+
+ SetLength(Words, 0);
+ CurWord := -1;
+
+ HasFreestyle := False;
+ CountFreestyle := 0;
+end;
+
+
+{ TLyricEngine }
+
+//---------------
+// Create - Constructor, just get Memory
+//---------------
+constructor TLyricEngine.Create;
+begin
+ inherited;
+
+ BPM := 0;
+ Resolution := 0;
+ LCounter := 0;
+ QueueFull := False;
+
+ UpperLine := TLyricLine.Create;
+ LowerLine := TLyricLine.Create;
+ QueueLine := TLyricLine.Create;
+
+ UseLinearFilter := True;
+ LastDrawBeat := 0;
+end;
+
+constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real);
+begin
+ Create;
+
+ UpperLineX := ULX;
+ UpperLineW := ULW;
+ UpperLineY := ULY;
+ UpperLineSize := Trunc(ULS);
+
+ LowerLineX := LLX;
+ LowerLineW := LLW;
+ LowerLineY := LLY;
+ LowerLineSize := Trunc(LLS);
+
+ LoadTextures;
+end;
+
+
+//---------------
+// Destroy - Frees Memory
+//---------------
+destructor TLyricEngine.Destroy;
+begin
+ UpperLine.Free;
+ LowerLine.Free;
+ QueueLine.Free;
+ inherited;
+end;
+
+//---------------
+// Clear - Clears all cached Song specific Information
+//---------------
+procedure TLyricEngine.Clear(cBPM: Real; cResolution: Integer);
+begin
+ BPM := cBPM;
+ Resolution := cResolution;
+ LCounter := 0;
+ QueueFull := False;
+
+ LastDrawBeat:=0;
+end;
+
+
+//---------------
+// LoadTextures - Load Player Textures and Create Lyric Textures
+//---------------
+procedure TLyricEngine.LoadTextures;
+var
+ I: Integer;
+
+ function CreateLineTex: glUint;
+ begin
+ // generate and bind Texture
+ glGenTextures(1, @Result);
+ glBindTexture(GL_TEXTURE_2D, Result);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if UseLinearFilter then
+ begin
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ end;
+ end;
+
+begin
+
+ // lyric indicator (bar that indicates when the line start)
+ IndicatorTex := Texture.LoadTexture(Skin.GetTextureFileName('LyricHelpBar'), TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+
+ // ball for current word hover in ball effect
+ BallTex := Texture.LoadTexture(Skin.GetTextureFileName('Ball'), TEXTURE_TYPE_TRANSPARENT, 0);
+
+ // duet mode: load player icon
+ for I := 0 to 5 do
+ begin
+ PlayerIconTex[I][0] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0);
+ PlayerIconTex[I][1] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0);
+ end;
+
+ // create line textures
+ UpperLine.Tex := CreateLineTex;
+ LowerLine.Tex := CreateLineTex;
+ QueueLine.Tex := CreateLineTex;
+end;
+
+
+//---------------
+// AddLine - Adds LyricLine to queue
+// The LyricEngine stores three lines in its queue:
+// UpperLine: the upper line displayed in the lyrics
+// LowerLine: the lower line displayed in the lyrics
+// QueueLine: an offscreen line that precedes LowerLine
+// If the queue is full the next call to AddLine will replace UpperLine with
+// LowerLine, LowerLine with QueueLine and QueueLine with the Line parameter.
+//---------------
+procedure TLyricEngine.AddLine(Line: PLine);
+var
+ LyricLine: TLyricLine;
+ PosX: Real;
+ I: Integer;
+ CurWord: PLyricWord;
+ RenderPass: Integer;
+
+ function CalcWidth(LyricLine: TLyricLine): Real;
+ begin
+ Result := glTextWidth(PChar(LyricLine.Text));
+
+ Result := Result + (LyricLine.CountFreestyle * 10);
+
+ // if the line ends with a freestyle not, then leave the place to finish to draw the text italic
+ if (LyricLine.Words[High(LyricLine.Words)].Freestyle) then
+ Result := Result + 12;
+ end;
+
+begin
+ // only add lines, if there is space
+ if not IsQueueFull then
+ begin
+ // set LyricLine to line to write to
+ if (LineCounter = 0) then
+ LyricLine := UpperLine
+ else if (LineCounter = 1) then
+ LyricLine := LowerLine
+ else
+ begin
+ // now the queue is full
+ LyricLine := QueueLine;
+ QueueFull := True;
+ end;
+ end
+ else
+ begin // rotate lines (round-robin-like)
+ LyricLine := UpperLine;
+ UpperLine := LowerLine;
+ LowerLine := QueueLine;
+ QueueLine := LyricLine;
+ end;
+
+ // reset line state
+ LyricLine.Reset();
+
+ // check if sentence has notes
+ if (Line <> nil) and (Length(Line.Note) > 0) then
+ begin
+ // copy values from SongLine to LyricLine
+ LyricLine.Start := Line.Start;
+ LyricLine.StartNote := Line.Note[0].Start;
+ LyricLine.Length := Line.Note[High(Line.Note)].Start +
+ Line.Note[High(Line.Note)].Length -
+ Line.Note[0].Start;
+ LyricLine.LastLine := Line.LastLine;
+
+ // copy words
+ SetLength(LyricLine.Words, Length(Line.Note));
+ for I := 0 to High(Line.Note) do
+ begin
+ LyricLine.Words[I].Start := Line.Note[I].Start;
+ LyricLine.Words[I].Length := Line.Note[I].Length;
+ LyricLine.Words[I].Text := Line.Note[I].Text;
+ LyricLine.Words[I].Freestyle := Line.Note[I].NoteType = ntFreestyle;
+
+ LyricLine.HasFreestyle := LyricLine.HasFreestyle or LyricLine.Words[I].Freestyle;
+ LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text;
+
+ if (I > 0) and
+ LyricLine.Words[I-1].Freestyle and
+ not LyricLine.Words[I].Freestyle then
+ begin
+ Inc(LyricLine.CountFreestyle);
+ end;
+ end;
+
+ // set font params
+ SetFontStyle(FontStyle);
+ SetFontPos(0, 0);
+ LyricLine.Size := UpperLineSize;
+ SetFontSize(LyricLine.Size);
+ SetFontItalic(False);
+ SetFontReflection(False, 0);
+ glColor4f(1, 1, 1, 1);
+
+ // change fontsize to fit the screen
+ LyricLine.Width := CalcWidth(LyricLine);
+ while (LyricLine.Width > UpperLineW) do
+ begin
+ Dec(LyricLine.Size);
+
+ if (LyricLine.Size <=1) then
+ Break;
+
+ SetFontSize(LyricLine.Size);
+ LyricLine.Width := CalcWidth(LyricLine);
+ end;
+
+ // Offscreen rendering of LyricTexture:
+ // First we will create a white transparent background to draw on.
+ // If the text was simply drawn to the screen with blending, the translucent
+ // parts of the text would be merged with the current color of the background.
+ // This would result in a texture that partly contains the screen we are
+ // drawing on. This will be visible in the fonts outline when the LyricTexture
+ // is drawn to the screen later.
+ // So we have to draw the text in TWO passes.
+ // At the first pass we copy the characters to the back-buffer in such a way
+ // that preceding characters are not repainted by following chars (otherwise
+ // some characters would be blended twice in the 2nd pass).
+ // To achieve this we disable blending and enable the depth-test. The z-buffer
+ // is used as a mask or replacement for the missing stencil-buffer. A z-value
+ // of 1 means the pixel was not assigned yet, whereas 0 stands for a pixel
+ // that was already drawn on. In addition we set the depth-func in such a way
+ // that assigned pixels (0) will not be drawn a second time.
+ // At the second pass we draw the text with blending and without depth-test.
+ // This will blend overlapping characters but not the background as it was
+ // repainted in the first pass.
+
+ glPushAttrib(GL_VIEWPORT_BIT or GL_DEPTH_BUFFER_BIT);
+ glViewPort(0, 0, 800, 600);
+ glClearColor(0, 0, 0, 0);
+ glDepthRange(0, 1);
+ glClearDepth(1);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ SetFontZ(0);
+
+ // assure blending is off and the correct depth-func is enabled
+ glDisable(GL_BLEND);
+ glDepthFunc(GL_LESS);
+
+ // we need two passes to draw the font onto the screen.
+ for RenderPass := 0 to 1 do
+ begin
+ if (RenderPass = 0) then
+ begin
+ // first pass: simply copy each character to the screen without overlapping.
+ SetFontBlend(false);
+ glEnable(GL_DEPTH_TEST);
+ end
+ else
+ begin
+ // second pass: now we will blend overlapping characters.
+ SetFontBlend(true);
+ glDisable(GL_DEPTH_TEST);
+ end;
+
+ PosX := 0;
+
+ // set word positions and line size and draw the line to the back-buffer
+ for I := 0 to High(LyricLine.Words) do
+ begin
+ CurWord := @LyricLine.Words[I];
+
+ SetFontItalic(CurWord.Freestyle);
+
+ CurWord.X := PosX;
+
+ // Draw Lyrics
+ SetFontPos(PosX, 0);
+ glPrint(PChar(CurWord.Text));
+
+ CurWord.Width := glTextWidth(PChar(CurWord.Text));
+ if CurWord.Freestyle then
+ begin
+ if (I < High(LyricLine.Words)) and not LyricLine.Words[I+1].Freestyle then
+ CurWord.Width := CurWord.Width + 10
+ else if (I = High(LyricLine.Words)) then
+ CurWord.Width := CurWord.Width + 12;
+ end;
+ PosX := PosX + CurWord.Width;
+ end;
+ end;
+
+ // copy back-buffer to texture
+ glBindTexture(GL_TEXTURE_2D, LyricLine.Tex);
+ // FIXME: this does not work this way
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 600-64, 1024, 64, 0);
+ if (glGetError() <> GL_NO_ERROR) then
+ Log.LogError('Creation of Lyrics-texture failed', 'TLyricEngine.AddLine');
+
+ // restore OpenGL state
+ glPopAttrib();
+
+ // clear buffer (use white to avoid flimmering if no cover/video is available)
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end; // if (Line <> nil) and (Length(Line.Note) > 0)
+
+ // increase the counter
+ Inc(LCounter);
+end;
+
+
+//---------------
+// Draw - Procedure Draws Lyrics; Beat is curent Beat in Quarters
+// Draw just manage the Lyrics, drawing is done by a call of DrawLyrics
+//---------------
+procedure TLyricEngine.Draw(Beat: Real);
+begin
+ DrawLyrics(Beat);
+ LastDrawBeat := Beat;
+end;
+
+//---------------
+// DrawLyrics(private) - Helper for Draw; main Drawing procedure
+//---------------
+procedure TLyricEngine.DrawLyrics(Beat: Real);
+begin
+ DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat);
+ DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat);
+end;
+
+//---------------
+// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon
+//---------------
+procedure TLyricEngine.DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real);
+var
+ IEnabled: Byte;
+begin
+ if Enabled then
+ IEnabled := 0
+ else
+ IEnabled := 1;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, PlayerIconTex[Player][IEnabled].TexNum);
+
+ glColor4f(1, 1, 1, Alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y + Size);
+ glTexCoord2f(1, 1); glVertex2f(X + Size, Y + Size);
+ glTexCoord2f(1, 0); glVertex2f(X + Size, Y);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+//---------------
+// DrawBall(private) - Helper for Draw; Draws the Ball over the LyricLine if needed
+//---------------
+procedure TLyricEngine.DrawBall(XBall, YBall, Alpha: Real);
+begin
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, BallTex.TexNum);
+
+ glColor4f(1, 1, 1, Alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(XBall - 10, YBall);
+ glTexCoord2f(0, 1); glVertex2f(XBall - 10, YBall + 20);
+ glTexCoord2f(1, 1); glVertex2f(XBall + 10, YBall + 20);
+ glTexCoord2f(1, 0); glVertex2f(XBall + 10, YBall);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+//---------------
+// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine
+//---------------
+procedure TLyricEngine.DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real);
+var
+ CurWordStart, CurWordEnd: Real; // screen coordinates of current word and the rest of the sentence
+ FreestyleDiff: Integer; // difference between top and bottom coordiantes for freestyle lyrics
+ Progress: Real; // progress of singing the current word
+ LyricX: Real; // left
+ LyricX2: Real; // right
+ LyricY: Real; // top
+ LyricsHeight: Real; // height the lyrics are displayed
+ Alpha: Real; // alphalevel to fade out at end
+ CurWord, LastWord: PLyricWord; // current word
+
+ {// duet mode
+ IconSize: Real; // size of player icons
+ IconAlpha: Real; // alpha level of player icons
+ }
+begin
+ // do not draw empty lines
+ // Note: lines with no words in it do not have a valid texture
+ if (Length(Line.Words) = 0) or
+ (Line.Width <= 0) then
+ begin
+ Exit;
+ end;
+
+ // this is actually a bit more than the real font size
+ // it helps adjusting the "zoom-center"
+ LyricsHeight := 30.5 * (Line.Size/10);
+
+ {
+ // duet mode
+ IconSize := (2 * Size);
+ IconAlpha := Frac(Beat/(Resolution*4));
+
+ DrawPlayerIcon (0, True, X, Y + (42 - IconSize) / 2 , IconSize, IconAlpha);
+ DrawPlayerIcon (1, True, X + IconSize + 1, Y + (42 - IconSize) / 2, IconSize, IconAlpha);
+ DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y + (42 - IconSize) / 2, IconSize, IconAlpha);
+ }
+
+ LyricX := X + W/2 - Line.Width/2;
+ LyricX2 := LyricX + Line.Width;
+
+ // maybe center smaller lines
+ //LyricY := Y;
+ LyricY := Y + ((Size / Line.Size - 1) * LyricsHeight) / 2;
+
+ Alpha := 1;
+
+ // check if this line is active (at least its first note must be active)
+ if (Beat >= Line.StartNote) then
+ begin
+ // if this line just got active, CurWord is -1,
+ // this means we should try to make the first word active
+ if (Line.CurWord = -1) then
+ Line.CurWord := 0;
+
+ // check if the current active word is still active.
+ // Otherwise proceed to the next word if there is one in this line.
+ // Note: the max. value of Line.CurWord is High(Line.Words)
+ if (Line.CurWord < High(Line.Words)) and
+ (Beat >= Line.Words[Line.CurWord + 1].Start) then
+ begin
+ Inc(Line.CurWord);
+ end;
+
+ FreestyleDiff := 0;
+
+ // determine current and last word in this line.
+ // If the end of the line is reached use the last word as current word.
+ LastWord := @Line.Words[High(Line.Words)];
+ CurWord := @Line.Words[Line.CurWord];
+
+ // calc the progress of the lyrics effect
+ Progress := (Beat - CurWord.Start) / CurWord.Length;
+ if Progress >= 1 then
+ Progress := 1;
+ if Progress <= 0 then
+ Progress := 0;
+
+ // last word of this line finished, but this line did not hide -> fade out
+ if Line.LastLine and
+ (Beat > LastWord.Start + LastWord.Length) then
+ begin
+ Alpha := 1 - (Beat - (LastWord.Start + LastWord.Length)) / 15;
+ if (Alpha < 0) then
+ Alpha := 0;
+ end;
+
+ // determine the start-/end positions of the fragment of the current word
+ CurWordStart := CurWord.X;
+ CurWordEnd := CurWord.X + CurWord.Width;
+
+ // Slide Effect
+ // simply paint the active texture to the current position
+ if Ini.LyricsEffect = 2 then
+ begin
+ CurWordStart := CurWordStart + CurWord.Width * Progress;
+ CurWordEnd := CurWordStart;
+ end;
+
+ if CurWord.Freestyle then
+ begin
+ if (Line.CurWord < High(Line.Words)) and
+ (not Line.Words[Line.CurWord + 1].Freestyle) then
+ begin
+ FreestyleDiff := 2;
+ end
+ else
+ begin
+ FreestyleDiff := 12;
+ CurWordStart := CurWordStart - 1;
+ CurWordEnd := CurWordEnd - 2;
+ end;
+ end;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, Line.Tex);
+
+ // draw sentence up to current word
+ // type 0: simple lyric effect
+ // type 3: ball lyric effect
+ // type 4: shift lyric effect
+ if (Ini.LyricsEffect in [0, 3, 4]) then
+ // ball lyric effect - only highlight current word and not that ones before in this line
+ glColorRGB(LineColor_en, Alpha)
+ else
+ glColorRGB(LineColor_act, Alpha);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 1);
+ glVertex2f(LyricX, LyricY);
+
+ glTexCoord2f(0, 1-LyricsHeight/64);
+ glVertex2f(LyricX, LyricY + LyricsHeight);
+
+ glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64);
+ glVertex2f(LyricX + CurWordStart, LyricY + LyricsHeight);
+
+ glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
+ glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY);
+ glEnd;
+
+ // draw rest of sentence
+ glColorRGB(LineColor_en, Alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
+ glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY);
+
+ glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64);
+ glVertex2f(LyricX + CurWordEnd, LyricY + LyricsHeight);
+
+ glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64);
+ glVertex2f(LyricX2, LyricY + LyricsHeight);
+
+ glTexCoord2f(Line.Width/1024, 1);
+ glVertex2f(LyricX2, LyricY);
+ glEnd;
+
+ // draw active word:
+ // type 0: simple lyric effect
+ // type 3: ball lyric effect
+ // type 4: shift lyric effect
+ // only change the color of the current word
+ if (Ini.LyricsEffect in [0, 3, 4]) then
+ begin
+ if (Ini.LyricsEffect = 4) then
+ LyricY := LyricY - 8 * (1-Progress);
+
+ glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
+ glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY);
+
+ glTexCoord2f(CurWordStart/1024, 0);
+ glVertex2f(LyricX + CurWordStart, LyricY + 64);
+
+ glTexCoord2f(CurWordEnd/1024, 0);
+ glVertex2f(LyricX + CurWordEnd, LyricY + 64);
+
+ glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
+ glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY);
+ glEnd;
+
+ if (Ini.LyricsEffect = 4) then
+ LyricY := LyricY + 8 * (1-Progress);
+ end
+
+ // draw active word:
+ // type 1: zoom lyric effect
+ // change color and zoom current word
+ else if Ini.LyricsEffect = 1 then
+ begin
+ glPushMatrix;
+
+ glTranslatef(LyricX + CurWordStart + (CurWordEnd-CurWordStart)/2,
+ LyricY + LyricsHeight/2, 0);
+
+ // set current zoom factor
+ glScalef(1.0 + (1-Progress) * 0.5, 1.0 + (1-Progress) * 0.5, 1.0);
+
+ glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1);
+ glVertex2f(-(CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2);
+
+ glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64);
+ glVertex2f(-(CurWordEnd-CurWordStart)/2, LyricsHeight/2);
+
+ glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64);
+ glVertex2f((CurWordEnd-CurWordStart)/2, LyricsHeight/2);
+
+ glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1);
+ glVertex2f((CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2);
+ glEnd;
+
+ glPopMatrix;
+ end;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // type 3: ball lyric effect
+ if Ini.LyricsEffect = 3 then
+ begin
+ DrawBall(LyricX + CurWordStart + (CurWordEnd-CurWordStart) * Progress,
+ LyricY - 15 - 15*sin(Progress * Pi), Alpha);
+ end;
+ end
+ else
+ begin
+ // this section is called if the whole line can be drawn at once and no
+ // word has to be emphasized.
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Line.Tex);
+
+ // enable the upper, disable the lower line
+ if (Line = UpperLine) then
+ glColorRGB(LineColor_en)
+ else
+ glColorRGB(LineColor_dis);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 1);
+ glVertex2f(LyricX, LyricY);
+
+ glTexCoord2f(0, 1-LyricsHeight/64);
+ glVertex2f(LyricX, LyricY + LyricsHeight);
+
+ glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64);
+ glVertex2f(LyricX2, LyricY + LyricsHeight);
+
+ glTexCoord2f(Line.Width/1024, 1);
+ glVertex2f(LyricX2, LyricY);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end;
+end;
+
+//---------------
+// GetUpperLine() - Returns a reference to the upper line
+//---------------
+function TLyricEngine.GetUpperLine(): TLyricLine;
+begin
+ Result := UpperLine;
+end;
+
+//---------------
+// GetLowerLine() - Returns a reference to the lower line
+//---------------
+function TLyricEngine.GetLowerLine(): TLyricLine;
+begin
+ Result := LowerLine;
+end;
+
+//---------------
+// GetUpperLineIndex() - Returns the index of the upper line
+//---------------
+function TLyricEngine.GetUpperLineIndex(): Integer;
+const
+ QUEUE_SIZE = 3;
+begin
+ // no line in queue
+ if (LineCounter <= 0) then
+ Result := -1
+ // no line has been removed from queue yet
+ else if (LineCounter <= QUEUE_SIZE) then
+ Result := 0
+ // lines have been removed from queue already
+ else
+ Result := LineCounter - QUEUE_SIZE;
+end;
+
+end.
+
diff --git a/src/Classes/UMain.pas b/src/Classes/UMain.pas
new file mode 100644
index 00000000..da9df6d3
--- /dev/null
+++ b/src/Classes/UMain.pas
@@ -0,0 +1,1107 @@
+unit UMain;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ Classes,
+ SDL,
+ UMusic,
+ URecord,
+ UTime,
+ UDisplay,
+ UIni,
+ ULog,
+ ULyrics,
+ UScreenSing,
+ USong,
+ gl;
+
+type
+ PPLayerNote = ^TPlayerNote;
+ TPlayerNote = record
+ Start: integer;
+ Length: integer;
+ Detect: real; // accurate place, detected in the note
+ Tone: real;
+ Perfect: boolean; // true if the note matches the original one, lit the star
+ Hit: boolean; // true if the note Hits the Line
+ end;
+
+ PPLayer = ^TPlayer;
+ TPlayer = record
+ Name: string;
+
+ // Index in Teaminfo record
+ TeamID: Byte;
+ PlayerID: Byte;
+
+ // Scores
+ Score: real;
+ ScoreLine: real;
+ ScoreGolden: real;
+
+ ScoreInt: integer;
+ ScoreLineInt: integer;
+ ScoreGoldenInt: integer;
+ ScoreTotalInt: integer;
+
+ // LineBonus
+ ScoreLast: Real;//Last Line Score
+
+ // PerfectLineTwinkle (effect)
+ LastSentencePerfect: Boolean;
+
+ HighNote: integer; // index of last note (= High(Note)?)
+ LengthNote: integer; // number of notes (= Length(Note)?).
+ Note: array of TPlayerNote;
+ end;
+
+
+var
+ // Absolute Paths
+ GamePath: string;
+ SoundPath: string;
+ SongPaths: TStringList;
+ LogPath: string;
+ ThemePath: string;
+ SkinsPath: string;
+ ScreenshotsPath: string;
+ CoverPaths: TStringList;
+ LanguagesPath: string;
+ PluginPath: string;
+ VisualsPath: string;
+ ResourcesPath: string;
+ PlayListPath: string;
+
+ Done: Boolean;
+ Event: TSDL_event;
+ // FIXME: ConversionFileName should not be global
+ ConversionFileName: string;
+ Restart: boolean;
+
+ // player and music info
+ Player: array of TPlayer;
+ PlayersPlay: integer;
+
+ CurrentSong : TSong;
+
+const
+ MAX_SONG_SCORE = 10000; // max. achievable points per song
+ MAX_SONG_LINE_BONUS = 1000; // max. achievable line bonus per song
+
+function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
+procedure InitializePaths;
+procedure AddSongPath(const Path: string);
+
+Procedure Main;
+procedure MainLoop;
+procedure CheckEvents;
+procedure Sing(Screen: TScreenSing);
+procedure NewSentence(Screen: TScreenSing);
+procedure NewBeatClick(Screen: TScreenSing); // executed when on then new beat for click
+procedure NewBeatDetect(Screen: TScreenSing); // executed when on then new beat for detection
+procedure NewNote(Screen: TScreenSing); // detect note
+function GetMidBeat(Time: real): real;
+function GetTimeFromBeat(Beat: integer): real;
+procedure ClearScores(PlayerNum: integer);
+
+implementation
+
+uses
+ Math,
+ StrUtils,
+ USongs,
+ UJoystick,
+ UCommandLine,
+ ULanguage,
+ //SDL_ttf,
+ USkins,
+ UCovers,
+ UCatCovers,
+ UDataBase,
+ UPlaylist,
+ UDLLManager,
+ UParty,
+ UConfig,
+ UCore,
+ UCommon,
+ UGraphic,
+ UGraphicClasses,
+ UPluginDefs,
+ UPlatform,
+ UThemes;
+
+
+
+
+procedure Main;
+var
+ WndTitle: string;
+begin
+ try
+ WndTitle := USDXVersionStr;
+
+ Platform.Init;
+
+ if Platform.TerminateIfAlreadyRunning(WndTitle) then
+ Exit;
+
+ // fix floating-point exceptions (FPE)
+ DisableFloatingPointExceptions();
+ // fix the locale for string-to-float parsing in C-libs
+ SetDefaultNumericLocale();
+
+ // setup separators for parsing
+ // Note: ThousandSeparator must be set because of a bug in TIniFile.ReadFloat
+ ThousandSeparator := ',';
+ DecimalSeparator := '.';
+
+ //------------------------------
+ //StartUp - Create Classes and Load Files
+ //------------------------------
+
+ // Initialize SDL
+ // Without SDL_INIT_TIMER SDL_GetTicks() might return strange values
+ SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER);
+ SDL_EnableUnicode(1);
+
+ USTime := TTime.Create;
+ VideoBGTimer := TRelativeTimer.Create;
+
+ // Commandline Parameter Parser
+ Params := TCMDParams.Create;
+
+ // Log + Benchmark
+ Log := TLog.Create;
+ Log.Title := WndTitle;
+ Log.FileOutputEnabled := 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_ttf (Not used yet, maybe in version 1.5)
+ 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;
+
+ //it's possible that this is the first run, create a .ini file if neccessary
+ Log.LogStatus('Write Ini', 'Initialization');
+ Ini.Save;
+
+ // 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);
+
+ // Lyrics-engine with media reference timer
+ LyricsState := TLyricsState.Create();
+
+ // 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 := TCoverDatabase.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 (Platform.GetGameUserPath + '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 Particle 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.LogStatus('Creating Core', 'Initialization');
+ {Core := TCore.Create(
+ USDXShortVersionStr,
+ MakeVersion(USDX_VERSION_MAJOR,
+ USDX_VERSION_MINOR,
+ USDX_VERSION_RELEASE,
+ chr(0))
+ ); }
+
+ Log.LogStatus('Running Core', 'Initialization');
+ //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
+
+ FinalizeMedia();
+
+ //TTF_Quit();
+ SDL_Quit();
+
+ if assigned(Log) then
+ begin
+ Log.LogStatus('Main Loop', 'Finished');
+ Log.Free;
+ end;
+ end;
+end;
+
+procedure MainLoop;
+var
+ Delay: integer;
+const
+ MAX_FPS = 100;
+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;
+
+ // delay
+ CountMidTime;
+
+ Delay := Floor(1000 / MAX_FPS - 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;
+ // Note: do NOT call SDL_SetVideoMode on Windows and MacOSX here.
+ // This would create a new OpenGL render-context and all texture data
+ // would be invalidated.
+ // On Linux the mode MUST be resetted, otherwise graphics will be corrupted.
+ {$IFDEF LINUX}
+ if boolean( Ini.FullScreen ) then
+ SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN)
+ else
+ SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE);
+ {$ENDIF}
+ 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 ) );
+
+ // FIXME: SDL_SetVideoMode creates a new OpenGL RC so we have to
+ // reload all texture data (-> whitescreen bug).
+ // Only Linux is able to handle screen-switching this way.
+ {$IFDEF LINUX}
+ 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);
+ {$ENDIF}
+ end
+ // if print is pressed -> make screenshot and save to screenshot path
+ else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then
+ Display.SaveScreenShot
+ // 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)
+ else
+ begin
+ // check if screen wants 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 // if ask-for-exit is disabled then simply exit
+ begin
+ Display.Fade := 0;
+ Display.NextScreenWithCheck := nil;
+ Display.CheckOK := True;
+ end;
+ end;
+
+ end;
+ end;
+ SDL_JOYAXISMOTION:
+ begin
+ // not implemented
+ end;
+ SDL_JOYBUTTONDOWN:
+ begin
+ // not implemented
+ 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;
+begin
+ // static BPM
+ if Length(CurrentSong.BPM) = 1 then
+ begin
+ Result := Time * CurrentSong.BPM[0].BPM / 60;
+ end
+ // variable BPM
+ else 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
+ // invalid BPM
+ else
+ begin
+ Result := 0;
+ end;
+end;
+
+function GetTimeFromBeat(Beat: integer): real;
+var
+ CurBPM: integer;
+begin
+ // static BPM
+ if Length(CurrentSong.BPM) = 1 then
+ begin
+ Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM;
+ end
+ // variable BPM
+ else 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
+ // invalid BPM
+ else
+ begin
+ Result := 0;
+ end;
+end;
+
+procedure Sing(Screen: TScreenSing);
+var
+ Count: integer;
+ CountGr: integer;
+ CP: integer;
+ Done: real;
+ N: integer;
+ CurLine: PLine;
+ CurNote: PLineFragment;
+begin
+ LyricsState.UpdateBeats();
+
+ // sentences routines
+ for CountGr := 0 to 0 do //High(Lines)
+ begin;
+ CP := CountGr;
+ // old parts
+ LyricsState.OldLine := Lines[CP].Current;
+
+ // choose current parts
+ for Count := 0 to Lines[CP].High do
+ begin
+ if LyricsState.CurrentBeat >= Lines[CP].Line[Count].Start then
+ Lines[CP].Current := Count;
+ end;
+
+ // clean player note if there is a new line
+ // (optimization on halfbeat time)
+ if Lines[CP].Current <> LyricsState.OldLine then
+ NewSentence(Screen);
+
+ end; // for CountGr
+
+ // make some operations on clicks
+ if {(LyricsState.CurrentBeatC >= 0) and }(LyricsState.OldBeatC <> LyricsState.CurrentBeatC) then
+ NewBeatClick(Screen);
+
+ // make some operations when detecting new voice pitch
+ if (LyricsState.CurrentBeatD >= 0) and (LyricsState.OldBeatD <> LyricsState.CurrentBeatD) then
+ NewBeatDetect(Screen);
+
+ CurLine := @Lines[0].Line[Lines[0].Current];
+
+ // remove moving text
+ Done := 1;
+ for N := 0 to CurLine.HighNote do
+ begin
+ CurNote := @CurLine.Note[N];
+ if (CurNote.Start <= LyricsState.MidBeat) and
+ (CurNote.Start + CurNote.Length >= LyricsState.MidBeat) then
+ begin
+ Done := (LyricsState.MidBeat - CurNote.Start) / CurNote.Length;
+ end;
+ end;
+end;
+
+procedure NewSentence(Screen: TScreenSing);
+var
+ i: Integer;
+begin
+ // clean note of player
+ for i := 0 to High(Player) do
+ begin
+ Player[i].LengthNote := 0;
+ Player[i].HighNote := -1;
+ SetLength(Player[i].Note, 0);
+ end;
+
+ // on sentence change...
+ Screen.onSentenceChange(Lines[0].Current);
+end;
+
+procedure NewBeatClick;
+var
+ Count: integer;
+begin
+ // beat click
+ if ((Ini.BeatClick = 1) and
+ ((LyricsState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0)) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Click);
+ end;
+
+ for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do
+ begin
+ if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LyricsState.CurrentBeatC) then
+ begin
+ // click assist
+ if Ini.ClickAssist = 1 then
+ AudioPlayback.PlaySound(SoundLib.Click);
+
+ // drum machine
+ (*
+ TempBeat := LyricsState.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;
+end;
+
+procedure NewBeatDetect(Screen: TScreenSing);
+begin
+ NewNote(Screen);
+end;
+
+procedure NewNote(Screen: TScreenSing);
+var
+ LineFragmentIndex: integer;
+ CurrentLineFragment: PLineFragment;
+ PlayerIndex: integer;
+ CurrentSound: TCaptureBuffer;
+ CurrentPlayer: PPlayer;
+ LastPlayerNote: PPLayerNote;
+ Line: PLine;
+ SentenceIndex: integer;
+ SentenceMin: integer;
+ SentenceMax: integer;
+ SentenceDetected: integer; // sentence of detected note
+ NoteAvailable: boolean;
+ NewNote: boolean;
+ Range: integer;
+ NoteHit: boolean;
+ MaxSongPoints: integer; // max. points for the song (without line bonus)
+ MaxLinePoints: Real; // max. points for the current line
+begin
+ // TODO: add duet mode support
+ // use Lines[LineSetIndex] with LineSetIndex depending on the current player
+
+ // count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
+ SentenceMin := Lines[0].Current-1;
+ if (SentenceMin < 0) then
+ SentenceMin := 0;
+ SentenceMax := Lines[0].Current;
+
+ // check for an active note at the current time defined in the lyrics
+ NoteAvailable := false;
+ SentenceDetected := SentenceMin;
+ for SentenceIndex := SentenceMin to SentenceMax do
+ begin
+ Line := @Lines[0].Line[SentenceIndex];
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ // check if line is active
+ if ((CurrentLineFragment.Start <= LyricsState.CurrentBeatD) and
+ (CurrentLineFragment.Start + CurrentLineFragment.Length-1 >= LyricsState.CurrentBeatD)) and
+ (CurrentLineFragment.NoteType <> ntFreestyle) and // but ignore FreeStyle notes
+ (CurrentLineFragment.Length > 0) then // and make sure the note lengths is at least 1
+ begin
+ SentenceDetected := SentenceIndex;
+ NoteAvailable := true;
+ Break;
+ end;
+ end;
+ // TODO: break here, if NoteAvailable is true? We would then use the first instead
+ // of the last note matching the current beat if notes overlap. But notes
+ // should not overlap at all.
+ //if (NoteAvailable) then
+ // Break;
+ end;
+
+ // analyze player signals
+ for PlayerIndex := 0 to PlayersPlay-1 do
+ begin
+ CurrentPlayer := @Player[PlayerIndex];
+ CurrentSound := AudioInputProcessor.Sound[PlayerIndex];
+ LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
+
+ // analyze buffer
+ CurrentSound.AnalyzeBuffer;
+
+ // add some noise
+ // TODO: do we need this?
+ //LyricsState.Tone := LyricsState.Tone + Round(Random(3)) - 1;
+
+ // add note if possible
+ if (CurrentSound.ToneValid and NoteAvailable) then
+ begin
+ Line := @Lines[0].Line[SentenceDetected];
+
+ // process until last note
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ if (CurrentLineFragment.Start <= LyricsState.OldBeatD+1) and
+ (CurrentLineFragment.Start + CurrentLineFragment.Length > LyricsState.OldBeatD+1) then
+ begin
+ // compare notes (from song-file and from player)
+
+ // move players tone to proper octave
+ while (CurrentSound.Tone - CurrentLineFragment.Tone > 6) do
+ CurrentSound.Tone := CurrentSound.Tone - 12;
+
+ while (CurrentSound.Tone - CurrentLineFragment.Tone < -6) do
+ CurrentSound.Tone := CurrentSound.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;
+
+ // check if the player hit the correct tone within the tolerated range
+ if (Abs(CurrentLineFragment.Tone - CurrentSound.Tone) <= Range) then
+ begin
+ // adjust the players tone to the correct one
+ // TODO: do we need to do this?
+ CurrentSound.Tone := CurrentLineFragment.Tone;
+
+ // half size notes patch
+ NoteHit := true;
+
+ if (Ini.LineBonus > 0) then
+ MaxSongPoints := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS
+ else
+ MaxSongPoints := MAX_SONG_SCORE;
+
+ // Note: ScoreValue is the sum of all note values of the song
+ MaxLinePoints := MaxSongPoints / Lines[0].ScoreValue;
+
+ // FIXME: is this correct? Why do we add the points for a whole line
+ // if just one note is correct?
+ case CurrentLineFragment.NoteType of
+ ntNormal: CurrentPlayer.Score := CurrentPlayer.Score + MaxLinePoints;
+ ntGolden: CurrentPlayer.ScoreGolden := CurrentPlayer.ScoreGolden + MaxLinePoints;
+ end;
+
+ CurrentPlayer.ScoreInt := Floor(CurrentPlayer.Score / 10) * 10;
+ CurrentPlayer.ScoreGoldenInt := Floor(CurrentPlayer.ScoreGolden / 10) * 10;
+
+ CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
+ CurrentPlayer.ScoreGoldenInt +
+ CurrentPlayer.ScoreLineInt;
+ end;
+
+ end; // operation
+ end; // for
+
+ // check if we have to add a new note or extend the note's length
+ if (SentenceDetected = SentenceMax) then
+ begin
+ // we will add a new note
+ NewNote := true;
+ // if last has the same tone
+ if ((CurrentPlayer.LengthNote > 0) and
+ (LastPlayerNote.Tone = CurrentSound.Tone) and
+ ((LastPlayerNote.Start + LastPlayerNote.Length) = LyricsState.CurrentBeatD)) then
+ begin
+ NewNote := false;
+ end;
+
+ // if is not as new note to control
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ if (Line.Note[LineFragmentIndex].Start = LyricsState.CurrentBeatD) then
+ NewNote := true;
+ end;
+
+ // add new note
+ if NewNote then
+ begin
+ // new note
+ Inc(CurrentPlayer.LengthNote);
+ Inc(CurrentPlayer.HighNote);
+ SetLength(CurrentPlayer.Note, CurrentPlayer.LengthNote);
+
+ // update player's last note
+ LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
+ with LastPlayerNote^ do
+ begin
+ Start := LyricsState.CurrentBeatD;
+ Length := 1;
+ Tone := CurrentSound.Tone; // Tone || ToneAbs
+ Detect := LyricsState.MidBeat;
+ Hit := NoteHit; // half note patch
+ end;
+ end
+ else
+ begin
+ // extend note length
+ Inc(LastPlayerNote.Length);
+ end;
+
+ // check for perfect note and then lit the star (on Draw)
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ if (CurrentLineFragment.Start = LastPlayerNote.Start) and
+ (CurrentLineFragment.Length = LastPlayerNote.Length) and
+ (CurrentLineFragment.Tone = LastPlayerNote.Tone) then
+ begin
+ LastPlayerNote.Perfect := true;
+ end;
+ end;
+ end; // if SentenceDetected = SentenceMax
+
+ end; // if Detected
+ end; // for PlayerIndex
+
+ //Log.LogStatus('EndBeat', 'NewBeat');
+
+ // on sentence end -> for LineBonus and display of SingBar (rating pop-up)
+ if (SentenceDetected >= Low(Lines[0].Line)) and
+ (SentenceDetected <= High(Lines[0].Line)) then
+ begin
+ Line := @Lines[0].Line[SentenceDetected];
+ CurrentLineFragment := @Line.Note[Line.HighNote];
+ if ((CurrentLineFragment.Start + CurrentLineFragment.Length - 1) = LyricsState.CurrentBeatD) then
+ begin
+ if assigned(Screen) then
+ Screen.OnSentenceEnd(SentenceDetected);
+ end;
+ end;
+
+end;
+
+procedure ClearScores(PlayerNum: integer);
+begin
+ with Player[PlayerNum] do
+ begin
+ Score := 0;
+ ScoreInt := 0;
+ ScoreLine := 0;
+ ScoreLineInt := 0;
+ ScoreGolden := 0;
+ ScoreGoldenInt := 0;
+ ScoreTotalInt := 0;
+ end;
+end;
+
+procedure AddSpecialPath(var PathList: TStringList; const Path: string);
+var
+ I: integer;
+ PathAbs, OldPathAbs: string;
+begin
+ if (PathList = nil) then
+ PathList := TStringList.Create;
+
+ if (Path = '') or not DirectoryExists(Path) then
+ Exit;
+
+ PathAbs := IncludeTrailingPathDelimiter(ExpandFileName(Path));
+
+ // check if path or a part of the path was already added
+ for I := 0 to PathList.Count-1 do
+ begin
+ OldPathAbs := IncludeTrailingPathDelimiter(ExpandFileName(PathList[I]));
+ // check if the new directory is a sub-directory of a previously added one.
+ // This is also true, if both paths point to the same directories.
+ if (AnsiStartsText(OldPathAbs, PathAbs)) then
+ begin
+ // ignore the new path
+ Exit;
+ end;
+
+ // check if a previously added directory is a sub-directory of the new one.
+ if (AnsiStartsText(PathAbs, OldPathAbs)) then
+ begin
+ // replace the old with the new one.
+ PathList[I] := PathAbs;
+ Exit;
+ end;
+ end;
+
+ PathList.Add(PathAbs);
+end;
+
+procedure AddSongPath(const Path: string);
+begin
+ AddSpecialPath(SongPaths, Path);
+end;
+
+procedure AddCoverPath(const Path: string);
+begin
+ AddSpecialPath(CoverPaths, Path);
+end;
+
+(**
+ * Initialize a path variable
+ * After setting paths, make sure that paths exist
+ *)
+function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
+begin
+ Result := false;
+
+ if (RequestedPath = '') then
+ Exit;
+
+ // Make sure the directory exists
+ if (not ForceDirectories(RequestedPath)) then
+ begin
+ PathResult := '';
+ Exit;
+ end;
+
+ PathResult := IncludeTrailingPathDelimiter(RequestedPath);
+
+ if (NeedsWritePermission) and
+ (FileIsReadOnly(RequestedPath)) then
+ begin
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+(**
+ * Function sets all absolute paths e.g. song path and makes sure the directorys exist
+ *)
+procedure InitializePaths;
+begin
+ // Log directory (must be writable)
+ if (not FindPath(LogPath, Platform.GetLogPath, true)) then
+ begin
+ Log.FileOutputEnabled := false;
+ Log.LogWarn('Log directory "'+ Platform.GetLogPath +'" not available', 'InitializePaths');
+ end;
+
+ FindPath(SoundPath, Platform.GetGameSharedPath + 'Sounds', false);
+ FindPath(ThemePath, Platform.GetGameSharedPath + 'Themes', false);
+ FindPath(SkinsPath, Platform.GetGameSharedPath + 'Themes', false);
+ FindPath(LanguagesPath, Platform.GetGameSharedPath + 'Languages', false);
+ FindPath(PluginPath, Platform.GetGameSharedPath + 'Plugins', false);
+ FindPath(VisualsPath, Platform.GetGameSharedPath + 'Visuals', false);
+ FindPath(ResourcesPath, Platform.GetGameSharedPath + 'Resources', false);
+
+ // Playlists are not shared as we need one directory to write too
+ FindPath(PlaylistPath, Platform.GetGameUserPath + 'Playlists', true);
+
+ // Screenshot directory (must be writable)
+ if (not FindPath(ScreenshotsPath, Platform.GetGameUserPath + 'Screenshots', true)) then
+ begin
+ Log.LogWarn('Screenshot directory "'+ Platform.GetGameUserPath +'" not available', 'InitializePaths');
+ end;
+
+ // Add song paths
+ AddSongPath(Params.SongPath);
+ AddSongPath(Platform.GetGameSharedPath + 'Songs');
+ AddSongPath(Platform.GetGameUserPath + 'Songs');
+
+ // Add category cover paths
+ AddCoverPath(Platform.GetGameSharedPath + 'Covers');
+ AddCoverPath(Platform.GetGameUserPath + 'Covers');
+end;
+
+end.
diff --git a/src/Classes/UMediaCore_FFmpeg.pas b/src/Classes/UMediaCore_FFmpeg.pas
new file mode 100644
index 00000000..cdd320ac
--- /dev/null
+++ b/src/Classes/UMediaCore_FFmpeg.pas
@@ -0,0 +1,405 @@
+unit UMediaCore_FFmpeg;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMusic,
+ avcodec,
+ avformat,
+ avutil,
+ ULog,
+ sdl;
+
+type
+ PPacketQueue = ^TPacketQueue;
+ TPacketQueue = class
+ private
+ FirstListEntry: PAVPacketList;
+ LastListEntry: PAVPacketList;
+ PacketCount: integer;
+ Mutex: PSDL_Mutex;
+ Condition: PSDL_Cond;
+ Size: integer;
+ AbortRequest: boolean;
+ public
+ constructor Create();
+ destructor Destroy(); override;
+
+ function Put(Packet : PAVPacket): integer;
+ function PutStatus(StatusFlag: integer; StatusInfo: Pointer): integer;
+ procedure FreeStatusInfo(var Packet: TAVPacket);
+ function GetStatusInfo(var Packet: TAVPacket): Pointer;
+ function Get(var Packet: TAVPacket; Blocking: boolean): integer;
+ function GetSize(): integer;
+ procedure Flush();
+ procedure Abort();
+ function IsAborted(): boolean;
+ end;
+
+const
+ STATUS_PACKET: PChar = 'STATUS_PACKET';
+const
+ PKT_STATUS_FLAG_EOF = 1; // signal end-of-file
+ PKT_STATUS_FLAG_FLUSH = 2; // request the decoder to flush its avcodec decode buffers
+ PKT_STATUS_FLAG_ERROR = 3; // signal an error state
+ PKT_STATUS_FLAG_EMPTY = 4; // request the decoder to output empty data (silence or black frames)
+
+type
+ TMediaCore_FFmpeg = class
+ private
+ AVCodecLock: PSDL_Mutex;
+ public
+ constructor Create();
+ destructor Destroy(); override;
+ class function GetInstance(): TMediaCore_FFmpeg;
+
+ function GetErrorString(ErrorNum: integer): string;
+ function FindStreamIDs(FormatCtx: PAVFormatContext; out FirstVideoStream, FirstAudioStream: integer ): boolean;
+ function FindAudioStreamIndex(FormatCtx: PAVFormatContext): integer;
+ function ConvertFFmpegToAudioFormat(FFmpegFormat: TSampleFormat; out Format: TAudioSampleFormat): boolean;
+ procedure LockAVCodec();
+ procedure UnlockAVCodec();
+ end;
+
+implementation
+
+uses
+ SysUtils;
+
+var
+ Instance: TMediaCore_FFmpeg;
+
+constructor TMediaCore_FFmpeg.Create();
+begin
+ inherited;
+ AVCodecLock := SDL_CreateMutex();
+end;
+
+destructor TMediaCore_FFmpeg.Destroy();
+begin
+ SDL_DestroyMutex(AVCodecLock);
+ inherited;
+end;
+
+class function TMediaCore_FFmpeg.GetInstance(): TMediaCore_FFmpeg;
+begin
+ if (not Assigned(Instance)) then
+ Instance := TMediaCore_FFmpeg.Create();
+ Result := Instance;
+end;
+
+procedure TMediaCore_FFmpeg.LockAVCodec();
+begin
+ SDL_mutexP(AVCodecLock);
+end;
+
+procedure TMediaCore_FFmpeg.UnlockAVCodec();
+begin
+ SDL_mutexV(AVCodecLock);
+end;
+
+function TMediaCore_FFmpeg.GetErrorString(ErrorNum: integer): string;
+begin
+ case ErrorNum of
+ AVERROR_IO: Result := 'AVERROR_IO';
+ AVERROR_NUMEXPECTED: Result := 'AVERROR_NUMEXPECTED';
+ AVERROR_INVALIDDATA: Result := 'AVERROR_INVALIDDATA';
+ AVERROR_NOMEM: Result := 'AVERROR_NOMEM';
+ AVERROR_NOFMT: Result := 'AVERROR_NOFMT';
+ AVERROR_NOTSUPP: Result := 'AVERROR_NOTSUPP';
+ AVERROR_NOENT: Result := 'AVERROR_NOENT';
+ AVERROR_PATCHWELCOME: Result := 'AVERROR_PATCHWELCOME';
+ else Result := 'AVERROR_#'+inttostr(ErrorNum);
+ end;
+end;
+
+{
+ @param(FormatCtx is a PAVFormatContext returned from av_open_input_file )
+ @param(FirstVideoStream is an OUT value of type integer, this is the index of the video stream)
+ @param(FirstAudioStream is an OUT value of type integer, this is the index of the audio stream)
+ @returns(@true on success, @false otherwise)
+}
+function TMediaCore_FFmpeg.FindStreamIDs(FormatCtx: PAVFormatContext; out FirstVideoStream, FirstAudioStream: integer): boolean;
+var
+ i: integer;
+ Stream: PAVStream;
+begin
+ // find the first video stream
+ FirstAudioStream := -1;
+ FirstVideoStream := -1;
+
+ for i := 0 to FormatCtx.nb_streams-1 do
+ begin
+ Stream := FormatCtx.streams[i];
+
+ if (Stream.codec.codec_type = CODEC_TYPE_VIDEO) and
+ (FirstVideoStream < 0) then
+ begin
+ FirstVideoStream := i;
+ end;
+
+ if (Stream.codec.codec_type = CODEC_TYPE_AUDIO) and
+ (FirstAudioStream < 0) then
+ begin
+ FirstAudioStream := i;
+ end;
+ end;
+
+ // return true if either an audio- or video-stream was found
+ Result := (FirstAudioStream > -1) or
+ (FirstVideoStream > -1) ;
+end;
+
+function TMediaCore_FFmpeg.FindAudioStreamIndex(FormatCtx: PAVFormatContext): integer;
+var
+ i: integer;
+ StreamIndex: integer;
+ Stream: PAVStream;
+begin
+ // find the first audio stream
+ StreamIndex := -1;
+
+ for i := 0 to FormatCtx^.nb_streams-1 do
+ begin
+ Stream := FormatCtx^.streams[i];
+
+ if (Stream.codec^.codec_type = CODEC_TYPE_AUDIO) then
+ begin
+ StreamIndex := i;
+ Break;
+ end;
+ end;
+
+ Result := StreamIndex;
+end;
+
+function TMediaCore_FFmpeg.ConvertFFmpegToAudioFormat(FFmpegFormat: TSampleFormat; out Format: TAudioSampleFormat): boolean;
+begin
+ case FFmpegFormat of
+ SAMPLE_FMT_U8: Format := asfU8;
+ SAMPLE_FMT_S16: Format := asfS16;
+ SAMPLE_FMT_S24: Format := asfS24;
+ SAMPLE_FMT_S32: Format := asfS32;
+ SAMPLE_FMT_FLT: Format := asfFloat;
+ else begin
+ Result := false;
+ Exit;
+ end;
+ end;
+ Result := true;
+end;
+
+{ TPacketQueue }
+
+constructor TPacketQueue.Create();
+begin
+ inherited;
+
+ FirstListEntry := nil;
+ LastListEntry := nil;
+ PacketCount := 0;
+ Size := 0;
+
+ Mutex := SDL_CreateMutex();
+ Condition := SDL_CreateCond();
+end;
+
+destructor TPacketQueue.Destroy();
+begin
+ Flush();
+ SDL_DestroyMutex(Mutex);
+ SDL_DestroyCond(Condition);
+ inherited;
+end;
+
+procedure TPacketQueue.Abort();
+begin
+ SDL_LockMutex(Mutex);
+
+ AbortRequest := true;
+
+ SDL_CondBroadcast(Condition);
+ SDL_UnlockMutex(Mutex);
+end;
+
+function TPacketQueue.IsAborted(): boolean;
+begin
+ SDL_LockMutex(Mutex);
+ Result := AbortRequest;
+ SDL_UnlockMutex(Mutex);
+end;
+
+function TPacketQueue.Put(Packet : PAVPacket): integer;
+var
+ CurrentListEntry : PAVPacketList;
+begin
+ Result := -1;
+
+ if (Packet = nil) then
+ Exit;
+
+ if (PChar(Packet^.data) <> STATUS_PACKET) then
+ begin
+ if (av_dup_packet(Packet) < 0) then
+ Exit;
+ end;
+
+ CurrentListEntry := av_malloc(SizeOf(TAVPacketList));
+ if (CurrentListEntry = nil) then
+ Exit;
+
+ CurrentListEntry^.pkt := Packet^;
+ CurrentListEntry^.next := nil;
+
+ SDL_LockMutex(Mutex);
+ try
+ if (LastListEntry = nil) then
+ FirstListEntry := CurrentListEntry
+ else
+ LastListEntry^.next := CurrentListEntry;
+
+ LastListEntry := CurrentListEntry;
+ Inc(PacketCount);
+
+ Size := Size + CurrentListEntry^.pkt.size;
+ SDL_CondSignal(Condition);
+ finally
+ SDL_UnlockMutex(Mutex);
+ end;
+
+ Result := 0;
+end;
+
+(**
+ * Adds a status packet (EOF, Flush, etc.) to the end of the queue.
+ * StatusInfo can be used to pass additional information to the decoder.
+ * Only assign nil or a valid pointer to data allocated with Getmem() to
+ * StatusInfo because the pointer will be disposed with Freemem() on a call
+ * to Flush(). If the packet is removed from the queue it is the decoder's
+ * responsibility to free the StatusInfo data with FreeStatusInfo().
+ *)
+function TPacketQueue.PutStatus(StatusFlag: integer; StatusInfo: Pointer): integer;
+var
+ TempPacket: PAVPacket;
+begin
+ // create temp. package
+ TempPacket := av_malloc(SizeOf(TAVPacket));
+ if (TempPacket = nil) then
+ begin
+ Result := -1;
+ Exit;
+ end;
+ // init package
+ av_init_packet(TempPacket^);
+ TempPacket^.data := Pointer(STATUS_PACKET);
+ TempPacket^.flags := StatusFlag;
+ TempPacket^.priv := StatusInfo;
+ // put a copy of the package into the queue
+ Result := Put(TempPacket);
+ // data has been copied -> delete temp. package
+ av_free(TempPacket);
+end;
+
+procedure TPacketQueue.FreeStatusInfo(var Packet: TAVPacket);
+begin
+ if (Packet.priv <> nil) then
+ FreeMem(Packet.priv);
+end;
+
+function TPacketQueue.GetStatusInfo(var Packet: TAVPacket): Pointer;
+begin
+ Result := Packet.priv;
+end;
+
+function TPacketQueue.Get(var Packet: TAVPacket; Blocking: boolean): integer;
+var
+ CurrentListEntry: PAVPacketList;
+const
+ WAIT_TIMEOUT = 10; // timeout in ms
+begin
+ Result := -1;
+
+ SDL_LockMutex(Mutex);
+ try
+ while (true) do
+ begin
+ if (AbortRequest) then
+ Exit;
+
+ CurrentListEntry := FirstListEntry;
+ if (CurrentListEntry <> nil) then
+ begin
+ FirstListEntry := CurrentListEntry^.next;
+ if (FirstListEntry = nil) then
+ LastListEntry := nil;
+ Dec(PacketCount);
+
+ Size := Size - CurrentListEntry^.pkt.size;
+ Packet := CurrentListEntry^.pkt;
+ av_free(CurrentListEntry);
+
+ Result := 1;
+ Break;
+ end
+ else if (not Blocking) then
+ begin
+ Result := 0;
+ Break;
+ end
+ else
+ begin
+ // block until a new package arrives,
+ // but do not wait till infinity to avoid deadlocks
+ if (SDL_CondWaitTimeout(Condition, Mutex, WAIT_TIMEOUT) = SDL_MUTEX_TIMEDOUT) then
+ begin
+ Result := 0;
+ Break;
+ end;
+ end;
+ end;
+ finally
+ SDL_UnlockMutex(Mutex);
+ end;
+end;
+
+function TPacketQueue.GetSize(): integer;
+begin
+ SDL_LockMutex(Mutex);
+ Result := Size;
+ SDL_UnlockMutex(Mutex);
+end;
+
+procedure TPacketQueue.Flush();
+var
+ CurrentListEntry, TempListEntry: PAVPacketList;
+begin
+ SDL_LockMutex(Mutex);
+
+ CurrentListEntry := FirstListEntry;
+ while(CurrentListEntry <> nil) do
+ begin
+ TempListEntry := CurrentListEntry^.next;
+ // free status data
+ if (PChar(CurrentListEntry^.pkt.data) = STATUS_PACKET) then
+ FreeStatusInfo(CurrentListEntry^.pkt);
+ // free packet data
+ av_free_packet(@CurrentListEntry^.pkt);
+ // Note: param must be a pointer to a pointer!
+ av_freep(@CurrentListEntry);
+ CurrentListEntry := TempListEntry;
+ end;
+ LastListEntry := nil;
+ FirstListEntry := nil;
+ PacketCount := 0;
+ Size := 0;
+
+ SDL_UnlockMutex(Mutex);
+end;
+
+end.
diff --git a/src/Classes/UMediaCore_SDL.pas b/src/Classes/UMediaCore_SDL.pas
new file mode 100644
index 00000000..252f72a0
--- /dev/null
+++ b/src/Classes/UMediaCore_SDL.pas
@@ -0,0 +1,38 @@
+unit UMediaCore_SDL;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMusic,
+ sdl;
+
+function ConvertAudioFormatToSDL(Format: TAudioSampleFormat; out SDLFormat: UInt16): boolean;
+
+implementation
+
+function ConvertAudioFormatToSDL(Format: TAudioSampleFormat; out SDLFormat: UInt16): boolean;
+begin
+ case Format of
+ asfU8: SDLFormat := AUDIO_U8;
+ asfS8: SDLFormat := AUDIO_S8;
+ asfU16LSB: SDLFormat := AUDIO_U16LSB;
+ asfS16LSB: SDLFormat := AUDIO_S16LSB;
+ asfU16MSB: SDLFormat := AUDIO_U16MSB;
+ asfS16MSB: SDLFormat := AUDIO_S16MSB;
+ asfU16: SDLFormat := AUDIO_U16;
+ asfS16: SDLFormat := AUDIO_S16;
+ else begin
+ Result := false;
+ Exit;
+ end;
+ end;
+ Result := true;
+end;
+
+end.
diff --git a/src/Classes/UMedia_dummy.pas b/src/Classes/UMedia_dummy.pas
new file mode 100644
index 00000000..438b89ab
--- /dev/null
+++ b/src/Classes/UMedia_dummy.pas
@@ -0,0 +1,243 @@
+unit UMedia_dummy;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+implementation
+
+uses
+ SysUtils,
+ math,
+ UMusic;
+
+type
+ TMedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput )
+ private
+ DummyOutputDeviceList: TAudioOutputDeviceList;
+ public
+ constructor Create();
+ function GetName: string;
+
+ function Init(): boolean;
+ function Finalize(): boolean;
+
+ function Open(const aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure SetSyncSource(SyncSource: TSyncSource);
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+
+ // IAudioInput
+ function InitializeRecord: boolean;
+ function FinalizeRecord: boolean;
+ procedure CaptureStart;
+ procedure CaptureStop;
+ procedure GetFFTData(var data: TFFTData);
+ function GetPCMData(var data: TPCMData): Cardinal;
+
+ // IAudioPlayback
+ function InitializePlayback: boolean;
+ function FinalizePlayback: boolean;
+
+ function GetOutputDeviceList(): TAudioOutputDeviceList;
+ procedure FadeIn(Time: real; TargetVolume: single);
+ procedure SetAppVolume(Volume: single);
+ procedure SetVolume(Volume: single);
+ procedure SetLoop(Enabled: boolean);
+ procedure Rewind;
+
+ function Finished: boolean;
+ function Length: real;
+
+ function OpenSound(const Filename: string): TAudioPlaybackStream;
+ procedure CloseSound(var PlaybackStream: TAudioPlaybackStream);
+ procedure PlaySound(stream: TAudioPlaybackStream);
+ procedure StopSound(stream: TAudioPlaybackStream);
+
+ function CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+ procedure CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
+ end;
+
+function TMedia_dummy.GetName: string;
+begin
+ Result := 'dummy';
+end;
+
+procedure TMedia_dummy.GetFrame(Time: Extended);
+begin
+end;
+
+procedure TMedia_dummy.DrawGL(Screen: integer);
+begin
+end;
+
+constructor TMedia_dummy.Create();
+begin
+ inherited;
+end;
+
+function TMedia_dummy.Init(): boolean;
+begin
+ Result := true;
+end;
+
+function TMedia_dummy.Finalize(): boolean;
+begin
+ Result := true;
+end;
+
+function TMedia_dummy.Open(const aFileName : string): boolean; // true if succeed
+begin
+ Result := false;
+end;
+
+procedure TMedia_dummy.Close;
+begin
+end;
+
+procedure TMedia_dummy.Play;
+begin
+end;
+
+procedure TMedia_dummy.Pause;
+begin
+end;
+
+procedure TMedia_dummy.Stop;
+begin
+end;
+
+procedure TMedia_dummy.SetPosition(Time: real);
+begin
+end;
+
+function TMedia_dummy.GetPosition: real;
+begin
+ Result := 0;
+end;
+
+procedure TMedia_dummy.SetSyncSource(SyncSource: TSyncSource);
+begin
+end;
+
+// IAudioInput
+function TMedia_dummy.InitializeRecord: boolean;
+begin
+ Result := true;
+end;
+
+function TMedia_dummy.FinalizeRecord: boolean;
+begin
+ Result := true;
+end;
+
+procedure TMedia_dummy.CaptureStart;
+begin
+end;
+
+procedure TMedia_dummy.CaptureStop;
+begin
+end;
+
+procedure TMedia_dummy.GetFFTData(var data: TFFTData);
+begin
+end;
+
+function TMedia_dummy.GetPCMData(var data: TPCMData): Cardinal;
+begin
+ Result := 0;
+end;
+
+// IAudioPlayback
+function TMedia_dummy.InitializePlayback: boolean;
+begin
+ SetLength(DummyOutputDeviceList, 1);
+ DummyOutputDeviceList[0] := TAudioOutputDevice.Create();
+ DummyOutputDeviceList[0].Name := '[Dummy Device]';
+ Result := true;
+end;
+
+function TMedia_dummy.FinalizePlayback: boolean;
+begin
+ Result := true;
+end;
+
+function TMedia_dummy.GetOutputDeviceList(): TAudioOutputDeviceList;
+begin
+ Result := DummyOutputDeviceList;
+end;
+
+procedure TMedia_dummy.SetAppVolume(Volume: single);
+begin
+end;
+
+procedure TMedia_dummy.SetVolume(Volume: single);
+begin
+end;
+
+procedure TMedia_dummy.SetLoop(Enabled: boolean);
+begin
+end;
+
+procedure TMedia_dummy.FadeIn(Time: real; TargetVolume: single);
+begin
+end;
+
+procedure TMedia_dummy.Rewind;
+begin
+end;
+
+function TMedia_dummy.Finished: boolean;
+begin
+ Result := false;
+end;
+
+function TMedia_dummy.Length: real;
+begin
+ Result := 60;
+end;
+
+function TMedia_dummy.OpenSound(const Filename: string): TAudioPlaybackStream;
+begin
+ Result := nil;
+end;
+
+procedure TMedia_dummy.CloseSound(var PlaybackStream: TAudioPlaybackStream);
+begin
+end;
+
+procedure TMedia_dummy.PlaySound(stream: TAudioPlaybackStream);
+begin
+end;
+
+procedure TMedia_dummy.StopSound(stream: TAudioPlaybackStream);
+begin
+end;
+
+function TMedia_dummy.CreateVoiceStream(Channel: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+begin
+ Result := nil;
+end;
+
+procedure TMedia_dummy.CloseVoiceStream(var VoiceStream: TAudioVoiceStream);
+begin
+end;
+
+initialization
+ MediaManager.Add(TMedia_dummy.Create);
+
+end.
diff --git a/src/Classes/UModules.pas b/src/Classes/UModules.pas
new file mode 100644
index 00000000..554a24c4
--- /dev/null
+++ b/src/Classes/UModules.pas
@@ -0,0 +1,26 @@
+unit UModules;
+
+interface
+
+{$I switches.inc}
+
+{*********************
+ UModules
+ Unit Contains all used Modules in its uses clausel
+ and a const with an array of all Modules to load
+*********************}
+
+uses
+ UCoreModule,
+ UPluginLoader;
+
+const
+ CORE_MODULES_TO_LOAD: Array[0..2] of cCoreModule = (
+ TPluginLoader, //First because it has to look if there are Module replacements (Feature o/t Future)
+ TCoreModule, //Remove this later, just a dummy
+ TtehPlugins //Represents the Plugins. Last because they may use CoreModules Services etc.
+ );
+
+implementation
+
+end.
\ No newline at end of file
diff --git a/src/Classes/UMusic.pas b/src/Classes/UMusic.pas
new file mode 100644
index 00000000..6476f629
--- /dev/null
+++ b/src/Classes/UMusic.pas
@@ -0,0 +1,1233 @@
+unit UMusic;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UTime,
+ Classes;
+
+type
+ TNoteType = (ntFreestyle, ntNormal, ntGolden);
+
+ (**
+ * TLineFragment represents a fragment of a lyrics line.
+ * This is a text-fragment (e.g. a syllable) assigned to a note pitch,
+ * represented by a bar in the sing-screen.
+ *)
+ PLineFragment = ^TLineFragment;
+ TLineFragment = record
+ Color: integer;
+ Start: integer; // beat the fragment starts at
+ Length: integer; // length in beats
+ Tone: integer; // full range tone
+ Text: string; // text assigned to this fragment (a syllable, word, etc.)
+ NoteType: TNoteType; // note-type: golden-note/freestyle etc.
+ end;
+
+ (**
+ * TLine represents one lyrics line and consists of multiple
+ * notes.
+ *)
+ PLine = ^TLine;
+ TLine = record
+ Start: integer; // the start beat of this line (<> start beat of the first note of this line)
+ Lyric: string;
+ LyricWidth: real; // @deprecated: width of the line in pixels.
+ // Do not use this as the width is not correct.
+ // Use TLyricsEngine.GetUpperLine().Width instead.
+ End_: integer;
+ BaseNote: integer;
+ HighNote: integer; // index of last note in line (= High(Note)?)
+ TotalNotes: integer; // value of all notes in the line
+ LastLine: boolean;
+ Note: array of TLineFragment;
+ end;
+
+ (**
+ * TLines stores sets of lyric lines and information on them.
+ * Normally just one set is defined but in duet mode it might for example
+ * contain two sets.
+ *)
+ TLines = record
+ Current: integer; // for drawing of current line
+ High: integer; // (= High(Line)?)
+ Number: integer;
+ Resolution: integer;
+ NotesGAP: integer;
+ ScoreValue: integer;
+ Line: array of TLine;
+ end;
+
+ (**
+ * TLyricsState contains all information concerning the
+ * state of the lyrics, e.g. the current beat or duration of the lyrics.
+ *)
+ TLyricsState = class
+ private
+ Timer: TRelativeTimer; // keeps track of the current time
+ public
+ OldBeat: integer; // previous discovered beat
+ CurrentBeat: integer; // current beat (rounded)
+ MidBeat: real; // current beat (float)
+
+ // now we use this for super synchronization!
+ // only used when analyzing voice
+ // TODO: change ...D to ...Detect(ed)
+ OldBeatD: integer; // previous discovered beat
+ CurrentBeatD: integer; // current discovered beat (rounded)
+ MidBeatD: real; // current discovered beat (float)
+
+ // we use this for audible clicks
+ // TODO: Change ...C to ...Click
+ OldBeatC: integer; // previous discovered beat
+ CurrentBeatC: integer;
+ MidBeatC: real; // like CurrentBeatC
+
+ OldLine: integer; // previous displayed sentence
+
+ StartTime: real; // time till start of lyrics (= Gap)
+ TotalTime: real; // total song time
+
+ constructor Create();
+ procedure Pause();
+ procedure Resume();
+
+ procedure Reset();
+ procedure UpdateBeats();
+
+ (**
+ * current song time (in seconds) used as base-timer for lyrics etc.
+ *)
+ function GetCurrentTime(): real;
+ procedure SetCurrentTime(Time: real);
+ end;
+
+
+const
+ FFTSize = 512; // size of FFT data (output: FFTSize/2 values)
+type
+ TFFTData = array[0..(FFTSize div 2)-1] of Single;
+
+type
+ PPCMStereoSample = ^TPCMStereoSample;
+ TPCMStereoSample = array[0..1] of SmallInt;
+ TPCMData = array[0..511] of TPCMStereoSample;
+
+type
+ TStreamStatus = (ssStopped, ssPlaying, ssPaused);
+const
+ StreamStatusStr: array[TStreamStatus] of string =
+ ('Stopped', 'Playing', 'Paused');
+
+type
+ TAudioSampleFormat = (
+ asfU8, asfS8, // unsigned/signed 8 bits
+ asfU16LSB, asfS16LSB, // unsigned/signed 16 bits (endianness: LSB)
+ asfU16MSB, asfS16MSB, // unsigned/signed 16 bits (endianness: MSB)
+ asfU16, asfS16, // unsigned/signed 16 bits (endianness: System)
+ asfS24, // signed 24 bits (endianness: System)
+ asfS32, // signed 32 bits (endianness: System)
+ asfFloat // float
+ );
+
+const
+ // Size of one sample (one channel only) in bytes
+ AudioSampleSize: array[TAudioSampleFormat] of integer = (
+ 1, 1, // asfU8, asfS8
+ 2, 2, // asfU16LSB, asfS16LSB
+ 2, 2, // asfU16MSB, asfS16MSB
+ 2, 2, // asfU16, asfS16
+ 3, // asfS24
+ 4, // asfS32
+ 4 // asfFloat
+ );
+
+const
+ CHANNELMAP_LEFT = 1;
+ CHANNELMAP_RIGHT = 2;
+ CHANNELMAP_FRONT = CHANNELMAP_LEFT or CHANNELMAP_RIGHT;
+
+type
+ TAudioFormatInfo = class
+ private
+ fSampleRate : double;
+ fChannels : byte;
+ fFormat : TAudioSampleFormat;
+ fFrameSize : integer;
+
+ procedure SetChannels(Channels: byte);
+ procedure SetFormat(Format: TAudioSampleFormat);
+ procedure UpdateFrameSize();
+ function GetBytesPerSec(): double;
+ public
+ constructor Create(Channels: byte; SampleRate: double; Format: TAudioSampleFormat);
+ function Copy(): TAudioFormatInfo;
+
+ (**
+ * Returns the inverse ratio of the size of data in this format to its
+ * size in a given target format.
+ * Example: SrcSize*SrcInfo.GetRatio(TgtInfo) = TgtSize
+ *)
+ function GetRatio(TargetInfo: TAudioFormatInfo): double;
+
+ property SampleRate: double read fSampleRate write fSampleRate;
+ property Channels: byte read fChannels write SetChannels;
+ property Format: TAudioSampleFormat read fFormat write SetFormat;
+ property FrameSize: integer read fFrameSize;
+ property BytesPerSec: double read GetBytesPerSec;
+ end;
+
+type
+ TSoundEffect = class
+ public
+ EngineData: Pointer; // can be used for engine-specific data
+ procedure Callback(Buffer: PChar; BufSize: integer); virtual; abstract;
+ end;
+
+ TVoiceRemoval = class(TSoundEffect)
+ public
+ procedure Callback(Buffer: PChar; BufSize: integer); override;
+ end;
+
+type
+ TSyncSource = class
+ function GetClock(): real; virtual; abstract;
+ end;
+
+ TAudioProcessingStream = class;
+ TOnCloseHandler = procedure(Stream: TAudioProcessingStream);
+
+ TAudioProcessingStream = class
+ protected
+ OnCloseHandlers: array of TOnCloseHandler;
+
+ function GetLength(): real; virtual; abstract;
+ function GetPosition(): real; virtual; abstract;
+ procedure SetPosition(Time: real); virtual; abstract;
+ function GetLoop(): boolean; virtual; abstract;
+ procedure SetLoop(Enabled: boolean); virtual; abstract;
+
+ procedure PerformOnClose();
+ public
+ function GetAudioFormatInfo(): TAudioFormatInfo; virtual; abstract;
+ procedure Close(); virtual; abstract;
+
+ (**
+ * Adds a new OnClose action handler.
+ * The handlers are performed in the order they were added.
+ * If not stated explicitely, member-variables might have been invalidated
+ * already. So do not use any member (variable/method/...) if you are not
+ * sure it is valid.
+ *)
+ procedure AddOnCloseHandler(Handler: TOnCloseHandler);
+
+ property Length: real read GetLength;
+ property Position: real read GetPosition write SetPosition;
+ property Loop: boolean read GetLoop write SetLoop;
+ end;
+
+ TAudioSourceStream = class(TAudioProcessingStream)
+ protected
+ function IsEOF(): boolean; virtual; abstract;
+ function IsError(): boolean; virtual; abstract;
+ public
+ function ReadData(Buffer: PChar; BufferSize: integer): integer; virtual; abstract;
+
+ property EOF: boolean read IsEOF;
+ property Error: boolean read IsError;
+ end;
+
+ (*
+ * State-Chart for playback-stream state transitions
+ * []: Transition, (): State
+ *
+ * /---[Play/FadeIn]--->-\ /-------[Pause]----->-\
+ * -[Create]->(Stop) (Play) (Pause)
+ * \\-<-[Stop/EOF*/Error]-/ \-<---[Play/FadeIn]--//
+ * \-<------------[Stop/EOF*/Error]--------------/
+ *
+ * *: if not looped, otherwise stream is repeated
+ * Note: SetPosition() does not change the state.
+ *)
+
+ TAudioPlaybackStream = class(TAudioProcessingStream)
+ protected
+ SyncSource: TSyncSource;
+ AvgSyncDiff: double;
+ SourceStream: TAudioSourceStream;
+
+ function GetLatency(): double; virtual; abstract;
+ function GetStatus(): TStreamStatus; virtual; abstract;
+ function GetVolume(): single; virtual; abstract;
+ procedure SetVolume(Volume: single); virtual; abstract;
+ function Synchronize(BufferSize: integer; FormatInfo: TAudioFormatInfo): integer;
+ procedure FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
+ public
+ (**
+ * Opens a SourceStream for playback.
+ * Note that the caller (not the TAudioPlaybackStream) is responsible to
+ * free the SourceStream after the Playback-Stream is closed.
+ * You may use an OnClose-handler to achieve this. GetSourceStream()
+ * guarantees to deliver this method's SourceStream parameter to
+ * the OnClose-handler. Freeing SourceStream at OnClose is allowed.
+ *)
+ function Open(SourceStream: TAudioSourceStream): boolean; virtual; abstract;
+
+ procedure Play(); virtual; abstract;
+ procedure Pause(); virtual; abstract;
+ procedure Stop(); virtual; abstract;
+ procedure FadeIn(Time: real; TargetVolume: single); virtual; abstract;
+
+ procedure GetFFTData(var data: TFFTData); virtual; abstract;
+ function GetPCMData(var data: TPCMData): Cardinal; virtual; abstract;
+
+ procedure AddSoundEffect(Effect: TSoundEffect); virtual; abstract;
+ procedure RemoveSoundEffect(Effect: TSoundEffect); virtual; abstract;
+
+ procedure SetSyncSource(SyncSource: TSyncSource);
+ function GetSourceStream(): TAudioSourceStream;
+
+ property Status: TStreamStatus read GetStatus;
+ property Volume: single read GetVolume write SetVolume;
+ end;
+
+ TAudioDecodeStream = class(TAudioSourceStream)
+ end;
+
+ TAudioVoiceStream = class(TAudioSourceStream)
+ protected
+ FormatInfo: TAudioFormatInfo;
+ ChannelMap: integer;
+ public
+ destructor Destroy; override;
+
+ function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; virtual;
+ procedure Close(); override;
+
+ procedure WriteData(Buffer: PChar; BufferSize: integer); virtual; abstract;
+ function GetAudioFormatInfo(): TAudioFormatInfo; override;
+
+ function GetLength(): real; override;
+ function GetPosition(): real; override;
+ procedure SetPosition(Time: real); override;
+ function GetLoop(): boolean; override;
+ procedure SetLoop(Enabled: boolean); override;
+ end;
+
+type
+ // soundcard output-devices information
+ TAudioOutputDevice = class
+ public
+ Name: string; // soundcard name
+ end;
+ TAudioOutputDeviceList = array of TAudioOutputDevice;
+
+type
+ IGenericPlayback = Interface
+ ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCE33DD}']
+ function GetName: String;
+
+ function Open(const Filename: string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ property Position: real read GetPosition write SetPosition;
+ end;
+
+ IVideoPlayback = Interface( IGenericPlayback )
+ ['{3574C40C-28AE-4201-B3D1-3D1F0759B131}']
+ function Init(): boolean;
+ function Finalize: boolean;
+
+ procedure GetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC
+ procedure DrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC
+
+ end;
+
+ IVideoVisualization = Interface( IVideoPlayback )
+ ['{5AC17D60-B34D-478D-B632-EB00D4078017}']
+ end;
+
+ IAudioPlayback = Interface( IGenericPlayback )
+ ['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}']
+ function InitializePlayback: boolean;
+ function FinalizePlayback: boolean;
+
+ function GetOutputDeviceList(): TAudioOutputDeviceList;
+
+ procedure SetAppVolume(Volume: single);
+ procedure SetVolume(Volume: single);
+ procedure SetLoop(Enabled: boolean);
+
+ procedure FadeIn(Time: real; TargetVolume: single);
+ procedure SetSyncSource(SyncSource: TSyncSource);
+
+ procedure Rewind;
+ function Finished: boolean;
+ function Length: real;
+
+ // Sounds
+ // TODO:
+ // add a TMediaDummyPlaybackStream implementation that will
+ // be used by the TSoundLib whenever OpenSound() fails, so checking for
+ // nil-pointers is not neccessary anymore.
+ // PlaySound/StopSound will be removed then, OpenSound will be renamed to
+ // CreateSound.
+ function OpenSound(const Filename: String): TAudioPlaybackStream;
+ procedure PlaySound(Stream: TAudioPlaybackStream);
+ procedure StopSound(Stream: TAudioPlaybackStream);
+
+ // Equalizer
+ procedure GetFFTData(var Data: TFFTData);
+
+ // Interface for Visualizer
+ function GetPCMData(var Data: TPCMData): Cardinal;
+
+ function CreateVoiceStream(ChannelMap: integer; FormatInfo: TAudioFormatInfo): TAudioVoiceStream;
+ end;
+
+ IGenericDecoder = Interface
+ ['{557B0E9A-604D-47E4-B826-13769F3E10B7}']
+ function GetName(): String;
+ function InitializeDecoder(): boolean;
+ function FinalizeDecoder(): boolean;
+ //function IsSupported(const Filename: string): boolean;
+ end;
+
+ (*
+ IVideoDecoder = Interface( IGenericDecoder )
+ ['{2F184B2B-FE69-44D5-9031-0A2462391DCA}']
+ function Open(const Filename: string): TVideoDecodeStream;
+ end;
+ *)
+
+ IAudioDecoder = Interface( IGenericDecoder )
+ ['{AB47B1B6-2AA9-4410-BF8C-EC79561B5478}']
+ function Open(const Filename: string): TAudioDecodeStream;
+ end;
+
+ IAudioInput = Interface
+ ['{A5C8DA92-2A0C-4AB2-849B-2F7448C6003A}']
+ function GetName: String;
+ function InitializeRecord: boolean;
+ function FinalizeRecord(): boolean;
+
+ procedure CaptureStart;
+ procedure CaptureStop;
+ end;
+
+type
+ TAudioConverter = class
+ protected
+ fSrcFormatInfo: TAudioFormatInfo;
+ fDstFormatInfo: TAudioFormatInfo;
+ public
+ function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; virtual;
+ destructor Destroy(); override;
+
+ (**
+ * Converts the InputBuffer and stores the result in OutputBuffer.
+ * If the result is not -1, InputSize will be set to the actual number of
+ * input-buffer bytes used.
+ * Returns the number of bytes written to the output-buffer or -1 if an error occured.
+ *)
+ function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; virtual; abstract;
+
+ (**
+ * Destination/Source size ratio
+ *)
+ function GetRatio(): double; virtual; abstract;
+
+ function GetOutputBufferSize(InputSize: integer): integer; virtual; abstract;
+ property SrcFormatInfo: TAudioFormatInfo read fSrcFormatInfo;
+ property DstFormatInfo: TAudioFormatInfo read fDstFormatInfo;
+ end;
+
+(* TODO
+const
+ SOUNDID_START = 0;
+ SOUNDID_BACK = 1;
+ SOUNDID_SWOOSH = 2;
+ SOUNDID_CHANGE = 3;
+ SOUNDID_OPTION = 4;
+ SOUNDID_CLICK = 5;
+ LAST_SOUNDID = SOUNDID_CLICK;
+
+ BaseSoundFilenames: array[0..LAST_SOUNDID] of string = (
+ '%SOUNDPATH%/Common start.mp3', // Start
+ '%SOUNDPATH%/Common back.mp3', // Back
+ '%SOUNDPATH%/menu swoosh.mp3', // Swoosh
+ '%SOUNDPATH%/select music change music 50.mp3', // Change
+ '%SOUNDPATH%/option change col.mp3', // Option
+ '%SOUNDPATH%/rimshot022b.mp3' // Click
+ {
+ '%SOUNDPATH%/bassdrumhard076b.mp3', // Drum (unused)
+ '%SOUNDPATH%/hihatclosed068b.mp3', // Hihat (unused)
+ '%SOUNDPATH%/claps050b.mp3', // Clap (unused)
+ '%SOUNDPATH%/Shuffle.mp3' // Shuffle (unused)
+ }
+ );
+*)
+
+type
+ TSoundLibrary = class
+ private
+ // TODO
+ //Sounds: array of TAudioPlaybackStream;
+ public
+ // TODO: move sounds to the private section
+ // and provide IDs instead.
+ Start: TAudioPlaybackStream;
+ Back: TAudioPlaybackStream;
+ Swoosh: TAudioPlaybackStream;
+ Change: TAudioPlaybackStream;
+ Option: TAudioPlaybackStream;
+ Click: TAudioPlaybackStream;
+ BGMusic: TAudioPlaybackStream;
+
+ constructor Create();
+ destructor Destroy(); override;
+
+ procedure LoadSounds();
+ procedure UnloadSounds();
+
+ procedure StartBgMusic();
+ procedure PauseBgMusic();
+ // TODO
+ //function AddSound(Filename: string): integer;
+ //procedure RemoveSound(ID: integer);
+ //function GetSound(ID: integer): TAudioPlaybackStream;
+ //property Sound[ID: integer]: TAudioPlaybackStream read GetSound; default;
+ end;
+
+var
+ // TODO: JB --- THESE SHOULD NOT BE GLOBAL
+ Lines: array of TLines;
+ LyricsState: TLyricsState;
+ SoundLib: TSoundLibrary;
+
+
+procedure InitializeSound;
+procedure InitializeVideo;
+procedure FinalizeMedia;
+
+function Visualization(): IVideoPlayback;
+function VideoPlayback(): IVideoPlayback;
+function AudioPlayback(): IAudioPlayback;
+function AudioInput(): IAudioInput;
+function AudioDecoders(): TInterfaceList;
+
+function MediaManager: TInterfaceList;
+
+procedure DumpMediaInterfaces();
+
+implementation
+
+uses
+ sysutils,
+ math,
+ UIni,
+ UMain,
+ UCommandLine,
+ URecord,
+ ULog;
+
+var
+ DefaultVideoPlayback : IVideoPlayback;
+ DefaultVisualization : IVideoPlayback;
+ DefaultAudioPlayback : IAudioPlayback;
+ DefaultAudioInput : IAudioInput;
+ AudioDecoderList : TInterfaceList;
+ MediaInterfaceList : TInterfaceList;
+
+
+constructor TAudioFormatInfo.Create(Channels: byte; SampleRate: double; Format: TAudioSampleFormat);
+begin
+ inherited Create();
+ fChannels := Channels;
+ fSampleRate := SampleRate;
+ fFormat := Format;
+ UpdateFrameSize();
+end;
+
+procedure TAudioFormatInfo.SetChannels(Channels: byte);
+begin
+ fChannels := Channels;
+ UpdateFrameSize();
+end;
+
+procedure TAudioFormatInfo.SetFormat(Format: TAudioSampleFormat);
+begin
+ fFormat := Format;
+ UpdateFrameSize();
+end;
+
+function TAudioFormatInfo.GetBytesPerSec(): double;
+begin
+ Result := FrameSize * SampleRate;
+end;
+
+procedure TAudioFormatInfo.UpdateFrameSize();
+begin
+ fFrameSize := AudioSampleSize[fFormat] * fChannels;
+end;
+
+function TAudioFormatInfo.Copy(): TAudioFormatInfo;
+begin
+ Result := TAudioFormatInfo.Create(Self.Channels, Self.SampleRate, Self.Format);
+end;
+
+function TAudioFormatInfo.GetRatio(TargetInfo: TAudioFormatInfo): double;
+begin
+ Result := (TargetInfo.FrameSize / Self.FrameSize) *
+ (TargetInfo.SampleRate / Self.SampleRate)
+end;
+
+
+function MediaManager: TInterfaceList;
+begin
+ if (not assigned(MediaInterfaceList)) then
+ MediaInterfaceList := TInterfaceList.Create();
+ Result := MediaInterfaceList;
+end;
+
+function VideoPlayback(): IVideoPlayback;
+begin
+ Result := DefaultVideoPlayback;
+end;
+
+function Visualization(): IVideoPlayback;
+begin
+ Result := DefaultVisualization;
+end;
+
+function AudioPlayback(): IAudioPlayback;
+begin
+ Result := DefaultAudioPlayback;
+end;
+
+function AudioInput(): IAudioInput;
+begin
+ Result := DefaultAudioInput;
+end;
+
+function AudioDecoders(): TInterfaceList;
+begin
+ Result := AudioDecoderList;
+end;
+
+procedure FilterInterfaceList(const IID: TGUID; InList, OutList: TInterfaceList);
+var
+ i: integer;
+ obj: IInterface;
+begin
+ if (not assigned(OutList)) then
+ Exit;
+
+ OutList.Clear;
+ for i := 0 to InList.Count-1 do
+ begin
+ if assigned(InList[i]) then
+ begin
+ // add object to list if it implements the interface searched for
+ if (InList[i].QueryInterface(IID, obj) = 0) then
+ OutList.Add(obj);
+ end;
+ end;
+end;
+
+procedure InitializeSound;
+var
+ i: integer;
+ InterfaceList: TInterfaceList;
+ CurrentAudioDecoder: IAudioDecoder;
+ CurrentAudioPlayback: IAudioPlayback;
+ CurrentAudioInput: IAudioInput;
+begin
+ // create a temporary list for interface enumeration
+ InterfaceList := TInterfaceList.Create();
+
+ // initialize all audio-decoders first
+ FilterInterfaceList(IAudioDecoder, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ begin
+ CurrentAudioDecoder := IAudioDecoder(InterfaceList[i]);
+ if (not CurrentAudioDecoder.InitializeDecoder()) then
+ begin
+ Log.LogError('Initialize failed, Removing - '+ CurrentAudioDecoder.GetName);
+ MediaManager.Remove(CurrentAudioDecoder);
+ end;
+ end;
+
+ // create and setup decoder-list (see AudioDecoders())
+ AudioDecoderList := TInterfaceList.Create;
+ FilterInterfaceList(IAudioDecoder, MediaManager, AudioDecoders);
+
+ // find and initialize playback interface
+ DefaultAudioPlayback := nil;
+ FilterInterfaceList(IAudioPlayback, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ begin
+ CurrentAudioPlayback := IAudioPlayback(InterfaceList[i]);
+ if (CurrentAudioPlayback.InitializePlayback()) then
+ begin
+ DefaultAudioPlayback := CurrentAudioPlayback;
+ break;
+ end;
+ Log.LogError('Initialize failed, Removing - '+ CurrentAudioPlayback.GetName);
+ MediaManager.Remove(CurrentAudioPlayback);
+ end;
+
+ // find and initialize input interface
+ DefaultAudioInput := nil;
+ FilterInterfaceList(IAudioInput, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ begin
+ CurrentAudioInput := IAudioInput(InterfaceList[i]);
+ if (CurrentAudioInput.InitializeRecord()) then
+ begin
+ DefaultAudioInput := CurrentAudioInput;
+ break;
+ end;
+ Log.LogError('Initialize failed, Removing - '+ CurrentAudioInput.GetName);
+ MediaManager.Remove(CurrentAudioInput);
+ end;
+
+ InterfaceList.Free;
+
+ // Update input-device list with registered devices
+ AudioInputProcessor.UpdateInputDeviceConfig();
+
+ // Load in-game sounds
+ SoundLib := TSoundLibrary.Create;
+end;
+
+procedure InitializeVideo();
+var
+ i: integer;
+ InterfaceList: TInterfaceList;
+ VideoInterface: IVideoPlayback;
+ VisualInterface: IVideoVisualization;
+begin
+ InterfaceList := TInterfaceList.Create;
+
+ // initialize and set video-playback singleton
+ DefaultVideoPlayback := nil;
+ FilterInterfaceList(IVideoPlayback, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ begin
+ VideoInterface := IVideoPlayback(InterfaceList[i]);
+ if (VideoInterface.Init()) then
+ begin
+ DefaultVideoPlayback := VideoInterface;
+ break;
+ end;
+ Log.LogError('Initialize failed, Removing - '+ VideoInterface.GetName);
+ MediaManager.Remove(VideoInterface);
+ end;
+
+ // initialize and set visualization singleton
+ DefaultVisualization := nil;
+ FilterInterfaceList(IVideoVisualization, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ begin
+ VisualInterface := IVideoVisualization(InterfaceList[i]);
+ if (VisualInterface.Init()) then
+ begin
+ DefaultVisualization := VisualInterface;
+ break;
+ end;
+ Log.LogError('Initialize failed, Removing - '+ VisualInterface.GetName);
+ MediaManager.Remove(VisualInterface);
+ end;
+
+ InterfaceList.Free;
+
+ // now that we have all interfaces, we can dump them
+ // TODO: move this to another place
+ if FindCmdLineSwitch( cMediaInterfaces ) then
+ begin
+ DumpMediaInterfaces();
+ halt;
+ end;
+end;
+
+procedure UnloadMediaModules;
+var
+ i: integer;
+ InterfaceList: TInterfaceList;
+begin
+ FreeAndNil(AudioDecoderList);
+ DefaultAudioPlayback := nil;
+ DefaultAudioInput := nil;
+ DefaultVideoPlayback := nil;
+ DefaultVisualization := nil;
+
+ // create temporary interface list
+ InterfaceList := TInterfaceList.Create();
+
+ // finalize audio playback interfaces (should be done before the decoders)
+ FilterInterfaceList(IAudioPlayback, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ IAudioPlayback(InterfaceList[i]).FinalizePlayback();
+
+ // finalize audio input interfaces
+ FilterInterfaceList(IAudioInput, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ IAudioInput(InterfaceList[i]).FinalizeRecord();
+
+ // finalize audio decoder interfaces
+ FilterInterfaceList(IAudioDecoder, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ IAudioDecoder(InterfaceList[i]).FinalizeDecoder();
+
+ // finalize video interfaces
+ FilterInterfaceList(IVideoPlayback, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ IVideoPlayback(InterfaceList[i]).Finalize();
+
+ // finalize audio decoder interfaces
+ FilterInterfaceList(IVideoVisualization, MediaManager, InterfaceList);
+ for i := 0 to InterfaceList.Count-1 do
+ IVideoVisualization(InterfaceList[i]).Finalize();
+
+ InterfaceList.Free;
+
+ // finally free interfaces (by removing all references to them)
+ FreeAndNil(MediaInterfaceList);
+end;
+
+procedure FinalizeMedia;
+begin
+ // stop, close and free sounds
+ SoundLib.Free;
+
+ // stop and close music stream
+ if (AudioPlayback <> nil) then
+ AudioPlayback.Close;
+
+ // stop any active captures
+ if (AudioInput <> nil) then
+ AudioInput.CaptureStop;
+
+ if (VideoPlayback <> nil) then
+ VideoPlayback.Close;
+
+ if (Visualization <> nil) then
+ Visualization.Close;
+
+ UnloadMediaModules();
+end;
+
+procedure DumpMediaInterfaces();
+begin
+ writeln( '' );
+ writeln( '--------------------------------------------------------------' );
+ writeln( ' In-use Media Interfaces ' );
+ writeln( '--------------------------------------------------------------' );
+ writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName );
+ writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName );
+ writeln( 'Registered Video Playback Interface : ' + VideoPlayback.GetName );
+ writeln( 'Registered Visualization Interface : ' + Visualization.GetName );
+ writeln( '--------------------------------------------------------------' );
+ writeln( '' );
+end;
+
+
+{ TSoundLibrary }
+
+constructor TSoundLibrary.Create();
+begin
+ inherited;
+ LoadSounds();
+end;
+
+destructor TSoundLibrary.Destroy();
+begin
+ UnloadSounds();
+ inherited;
+end;
+
+procedure TSoundLibrary.LoadSounds();
+begin
+ UnloadSounds();
+
+ Start := AudioPlayback.OpenSound(SoundPath + 'Common start.mp3');
+ Back := AudioPlayback.OpenSound(SoundPath + 'Common back.mp3');
+ Swoosh := AudioPlayback.OpenSound(SoundPath + 'menu swoosh.mp3');
+ Change := AudioPlayback.OpenSound(SoundPath + 'select music change music 50.mp3');
+ Option := AudioPlayback.OpenSound(SoundPath + 'option change col.mp3');
+ Click := AudioPlayback.OpenSound(SoundPath + 'rimshot022b.mp3');
+
+ BGMusic := AudioPlayback.OpenSound(SoundPath + 'Bebeto_-_Loop010.mp3');
+
+ if (BGMusic <> nil) then
+ BGMusic.Loop := True;
+end;
+
+procedure TSoundLibrary.UnloadSounds();
+begin
+ FreeAndNil(Start);
+ FreeAndNil(Back);
+ FreeAndNil(Swoosh);
+ FreeAndNil(Change);
+ FreeAndNil(Option);
+ FreeAndNil(Click);
+ FreeAndNil(BGMusic);
+end;
+
+(* TODO
+function TSoundLibrary.GetSound(ID: integer): TAudioPlaybackStream;
+begin
+ if ((ID >= 0) and (ID < Length(Sounds))) then
+ Result := Sounds[ID]
+ else
+ Result := nil;
+end;
+*)
+
+procedure TSoundLibrary.StartBgMusic();
+begin
+ if (TBackgroundMusicOption(Ini.BackgroundMusicOption) = bmoOn) and
+ (Soundlib.BGMusic <> nil) and not (Soundlib.BGMusic.Status = ssPlaying) then
+ begin
+ AudioPlayback.PlaySound(Soundlib.BGMusic);
+ end;
+end;
+
+procedure TSoundLibrary.PauseBgMusic();
+begin
+ If (Soundlib.BGMusic <> nil) then
+ begin
+ Soundlib.BGMusic.Pause;
+ end;
+end;
+
+{ TVoiceRemoval }
+
+procedure TVoiceRemoval.Callback(Buffer: PChar; BufSize: integer);
+var
+ FrameIndex, FrameSize: integer;
+ Value: integer;
+ Sample: PPCMStereoSample;
+begin
+ FrameSize := 2 * SizeOf(SmallInt);
+ for FrameIndex := 0 to (BufSize div FrameSize)-1 do
+ begin
+ Sample := PPCMStereoSample(Buffer);
+ // channel difference
+ Value := Sample[0] - Sample[1];
+ // clip
+ if (Value > High(SmallInt)) then
+ Value := High(SmallInt)
+ else if (Value < Low(SmallInt)) then
+ Value := Low(SmallInt);
+ // assign result
+ Sample[0] := Value;
+ Sample[1] := Value;
+ // increase to next frame
+ Inc(Buffer, FrameSize);
+ end;
+end;
+
+
+{ TVoiceRemoval }
+
+constructor TLyricsState.Create();
+begin
+ // create a triggered timer, so we can Pause() it, set the time
+ // and Resume() it afterwards for better synching.
+ Timer := TRelativeTimer.Create(true);
+
+ // reset state
+ Reset();
+end;
+
+procedure TLyricsState.Pause();
+begin
+ Timer.Pause();
+end;
+
+procedure TLyricsState.Resume();
+begin
+ Timer.Resume();
+end;
+
+procedure TLyricsState.SetCurrentTime(Time: real);
+begin
+ // do not start the timer (if not started already),
+ // after setting the current time
+ Timer.SetTime(Time, false);
+end;
+
+function TLyricsState.GetCurrentTime(): real;
+begin
+ Result := Timer.GetTime();
+end;
+
+(**
+ * Resets the timer and state of the lyrics.
+ * The timer will be stopped afterwards so you have to call Resume()
+ * to start the lyrics timer.
+ *)
+procedure TLyricsState.Reset();
+begin
+ Pause();
+ SetCurrentTime(0);
+
+ StartTime := 0;
+ TotalTime := 0;
+
+ OldBeat := -1;
+ MidBeat := -1;
+ CurrentBeat := -1;
+
+ OldBeatC := -1;
+ MidBeatC := -1;
+ CurrentBeatC := -1;
+
+ OldBeatD := -1;
+ MidBeatD := -1;
+ CurrentBeatD := -1;
+end;
+
+(**
+ * Updates the beat information (CurrentBeat/MidBeat/...) according to the
+ * current lyric time.
+ *)
+procedure TLyricsState.UpdateBeats();
+var
+ CurLyricsTime: real;
+begin
+ CurLyricsTime := GetCurrentTime();
+
+ OldBeat := CurrentBeat;
+ MidBeat := GetMidBeat(CurLyricsTime - StartTime / 1000);
+ CurrentBeat := Floor(MidBeat);
+
+ OldBeatC := CurrentBeatC;
+ MidBeatC := GetMidBeat(CurLyricsTime - StartTime / 1000);
+ CurrentBeatC := Floor(MidBeatC);
+
+ OldBeatD := CurrentBeatD;
+ // MidBeatD = MidBeat with additional GAP
+ MidBeatD := -0.5 + GetMidBeat(CurLyricsTime - (StartTime + 120 + 20) / 1000);
+ CurrentBeatD := Floor(MidBeatD);
+end;
+
+
+{ TAudioConverter }
+
+function TAudioConverter.Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean;
+begin
+ fSrcFormatInfo := SrcFormatInfo.Copy();
+ fDstFormatInfo := DstFormatInfo.Copy();
+ Result := true;
+end;
+
+destructor TAudioConverter.Destroy();
+begin
+ FreeAndNil(fSrcFormatInfo);
+ FreeAndNil(fDstFormatInfo);
+end;
+
+
+{ TAudioProcessingStream }
+
+procedure TAudioProcessingStream.AddOnCloseHandler(Handler: TOnCloseHandler);
+begin
+ if (@Handler <> nil) then
+ begin
+ SetLength(OnCloseHandlers, System.Length(OnCloseHandlers)+1);
+ OnCloseHandlers[High(OnCloseHandlers)] := @Handler;
+ end;
+end;
+
+procedure TAudioProcessingStream.PerformOnClose();
+var i: integer;
+begin
+ for i := 0 to High(OnCloseHandlers) do
+ begin
+ OnCloseHandlers[i](Self);
+ end;
+end;
+
+
+{ TAudioPlaybackStream }
+
+function TAudioPlaybackStream.GetSourceStream(): TAudioSourceStream;
+begin
+ Result := SourceStream;
+end;
+
+procedure TAudioPlaybackStream.SetSyncSource(SyncSource: TSyncSource);
+begin
+ Self.SyncSource := SyncSource;
+ AvgSyncDiff := -1;
+end;
+
+(*
+ * Results an adjusted size of the input buffer size to keep the stream in sync
+ * with the SyncSource. If no SyncSource was assigned to this stream, the
+ * input buffer size will be returned, so this method will have no effect.
+ *
+ * These are the possible cases:
+ * - Result > BufferSize: stream is behind the sync-source (stream is too slow),
+ * (Result-BufferSize) bytes of the buffer must be skipped.
+ * - Result = BufferSize: stream is in sync,
+ * there is nothing to do.
+ * - Result < BufferSize: stream is ahead of the sync-source (stream is too fast),
+ * (BufferSize-Result) bytes of the buffer must be padded.
+ *)
+function TAudioPlaybackStream.Synchronize(BufferSize: integer; FormatInfo: TAudioFormatInfo): integer;
+var
+ TimeDiff: double;
+ TimeCorrectionFactor: double;
+const
+ AVG_HISTORY_FACTOR = 0.9;
+ SYNC_THRESHOLD = 0.045;
+ MAX_SYNC_DIFF_TIME = 0.002;
+begin
+ Result := BufferSize;
+
+ if (not assigned(SyncSource)) then
+ Exit;
+
+ if (BufferSize <= 0) then
+ Exit;
+
+ // difference between sync-source and stream position
+ // (negative if the music-stream's position is ahead of the master clock)
+ TimeDiff := SyncSource.GetClock() - (Position - GetLatency());
+
+ // calculate average time difference (some sort of weighted mean).
+ // The bigger AVG_HISTORY_FACTOR is, the smoother is the average diff.
+ // This means that older diffs are weighted more with a higher history factor
+ // than with a lower. Do not use a too low history factor. FFmpeg produces
+ // very instable timestamps (pts) for ogg due to some bugs. They may differ
+ // +-50ms from the real stream position. Without filtering those glitches we
+ // would synch without any need, resulting in ugly plopping sounds.
+ if (AvgSyncDiff = -1) then
+ AvgSyncDiff := TimeDiff
+ else
+ AvgSyncDiff := TimeDiff * (1-AVG_HISTORY_FACTOR) +
+ AvgSyncDiff * AVG_HISTORY_FACTOR;
+
+ // check if sync needed
+ if (Abs(AvgSyncDiff) >= SYNC_THRESHOLD) then
+ begin
+ // TODO: use SetPosition if diff is too large (>5s)
+ if (TimeDiff < 1) then
+ TimeCorrectionFactor := Sign(TimeDiff)*TimeDiff*TimeDiff
+ else
+ TimeCorrectionFactor := TimeDiff;
+
+ // calculate adapted buffer size
+ // reduce size of data to fetch if music is ahead, increase otherwise
+ Result := BufferSize + Round(TimeCorrectionFactor * FormatInfo.SampleRate) * FormatInfo.FrameSize;
+ if (Result < 0) then
+ Result := 0;
+
+ // reset average
+ AvgSyncDiff := -1;
+ end;
+
+ (*
+ DebugWriteln('Diff: ' + floattostrf(TimeDiff, ffFixed, 15, 3) +
+ '| SyS: ' + floattostrf(SyncSource.GetClock(), ffFixed, 15, 3) +
+ '| Pos: ' + floattostrf(Position, ffFixed, 15, 3) +
+ '| Avg: ' + floattostrf(AvgSyncDiff, ffFixed, 15, 3));
+ *)
+end;
+
+(*
+ * Fills a buffer with copies of the given frame or with 0 if frame.
+ *)
+procedure TAudioPlaybackStream.FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
+var
+ i: integer;
+ FrameCopyCount: integer;
+begin
+ // the buffer must at least contain place for one copy of the frame.
+ if ((Buffer = nil) or (BufferSize <= 0) or (BufferSize < FrameSize)) then
+ Exit;
+
+ // no valid frame -> fill with 0
+ if ((Frame = nil) or (FrameSize <= 0)) then
+ begin
+ FillChar(Buffer[0], BufferSize, 0);
+ Exit;
+ end;
+
+ // number of frames to copy
+ FrameCopyCount := BufferSize div FrameSize;
+ // insert as many copies of frame into the buffer as possible
+ for i := 0 to FrameCopyCount-1 do
+ Move(Frame[0], Buffer[i*FrameSize], FrameSize);
+end;
+
+{ TAudioVoiceStream }
+
+function TAudioVoiceStream.Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean;
+begin
+ Self.ChannelMap := ChannelMap;
+ Self.FormatInfo := FormatInfo.Copy();
+ // a voice stream is always mono, reassure the the format is correct
+ Self.FormatInfo.Channels := 1;
+ Result := true;
+end;
+
+destructor TAudioVoiceStream.Destroy;
+begin
+ Close();
+ inherited;
+end;
+
+procedure TAudioVoiceStream.Close();
+begin
+ PerformOnClose();
+ FreeAndNil(FormatInfo);
+end;
+
+function TAudioVoiceStream.GetAudioFormatInfo(): TAudioFormatInfo;
+begin
+ Result := FormatInfo;
+end;
+
+function TAudioVoiceStream.GetLength(): real;
+begin
+ Result := -1;
+end;
+
+function TAudioVoiceStream.GetPosition(): real;
+begin
+ Result := -1;
+end;
+
+procedure TAudioVoiceStream.SetPosition(Time: real);
+begin
+end;
+
+function TAudioVoiceStream.GetLoop(): boolean;
+begin
+ Result := false;
+end;
+
+procedure TAudioVoiceStream.SetLoop(Enabled: boolean);
+begin
+end;
+
+
+end.
diff --git a/src/Classes/UParty.pas b/src/Classes/UParty.pas
new file mode 100644
index 00000000..01a182b1
--- /dev/null
+++ b/src/Classes/UParty.pas
@@ -0,0 +1,630 @@
+unit UParty;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses UPartyDefs, UCoreModule, UPluginDefs;
+
+type
+ ARounds = Array [0..252] of Integer; //0..252 needed for
+ PARounds = ^ARounds;
+
+ TRoundInfo = record
+ Modi: Cardinal;
+ Winner: Byte;
+ end;
+
+ TeamOrderEntry = record
+ Teamnum: Byte;
+ Score: Byte;
+ end;
+
+ TeamOrderArray = Array[0..5] of Byte;
+
+ TUS_ModiInfoEx = record
+ Info: TUS_ModiInfo;
+ Owner: Integer;
+ TimesPlayed: Byte; //Helper for setting Round Plugins
+ end;
+
+ TPartySession = class (TCoreModule)
+ private
+ bPartyMode: Boolean; //Is this Party or Singleplayer
+ CurRound: Byte;
+
+ Modis: Array of TUS_ModiInfoEx;
+ Teams: TTeamInfo;
+
+ function IsWinner(Player, Winner: Byte): boolean;
+ procedure GenScores;
+ function GetRandomPlugin(TeamMode: Boolean): Cardinal;
+ function GetRandomPlayer(Team: Byte): Byte;
+ public
+ //Teams: TTeamInfo;
+ Rounds: array of TRoundInfo;
+
+ //TCoreModule methods to inherit
+ Constructor Create; override;
+ Procedure Info(const pInfo: PModuleInfo); override;
+ Function Load: Boolean; override;
+ Function Init: Boolean; override;
+ Procedure DeInit; override;
+ Destructor Destroy; override;
+
+ //Register Modi Service
+ Function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new Modi. wParam: Pointer to TUS_ModiInfo
+
+ //Start new Party
+ Function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new Party Mode. Returns Non Zero on Success
+ Function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns Pointer to Cur. Modis TUS_ModiInfo (to Use with Singscreen)
+ Function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops Party Mode. Returns 1 If Partymode was enabled before.
+ Function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
+
+ Function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
+ Function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and does the RoundEnding
+
+ Function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
+ Function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
+
+ Function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
+ Function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
+ end;
+
+const
+ StandardModi = 0; //Modi ID that will be played in non party Mode
+
+implementation
+
+uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils;
+
+{*********************
+ TPluginLoader
+ Implentation
+*********************}
+
+//-------------
+// Function that gives some Infos about the Module to the Core
+//-------------
+Procedure TPartySession.Info(const pInfo: PModuleInfo);
+begin
+ pInfo^.Name := 'TPartySession';
+ pInfo^.Version := MakeVersion(1,0,0,chr(0));
+ pInfo^.Description := 'Manages Party Modi and Party Game';
+end;
+
+//-------------
+// Just the Constructor
+//-------------
+Constructor TPartySession.Create;
+begin
+ inherited;
+ //UnSet PartyMode
+ bPartyMode := False;
+end;
+
+//-------------
+//Is Called on Loading.
+//In this Method only Events and Services should be created
+//to offer them to other Modules or Plugins during the Init process
+//If False is Returned this will cause a Forced Exit
+//-------------
+Function TPartySession.Load: Boolean;
+begin
+ //Add Register Party Modi Service
+ Result := True;
+ Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi);
+ Core.Services.AddService('Party/StartParty', nil, Self.StartParty);
+ Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi);
+end;
+
+//-------------
+//Is Called on Init Process
+//In this Method you can Hook some Events and Create + Init
+//your Classes, Variables etc.
+//If False is Returned this will cause a Forced Exit
+//-------------
+Function TPartySession.Init: Boolean;
+begin
+ //Just set Prvate Var to true.
+ Result := true;
+end;
+
+//-------------
+//Is Called if this Module has been Inited and there is a Exit.
+//Deinit is in backwards Initing Order
+//-------------
+Procedure TPartySession.DeInit;
+begin
+ //Force DeInit
+
+end;
+
+//-------------
+//Is Called if this Module will be unloaded and has been created
+//Should be used to Free Memory
+//-------------
+Destructor TPartySession.Destroy;
+begin
+ //Just save some Memory if it wasn't done now..
+ SetLength(Modis, 0);
+ inherited;
+end;
+
+//-------------
+// Registers a new Modi. wParam: Pointer to TUS_ModiInfo
+// Service for Plugins
+//-------------
+Function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer;
+var
+ Len: Integer;
+ Info: PUS_ModiInfo;
+begin
+ Info := PModiInfo;
+ //Copy Info if cbSize is correct
+ If (Info.cbSize = SizeOf(TUS_ModiInfo)) then
+ begin
+ Len := Length(Modis);
+ SetLength(Modis, Len + 1);
+
+ Modis[Len].Info := Info^;
+ end
+ else
+ Core.ReportError(Integer(PChar('Plugins try to Register Modi with wrong Pointer, or wrong TUS_ModiInfo Record.')), PChar('TPartySession'));
+
+ // FIXME: return a valid result
+ Result := 0;
+end;
+
+//----------
+// Returns a Number of a Random Plugin
+//----------
+Function TPartySession.GetRandomPlugin(TeamMode: Boolean): Cardinal;
+var
+ LowestTP: Byte;
+ NumPwithLTP: Word;
+ I: Integer;
+ R: Word;
+begin
+ Result := StandardModi; //If there are no matching Modis, Play StandardModi
+ LowestTP := high(Byte);
+ NumPwithLTP := 0;
+
+ //Search for Plugins not often played yet
+ For I := 0 to high(Modis) do
+ begin
+ if (Modis[I].TimesPlayed < lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ begin
+ lowestTP := Modis[I].TimesPlayed;
+ NumPwithLTP := 1;
+ end
+ else if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ begin
+ Inc(NumPwithLTP);
+ end;
+ end;
+
+ //Create Random No
+ R := Random(NumPwithLTP);
+
+ //Search for Random Plugin
+ For I := 0 to high(Modis) do
+ begin
+ if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ begin
+ //Plugin Found
+ if (R = 0) then
+ begin
+ Result := I;
+ Inc(Modis[I].TimesPlayed);
+ Break;
+ end;
+
+ Dec(R);
+ end;
+ end;
+end;
+
+//----------
+// Starts new Party Mode. Returns Non Zero on Success
+//----------
+Function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer;
+var
+ I: Integer;
+ aiRounds: PARounds;
+ TeamMode: Boolean;
+begin
+ Result := 0;
+ If (Teams.NumTeams >= 1) AND (NumRounds < High(Byte)-1) then
+ begin
+ bPartyMode := false;
+ aiRounds := PAofIRounds;
+
+ Try
+ //Is this Teammode(More then one Player per Team) ?
+ TeamMode := True;
+ For I := 0 to Teams.NumTeams-1 do
+ TeamMode := TeamMode AND (Teams.Teaminfo[I].NumPlayers > 1);
+
+ //Set Rounds
+ SetLength(Rounds, NumRounds);
+
+ For I := 0 to High(Rounds) do
+ begin //Set Plugins
+ If (aiRounds[I] = -1) then
+ Rounds[I].Modi := GetRandomPlugin(TeamMode)
+ Else If (aiRounds[I] >= 0) AND (aiRounds[I] <= High(Modis)) AND (TeamMode OR ((Modis[aiRounds[I]].Info.LoadingSettings AND MLS_TeamOnly) = 0)) then
+ Rounds[I].Modi := aiRounds[I]
+ Else
+ Rounds[I].Modi := StandardModi;
+
+ Rounds[I].Winner := High(Byte); //Set Winner to Not Played
+ end;
+
+ CurRound := High(Byte); //Set CurRound to not defined
+
+ //Return teh true and Set PartyMode
+ bPartyMode := True;
+ Result := 1;
+
+ Except
+ Core.ReportError(Integer(PChar('Can''t start PartyMode.')), PChar('TPartySession'));
+ end;
+ end;
+end;
+
+//----------
+// Returns Pointer to Cur. ModiInfoEx (to Use with Singscreen)
+//----------
+Function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer;
+begin
+ If (bPartyMode) AND (CurRound <= High(Rounds)) then
+ begin //If PartyMode is enabled:
+ //Return the Plugin of the Cur Round
+ Result := Integer(@Modis[Rounds[CurRound].Modi]);
+ end
+ else
+ begin //Return StandardModi
+ Result := Integer(@Modis[StandardModi]);
+ end;
+end;
+
+//----------
+// Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible
+//----------
+Function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer;
+begin
+ Result := -1;
+ If (bPartyMode) then
+ begin
+ // to-do : Whitü: Check here if SingScreen is not Shown atm.
+ bPartyMode := False;
+ Result := 1;
+ end
+ else
+ Result := 0;
+end;
+
+//----------
+//GetRandomPlayer - Gives back a Random Player to Play next Round
+//----------
+function TPartySession.GetRandomPlayer(Team: Byte): Byte;
+var
+ I, R: Integer;
+ lowestTP: Byte;
+ NumPwithLTP: Byte;
+begin
+ LowestTP := high(Byte);
+ NumPwithLTP := 0;
+ Result := 0;
+
+ //Search for Players that have not often played yet
+ For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ begin
+ if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
+ begin
+ lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
+ NumPwithLTP := 1;
+ end
+ else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
+ begin
+ Inc(NumPwithLTP);
+ end;
+ end;
+
+ //Create Random No
+ R := Random(NumPwithLTP);
+
+ //Search for Random Player
+ For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ begin
+ if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then
+ begin
+ //Player Found
+ if (R = 0) then
+ begin
+ Result := I;
+ Break;
+ end;
+
+ Dec(R);
+ end;
+ end;
+end;
+
+//----------
+// NextRound - Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
+//----------
+Function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer;
+var I: Integer;
+begin
+ If ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then
+ begin //everythings OK! -> Start the Round, maaaaan
+ Inc(CurRound);
+
+ //Set Players to play this Round
+ for I := 0 to Teams.NumTeams-1 do
+ Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I);
+
+ // FIXME: return a valid result
+ Result := 0;
+ end
+ else
+ Result := -1;
+end;
+
+//----------
+//IsWinner - Returns True if the Players Bit is set in the Winner Byte
+//----------
+function TPartySession.IsWinner(Player, Winner: Byte): boolean;
+var
+ Bit: Byte;
+begin
+ Bit := 1 shl Player;
+
+ Result := ((Winner AND Bit) = Bit);
+end;
+
+//----------
+//GenScores - Inc Scores for Cur. Round
+//----------
+procedure TPartySession.GenScores;
+var
+ I: Byte;
+begin
+ for I := 0 to Teams.NumTeams-1 do
+ begin
+ if isWinner(I, Rounds[CurRound].Winner) then
+ Inc(Teams.Teaminfo[I].Score);
+ end;
+end;
+
+//----------
+// CallModiInit - Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
+//----------
+Function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer;
+begin
+ If (not bPartyMode) then
+ begin //Set Rounds if not in PartyMode
+ SetLength(Rounds, 1);
+ Rounds[0].Modi := StandardModi;
+ Rounds[0].Winner := High(Byte);
+ CurRound := 0;
+ end;
+
+ Try
+ //Core.
+ Except
+ on E : Exception do
+ begin
+ Core.ReportError(Integer(PChar('Error starting Modi: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession'));
+ If (Rounds[CurRound].Modi = StandardModi) then
+ begin
+ Core.ReportError(Integer(PChar('Can''t start StandardModi, will exit now!')), PChar('TPartySession'));
+ Halt;
+ end
+ Else //Select StandardModi
+ begin
+ Rounds[CurRound].Modi := StandardModi
+ end;
+ end;
+ End;
+
+ // FIXME: return a valid result
+ Result := 0;
+end;
+
+//----------
+// CallModiDeInit - Calls DeInitProc and does the RoundEnding
+//----------
+Function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer;
+var
+ I: Integer;
+ MaxScore: Word;
+begin
+ If (bPartyMode) then
+ begin
+ //Get Winner Byte!
+ if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get Winners from Plugin
+ Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID)
+ else
+ begin //Create winners by Score :/
+ Rounds[CurRound].Winner := 0;
+ MaxScore := 0;
+ for I := 0 to Teams.NumTeams-1 do
+ begin
+ // to-do : recode Percentage stuff
+ //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999;
+ if (Player[I].ScoreTotalInt > MaxScore) then
+ begin
+ MaxScore := Player[I].ScoreTotalInt;
+ Rounds[CurRound].Winner := 1 shl I;
+ end
+ else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then
+ begin
+ Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I);
+ end;
+ end;
+
+
+ //When nobody has Points -> Everybody loose
+ if (MaxScore = 0) then
+ Rounds[CurRound].Winner := 0;
+
+ end;
+
+ //Generate teh Scores
+ GenScores;
+
+ //Inc Players TimesPlayed
+ If ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings AND MLS_IncTP) = MLS_IncTP) then
+ begin
+ For I := 0 to Teams.NumTeams-1 do
+ Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed);
+ end;
+ end
+ else if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then
+ Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID);
+
+ // FIXME: return a valid result
+ Result := 0;
+end;
+
+//----------
+// GetTeamInfo - Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
+//----------
+Function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
+var Info: ^TTeamInfo;
+begin
+ Result := -1;
+ Info := pTeamInfo;
+ If (Info <> nil) then
+ begin
+ Try
+ // to - do : Check Delphi memory management in this case
+ //Not sure if i had to copy PChars to a new address or if delphi manages this o0
+ Info^ := Teams;
+ Result := 0;
+ Except
+ Result := -2;
+ End;
+ end;
+end;
+
+//----------
+// SetTeamInfo - Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
+//----------
+Function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
+var
+ TeamInfobackup: TTeamInfo;
+ Info: ^TTeamInfo;
+begin
+ Result := -1;
+ Info := pTeamInfo;
+ If (Info <> nil) then
+ begin
+ Try
+ TeamInfoBackup := Teams;
+ // to - do : Check Delphi memory management in this case
+ //Not sure if i had to copy PChars to a new address or if delphi manages this o0
+ Teams := Info^;
+ Result := 0;
+ Except
+ Teams := TeamInfoBackup;
+ Result := -2;
+ End;
+ end;
+end;
+
+//----------
+// GetTeamOrder - Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
+//----------
+Function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer;
+var
+ I, J: Integer;
+ ATeams: array [0..5] of TeamOrderEntry;
+ TempTeam: TeamOrderEntry;
+begin
+ // to-do : PartyMode: Write this in another way, so that teams with the same scire get the same Placing
+ //Fill Team Array
+ For I := 0 to Teams.NumTeams-1 do
+ begin
+ ATeams[I].Teamnum := I;
+ ATeams[I].Score := Teams.Teaminfo[I].Score;
+ end;
+
+ //Sort Teams
+ for J := 0 to Teams.NumTeams-1 do
+ for I := 1 to Teams.NumTeams-1 do
+ if ATeams[I].Score > ATeams[I-1].Score then
+ begin
+ TempTeam := ATeams[I-1];
+ ATeams[I-1] := ATeams[I];
+ ATeams[I] := TempTeam;
+ end;
+
+ //Copy to Result
+ Result := 0;
+ For I := 0 to Teams.NumTeams-1 do
+ Result := Result or (ATeams[I].TeamNum Shl I*3);
+end;
+
+//----------
+// GetWinnerString - wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
+//----------
+Function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer;
+var
+ Winners: Array of String;
+ I: Integer;
+ ResultStr: String;
+ S: ^String;
+begin
+ ResultStr := Language.Translate('PARTY_NOBODY');
+
+ if (wParam <= High(Rounds)) then
+ begin
+ if (Rounds[wParam].Winner <> 0) then
+ begin
+ if (Rounds[wParam].Winner = 255) then
+ begin
+ ResultStr := Language.Translate('PARTY_NOTPLAYEDYET');
+ end
+ else
+ begin
+ SetLength(Winners, 0);
+ for I := 0 to Teams.NumTeams-1 do
+ begin
+ if isWinner(I, Rounds[wParam].Winner) then
+ begin
+ SetLength(Winners, Length(Winners) + 1);
+ Winners[high(Winners)] := Teams.TeamInfo[I].Name;
+ end;
+ end;
+ ResultStr := Language.Implode(Winners);
+ end;
+ end;
+ end;
+
+ //Now Return what we have got
+ If (lParam = nil) then
+ begin //ReturnString Length
+ Result := Length(ResultStr);
+ end
+ Else
+ begin //Return String
+ Try
+ S := lParam;
+ S^ := ResultStr;
+ Result := 0;
+ Except
+ Result := -1;
+
+ End;
+ end;
+end;
+
+end.
diff --git a/src/Classes/UPlatform.pas b/src/Classes/UPlatform.pas
new file mode 100644
index 00000000..b71ac1b8
--- /dev/null
+++ b/src/Classes/UPlatform.pas
@@ -0,0 +1,165 @@
+unit UPlatform;
+
+// Comment by Eddie:
+// This unit defines an interface for platform specific utility functions.
+// The Interface is implemented in separate files for each platform:
+// UPlatformWindows, UPlatformLinux and UPlatformMacOSX.
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes;
+
+type
+ TDirectoryEntry = record
+ Name : WideString;
+ IsDirectory : boolean;
+ IsFile : boolean;
+ end;
+
+ TDirectoryEntryArray = array of TDirectoryEntry;
+
+ TPlatform = class
+ procedure Init; virtual;
+ function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; virtual; abstract;
+ function TerminateIfAlreadyRunning(var WndTitle : string): boolean; virtual;
+ function FindSongFile(Dir, Mask: WideString): WideString; virtual;
+ procedure Halt; virtual;
+ function GetLogPath : WideString; virtual; abstract;
+ function GetGameSharedPath : WideString; virtual; abstract;
+ function GetGameUserPath : WideString; virtual; abstract;
+ function CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean; virtual;
+ end;
+
+ function Platform(): TPlatform;
+
+implementation
+
+uses
+ SysUtils,
+ {$IFDEF MSWINDOWS}
+ UPlatformWindows,
+ {$ENDIF}
+ {$IFDEF LINUX}
+ UPlatformLinux,
+ {$ENDIF}
+ {$IFDEF DARWIN}
+ UPlatformMacOSX,
+ {$ENDIF}
+ ULog;
+
+
+// I have modified it to use the Platform_singleton in this location ( in the implementaiton )
+// so that this variable can NOT be overwritten from anywhere else in the application.
+// the accessor function platform, emulates all previous calls to work the same way.
+var
+ Platform_singleton : TPlatform;
+
+function Platform : TPlatform;
+begin
+ Result := Platform_singleton;
+end;
+
+(**
+ * Default Init() implementation
+ *)
+procedure TPlatform.Init;
+begin
+end;
+
+(**
+ * Default Halt() implementation
+ *)
+procedure TPlatform.Halt;
+begin
+ // Note: Application.terminate is NOT the same
+ System.Halt;
+end;
+
+(**
+ * Default TerminateIfAlreadyRunning() implementation
+ *)
+function TPlatform.TerminateIfAlreadyRunning(var WndTitle : string): Boolean;
+begin
+ Result := false;
+end;
+
+(**
+ * Default FindSongFile() implementation
+ *)
+function TPlatform.FindSongFile(Dir, Mask: WideString): WideString;
+var
+ SR: TSearchRec; // for parsing song directory
+begin
+ Result := '';
+ if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then
+ begin
+ Result := SR.Name;
+ end;
+ SysUtils.FindClose(SR);
+end;
+
+function TPlatform.CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean;
+const
+ COPY_BUFFER_SIZE = 4096; // a good tradeoff between speed and memory consumption
+var
+ SourceFile, TargetFile: TFileStream;
+ FileCopyBuffer: array [0..COPY_BUFFER_SIZE-1] of byte; // temporary copy-buffer.
+ NumberOfBytes: integer; // number of bytes read from SourceFile
+begin
+ Result := false;
+ SourceFile := nil;
+ TargetFile := nil;
+
+ // if overwrite is disabled return if the target file already exists
+ if (FailIfExists and FileExists(Target)) then
+ Exit;
+
+ try
+ try
+ // open source and target file (might throw an exception on error)
+ SourceFile := TFileStream.Create(Source, fmOpenRead);
+ TargetFile := TFileStream.Create(Target, fmCreate or fmOpenWrite);
+
+ while true do
+ begin
+ // read a block from the source file and check for errors or EOF
+ NumberOfBytes := SourceFile.Read(FileCopyBuffer, SizeOf(FileCopyBuffer));
+ if (NumberOfBytes <= 0) then
+ Break;
+ // write block to target file and check if everything was written
+ if (TargetFile.Write(FileCopyBuffer, NumberOfBytes) <> NumberOfBytes) then
+ Exit;
+ end;
+ except
+ Exit;
+ end;
+ finally
+ SourceFile.Free;
+ TargetFile.Free;
+ end;
+
+ Result := true;
+end;
+
+
+initialization
+{$IFDEF MSWINDOWS}
+ Platform_singleton := TPlatformWindows.Create;
+{$ENDIF}
+{$IFDEF LINUX}
+ Platform_singleton := TPlatformLinux.Create;
+{$ENDIF}
+{$IFDEF DARWIN}
+ Platform_singleton := TPlatformMacOSX.Create;
+{$ENDIF}
+
+finalization
+ Platform_singleton.Free;
+
+end.
diff --git a/src/Classes/UPlatformLinux.pas b/src/Classes/UPlatformLinux.pas
new file mode 100644
index 00000000..27fb130e
--- /dev/null
+++ b/src/Classes/UPlatformLinux.pas
@@ -0,0 +1,160 @@
+unit UPlatformLinux;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes,
+ UPlatform,
+ UConfig;
+
+type
+ TPlatformLinux = class(TPlatform)
+ private
+ function GetHomeDir(): string;
+ public
+ function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; override;
+
+ function GetLogPath : WideString; override;
+ function GetGameSharedPath : WideString; override;
+ function GetGameUserPath : WideString; override;
+ end;
+
+implementation
+
+uses
+ UCommandLine,
+ BaseUnix,
+ {$IF FPC_VERSION_INT >= 2002002}
+ pwd,
+ {$IFEND}
+ SysUtils,
+ ULog;
+
+function TPlatformLinux.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray;
+var
+ i: Integer;
+ TheDir : pDir;
+ ADirent : pDirent;
+ Entry : Longint;
+ lAttrib : integer;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ TheDir := FpOpenDir( Dir );
+ if Assigned(TheDir) then
+ begin
+ repeat
+ ADirent := FpReadDir(TheDir^);
+
+ if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then
+ begin
+ lAttrib := FileGetAttr(Dir + ADirent^.d_name);
+ if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then
+ begin
+ SetLength( Result, i + 1);
+ Result[i].Name := ADirent^.d_name;
+ Result[i].IsDirectory := true;
+ Result[i].IsFile := false;
+ i := i + 1;
+ end
+ else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then
+ begin
+ SetLength( Result, i + 1);
+ Result[i].Name := ADirent^.d_name;
+ Result[i].IsDirectory := false;
+ Result[i].IsFile := true;
+ i := i + 1;
+ end;
+ end;
+ until (ADirent = nil);
+
+ FpCloseDir(TheDir^);
+ end;
+end;
+
+function TPlatformLinux.GetLogPath: WideString;
+begin
+ if FindCmdLineSwitch( cUseLocalPaths ) then
+ begin
+ Result := ExtractFilePath(ParamStr(0));
+ end
+ else
+ begin
+ {$IFDEF UseLocalDirs}
+ Result := ExtractFilePath(ParamStr(0));
+ {$ELSE}
+ Result := GetGameUserPath() + 'logs' + PathDelim;
+ {$ENDIF}
+ end;
+
+ // create non-existing directories
+ ForceDirectories(Result);
+end;
+
+function TPlatformLinux.GetGameSharedPath: WideString;
+begin
+ if FindCmdLineSwitch( cUseLocalPaths ) then
+ Result := ExtractFilePath(ParamStr(0))
+ else
+ begin
+ {$IFDEF UseLocalDirs}
+ Result := ExtractFilePath(ParamStr(0));
+ {$ELSE}
+ Result := SharedPath + PathDelim;
+ {$ENDIF}
+ end;
+end;
+
+function TPlatformLinux.GetGameUserPath: WideString;
+begin
+ if FindCmdLineSwitch( cUseLocalPaths ) then
+ Result := ExtractFilePath(ParamStr(0))
+ else
+ begin
+ {$IFDEF UseLocalDirs}
+ Result := ExtractFilePath(ParamStr(0));
+ {$ELSE}
+ Result := GetHomeDir() + '.'+PathSuffix + PathDelim;
+ {$ENDIF}
+ end;
+end;
+
+(**
+ * Returns the user's home directory terminated by a path delimiter
+ *)
+function TPlatformLinux.GetHomeDir(): string;
+{$IF FPC_VERSION_INT >= 2002002}
+var
+ PasswdEntry: PPasswd;
+{$IFEND}
+begin
+ Result := '';
+
+ {$IF FPC_VERSION_INT >= 2002002}
+ // try to retrieve the info from passwd
+ PasswdEntry := FpGetpwuid(FpGetuid());
+ if (PasswdEntry <> nil) then
+ Result := PasswdEntry.pw_dir;
+ {$IFEND}
+ // fallback if passwd does not contain the path
+ if (Result = '') then
+ Result := GetEnvironmentVariable('HOME');
+ // add trailing path delimiter (normally '/')
+ if (Result <> '') then
+ Result := IncludeTrailingPathDelimiter(Result);
+
+ {$IF FPC_VERSION_INT >= 2002002}
+ // GetUserDir() is another function that returns a user path.
+ // It uses env-var HOME or a fallback to a temp-dir.
+ //Result := GetUserDir();
+ {$IFEND}
+end;
+
+end.
diff --git a/src/Classes/UPlatformMacOSX.pas b/src/Classes/UPlatformMacOSX.pas
new file mode 100644
index 00000000..849c354b
--- /dev/null
+++ b/src/Classes/UPlatformMacOSX.pas
@@ -0,0 +1,294 @@
+unit UPlatformMacOSX;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes,
+ ULog,
+ UPlatform;
+
+type
+ {**
+ * @abstract(Provides Mac OS X specific details.)
+ * @lastmod(August 1, 2008)
+ * The UPlatformMacOSX unit takes care of setting paths to resource folders.
+ *
+ * (Note for non-Maccies: "folder" is the Mac name for directory.)
+ *
+ * Note on the resource folders:
+ * 1. Installation of an application on the mac works as follows: Extract and copy an application
+ * and if you don't like or need the application anymore you move the folder
+ * to the trash - and you're done.
+ * 2. The use folders in the user's home directory is against Apple's guidelines
+ * and strange to an average user.
+ * 3. Even worse is using /usr/local/... since all lowercase folders in / are
+ * not visible to an average user in the Finder, at least not without some "tricks".
+ *
+ * The best way would be to store everything within the application bundle. However, this
+ * requires USDX to offer the handling of the resources. Until this is implemented, the
+ * second best solution is as follows:
+ *
+ * According to Aple guidelines handling of resources and folders should follow these lines:
+ *
+ * Acceptable places for files are folders named UltraStarDeluxe either in
+ * /Library/Application Support/
+ * or
+ * ~/Library/Application Support/
+ *
+ * So
+ * GetGameSharedPath could return
+ * /Library/Application Support/UltraStarDeluxe/Resources/.
+ * GetGameUserPath could return
+ * ~/Library/Application Support/UltraStarDeluxe/Resources/.
+ *
+ * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
+ * is used. So every user needs the complete set of files and folders.
+ * Future versions may also use shared resources in
+ * /Library/Application Support/UltraStarDeluxe/Resources. However, this is not
+ * treated yet in the code outside this unit.
+ *
+ * USDX checks, whether GetGameUserPath exists. If not, USDX creates it.
+ * The existence of needed files is then checked and if a file is missing
+ * it is copied to there from within the Resources folder in the Application
+ * bundle, which contains the default files. USDX should not delete files or
+ * folders in Application Support/UltraStarDeluxe automatically or without
+ * user confirmation.
+ *}
+ TPlatformMacOSX = class(TPlatform)
+ private
+ {**
+ * GetBundlePath returns the path to the application bundle UltraStarDeluxe.app.
+ *}
+ function GetBundlePath: WideString;
+
+ {**
+ * GetApplicationSupportPath returns the path to
+ * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
+ *}
+ function GetApplicationSupportPath: WideString;
+
+ {**
+ * see the description of @link(Init).
+ *}
+ procedure CreateUserFolders();
+
+ public
+ {**
+ * Init simply calls @link(CreateUserFolders), which in turn scans the folder
+ * UltraStarDeluxe.app/Contents/Resources for all files and folders.
+ * $HOME/Library/Application Support/UltraStarDeluxe/Resources is then checked
+ * for their presence and missing ones are copied.
+ *}
+ procedure Init; override;
+
+ {**
+ * DirectoryFindFiles returns all entries of a folder with names and booleans
+ * about their type, i.e. file or directory.
+ *}
+ function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override;
+
+ {**
+ * GetLogPath returns the path for log messages. Currently it is set to
+ * $HOME/Library/Application Support/UltraStarDeluxe/Resources/Log.
+ *}
+ function GetLogPath : WideString; override;
+
+ {**
+ * GetGameSharedPath returns the path for shared resources. Currently it is set to
+ * /Library/Application Support/UltraStarDeluxe/Resources.
+ * However it is not used.
+ *}
+ function GetGameSharedPath : WideString; override;
+
+ {**
+ * GetGameUserPath returns the path for user resources. Currently it is set to
+ * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
+ * This is where a user can add songs, themes, ....
+ *}
+ function GetGameUserPath : WideString; override;
+ end;
+
+implementation
+
+uses
+ SysUtils,
+ BaseUnix;
+
+procedure TPlatformMacOSX.Init;
+begin
+ CreateUserFolders();
+end;
+
+procedure TPlatformMacOSX.CreateUserFolders();
+var
+ RelativePath: string;
+ // BaseDir contains the path to the folder, where a search is performed.
+ // It is set to the entries in @link(DirectoryList) one after the other.
+ BaseDir: string;
+ // OldBaseDir contains the path to the folder, where the search started.
+ // It is used to return to it, when the search is completed in all folders.
+ OldBaseDir: string;
+ // This record contains the result of a file search with FindFirst or FindNext
+ SearchInfo: TSearchRec;
+ // These two lists contain all folder and file names found
+ // within the folder @link(BaseDir).
+ DirectoryList, FileList: TStringList;
+ // DirectoryIsFinished contains the index of the folder in @link(DirectoryList),
+ // which is the last one completely searched. Later folders are still to be
+ // searched for additional files and folders.
+ DirectoryIsFinished: longint;
+ Counter: longint;
+
+ UserPathName: string;
+const
+ // used to construct the @link(UserPathName)
+ PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources';
+begin
+ // Get the current folder and save it in OldBaseDir for returning to it, when
+ // finished.
+ GetDir(0, OldBaseDir);
+
+ // UltraStarDeluxe.app/Contents/Resources contains all the default files and
+ // folders.
+ BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources';
+ ChDir(BaseDir);
+
+ // Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
+ // is used.
+ UserPathName := GetEnvironmentVariable('HOME') + PathName;
+
+ DirectoryIsFinished := 0;
+ DirectoryList := TStringList.Create();
+ FileList := TStringList.Create();
+ DirectoryList.Add('.');
+
+ // create the folder and file lists
+ repeat
+
+ RelativePath := DirectoryList[DirectoryIsFinished];
+ ChDir(BaseDir + '/' + RelativePath);
+ if (FindFirst('*', faAnyFile, SearchInfo) = 0) then
+ begin
+ repeat
+ if DirectoryExists(SearchInfo.Name) then
+ begin
+ if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then
+ DirectoryList.Add(RelativePath + '/' + SearchInfo.Name);
+ end
+ else
+ Filelist.Add(RelativePath + '/' + SearchInfo.Name);
+ until (FindNext(SearchInfo) <> 0);
+ end;
+ FindClose(SearchInfo);
+ Inc(DirectoryIsFinished);
+ until (DirectoryIsFinished = DirectoryList.Count);
+
+ // create missing folders
+ for Counter := 0 to DirectoryList.Count-1 do
+ begin
+ if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then
+ Log.LogError('Failed to create the folder "'+ UserPathName + '/' + DirectoryList[Counter] +'"',
+ 'TPlatformMacOSX.CreateUserFolders');
+ end;
+ DirectoryList.Free();
+
+ // copy missing files
+ for Counter := 0 to Filelist.Count-1 do
+ begin
+ CopyFile(BaseDir + '/' + Filelist[Counter],
+ UserPathName + '/' + Filelist[Counter], true);
+ end;
+ FileList.Free();
+
+ // go back to the initial folder
+ ChDir(OldBaseDir);
+end;
+
+function TPlatformMacOSX.GetBundlePath: WideString;
+var
+ i, pos : integer;
+begin
+ // Mac applications are packaged in folders.
+ // We have to cut the last two folders
+ // to get the application folder.
+
+ Result := ExtractFilePath(ParamStr(0));
+ for i := 1 to 2 do
+ begin
+ pos := Length(Result);
+ repeat
+ Delete(Result, pos, 1);
+ pos := Length(Result);
+ until (pos = 0) or (Result[pos] = '/');
+ end;
+end;
+
+function TPlatformMacOSX.GetApplicationSupportPath: WideString;
+const
+ PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources';
+begin
+ Result := GetEnvironmentVariable('HOME') + PathName + '/';
+end;
+
+function TPlatformMacOSX.GetLogPath: WideString;
+begin
+ Result := GetApplicationSupportPath + 'Logs';
+end;
+
+function TPlatformMacOSX.GetGameSharedPath: WideString;
+begin
+ Result := GetApplicationSupportPath;
+end;
+
+function TPlatformMacOSX.GetGameUserPath: WideString;
+begin
+ Result := GetApplicationSupportPath;
+end;
+
+function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray;
+var
+ i : integer;
+ TheDir : pdir;
+ ADirent : pDirent;
+ lAttrib : integer;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ TheDir := FPOpenDir(Dir);
+ if Assigned(TheDir) then
+ repeat
+ ADirent := FPReadDir(TheDir);
+
+ if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then
+ begin
+ lAttrib := FileGetAttr(Dir + ADirent^.d_name);
+ if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then
+ begin
+ SetLength(Result, i + 1);
+ Result[i].Name := ADirent^.d_name;
+ Result[i].IsDirectory := true;
+ Result[i].IsFile := false;
+ i := i + 1;
+ end
+ else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then
+ begin
+ SetLength(Result, i + 1);
+ Result[i].Name := ADirent^.d_name;
+ Result[i].IsDirectory := false;
+ Result[i].IsFile := true;
+ i := i + 1;
+ end;
+ end;
+ until ADirent = nil;
+
+ FPCloseDir(TheDir);
+end;
+
+end.
diff --git a/src/Classes/UPlatformWindows.pas b/src/Classes/UPlatformWindows.pas
new file mode 100644
index 00000000..ee132a7b
--- /dev/null
+++ b/src/Classes/UPlatformWindows.pas
@@ -0,0 +1,236 @@
+unit UPlatformWindows;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+// turn off messages for platform specific symbols
+{$WARN SYMBOL_PLATFORM OFF}
+
+uses
+ Classes,
+ UPlatform;
+
+type
+ TPlatformWindows = class(TPlatform)
+ private
+ function GetSpecialPath(CSIDL: integer): WideString;
+ public
+ function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; override;
+ function TerminateIfAlreadyRunning(var WndTitle: String): Boolean; override;
+
+ function GetLogPath: WideString; override;
+ function GetGameSharedPath: WideString; override;
+ function GetGameUserPath: WideString; override;
+
+ function CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean; override;
+ end;
+
+implementation
+
+uses
+ SysUtils,
+ ShlObj,
+ Windows,
+ UConfig;
+
+type
+ TSearchRecW = record
+ Time: Integer;
+ Size: Integer;
+ Attr: Integer;
+ Name: WideString;
+ ExcludeAttr: Integer;
+ FindHandle: THandle;
+ FindData: TWin32FindDataW;
+ end;
+
+function FindFirstW(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; forward;
+function FindNextW(var F: TSearchRecW): Integer; forward;
+procedure FindCloseW(var F: TSearchRecW); forward;
+function FindMatchingFileW(var F: TSearchRecW): Integer; forward;
+function DirectoryExistsW(const Directory: widestring): Boolean; forward;
+
+function FindFirstW(const Path: widestring; Attr: Integer; var F: TSearchRecW): Integer;
+const
+ faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
+begin
+ F.ExcludeAttr := not Attr and faSpecial;
+{$IFDEF Delphi}
+ F.FindHandle := FindFirstFileW(PWideChar(Path), F.FindData);
+{$ELSE}
+ F.FindHandle := FindFirstFileW(PWideChar(Path), @F.FindData);
+{$ENDIF}
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Result := FindMatchingFileW(F);
+ if Result <> 0 then FindCloseW(F);
+ end else
+ Result := GetLastError;
+end;
+
+function FindNextW(var F: TSearchRecW): Integer;
+begin
+{$IFDEF Delphi}
+ if FindNextFileW(F.FindHandle, F.FindData) then
+{$ELSE}
+ if FindNextFileW(F.FindHandle, @F.FindData) then
+{$ENDIF}
+ Result := FindMatchingFileW(F)
+ else
+ Result := GetLastError;
+end;
+
+procedure FindCloseW(var F: TSearchRecW);
+begin
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Windows.FindClose(F.FindHandle);
+ F.FindHandle := INVALID_HANDLE_VALUE;
+ end;
+end;
+
+function FindMatchingFileW(var F: TSearchRecW): Integer;
+var
+ LocalFileTime: TFileTime;
+begin
+ with F do
+ begin
+ while FindData.dwFileAttributes and ExcludeAttr <> 0 do
+{$IFDEF Delphi}
+ if not FindNextFileW(FindHandle, FindData) then
+{$ELSE}
+ if not FindNextFileW(FindHandle, @FindData) then
+{$ENDIF}
+ begin
+ Result := GetLastError;
+ Exit;
+ end;
+ FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
+ FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
+ Size := FindData.nFileSizeLow;
+ Attr := FindData.dwFileAttributes;
+ Name := FindData.cFileName;
+ end;
+ Result := 0;
+end;
+
+function DirectoryExistsW(const Directory: widestring): Boolean;
+var
+ Code: Integer;
+begin
+ Code := GetFileAttributesW(PWideChar(Directory));
+ Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
+end;
+
+//------------------------------
+//Start more than One Time Prevention
+//------------------------------
+function TPlatformWindows.TerminateIfAlreadyRunning(var WndTitle: String): Boolean;
+var
+ hWnd: THandle;
+ I: Integer;
+begin
+ Result := false;
+ hWnd:= FindWindow(nil, PChar(WndTitle));
+ //Programm already started
+ if (hWnd <> 0) then
+ begin
+ I := Messagebox(0, PChar('Another Instance of Ultrastar is already running. Continue ?'), PChar(WndTitle), MB_ICONWARNING or MB_YESNO);
+ if (I = IDYes) then
+ begin
+ I := 1;
+ repeat
+ Inc(I);
+ hWnd := FindWindow(nil, PChar(WndTitle + ' Instance ' + InttoStr(I)));
+ until (hWnd = 0);
+ WndTitle := WndTitle + ' Instance ' + InttoStr(I);
+ end
+ else
+ Result := true;
+ end;
+end;
+
+function TPlatformWindows.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray;
+var
+ i : Integer;
+ SR : TSearchRecW;
+ Attrib : Integer;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ if FindFirstW(Dir + '*', faAnyFile or faDirectory, SR) = 0 then
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ begin
+ Attrib := FileGetAttr(Dir + SR.name);
+ if ReturnAllSubDirs and ((Attrib and faDirectory) <> 0) then
+ begin
+ SetLength( Result, i + 1);
+ Result[i].Name := SR.name;
+ Result[i].IsDirectory := true;
+ Result[i].IsFile := false;
+ i := i + 1;
+ end
+ else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(SR.Name)) > 0) then
+ begin
+ SetLength( Result, i + 1);
+ Result[i].Name := SR.Name;
+ Result[i].IsDirectory := false;
+ Result[i].IsFile := true;
+ i := i + 1;
+ end;
+ end;
+ until FindNextW(SR) <> 0;
+ FindCloseW(SR);
+end;
+
+(**
+ * Returns the path of a special folder.
+ *
+ * Some Folder IDs:
+ * CSIDL_APPDATA (e.g. C:\Documents and Settings\username\Application Data)
+ * CSIDL_LOCAL_APPDATA (e.g. C:\Documents and Settings\username\Local Settings\Application Data)
+ * CSIDL_PROFILE (e.g. C:\Documents and Settings\username)
+ * CSIDL_PERSONAL (e.g. C:\Documents and Settings\username\My Documents)
+ * CSIDL_MYMUSIC (e.g. C:\Documents and Settings\username\My Documents\My Music)
+ *)
+function TPlatformWindows.GetSpecialPath(CSIDL: integer): WideString;
+var
+ Buffer: array [0..MAX_PATH-1] of WideChar;
+begin
+{$IF Defined(Delphi) or (FPC_VERSION_INT >= 2002002)} // >= 2.2.2
+ if (SHGetSpecialFolderPathW(0, @Buffer, CSIDL, false)) then
+ Result := Buffer
+ else
+{$IFEND}
+ Result := '';
+end;
+
+function TPlatformWindows.GetLogPath: WideString;
+begin
+ Result := ExtractFilePath(ParamStr(0));
+end;
+
+function TPlatformWindows.GetGameSharedPath: WideString;
+begin
+ Result := ExtractFilePath(ParamStr(0));
+end;
+
+function TPlatformWindows.GetGameUserPath: WideString;
+begin
+ //Result := GetSpecialPath(CSIDL_APPDATA) + PathDelim + 'UltraStarDX' + PathDelim;
+ Result := ExtractFilePath(ParamStr(0));
+end;
+
+function TPlatformWindows.CopyFile(const Source, Target: WideString; FailIfExists: boolean): boolean;
+begin
+ Result := Windows.CopyFileW(PWideChar(Source), PWideChar(Target), FailIfExists);
+end;
+
+end.
diff --git a/src/Classes/UPlaylist.pas b/src/Classes/UPlaylist.pas
new file mode 100644
index 00000000..c867c356
--- /dev/null
+++ b/src/Classes/UPlaylist.pas
@@ -0,0 +1,490 @@
+unit UPlaylist;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ USong;
+
+type
+ TPlaylistItem = record
+ Artist: String;
+ Title: String;
+ SongID: Integer;
+ end;
+
+ APlaylistItem = array of TPlaylistItem;
+
+ TPlaylist = record
+ Name: String;
+ Filename: String;
+ Items: APlaylistItem;
+ end;
+
+ APlaylist = array of TPlaylist;
+
+ //----------
+ //TPlaylistManager - Class for Managing Playlists (Loading, Displaying, Saving)
+ //----------
+ TPlaylistManager = class
+ private
+
+ public
+ Mode: TSingMode; //Current Playlist Mode for SongScreen
+ CurPlayList: Cardinal;
+ CurItem: Cardinal;
+
+ Playlists: APlaylist;
+
+ constructor Create;
+ Procedure LoadPlayLists;
+ Function LoadPlayList(Index: Cardinal; Filename: String): Boolean;
+ Procedure SavePlayList(Index: Cardinal);
+
+ Procedure SetPlayList(Index: Cardinal);
+
+ Function AddPlaylist(Name: String): Cardinal;
+ Procedure DelPlaylist(const Index: Cardinal);
+
+ Procedure AddItem(const SongID: Cardinal; const iPlaylist: Integer = -1);
+ Procedure DelItem(const iItem: Cardinal; const iPlaylist: Integer = -1);
+
+ Procedure GetNames(var PLNames: array of String);
+ Function GetIndexbySongID(const SongID: Cardinal; const iPlaylist: Integer = -1): Integer;
+ end;
+
+ {Modes:
+ 0: Standard Mode
+ 1: Category Mode
+ 2: PlayList Mode}
+
+ var
+ PlayListMan: TPlaylistManager;
+
+
+implementation
+
+uses USongs,
+ ULog,
+ UMain,
+ //UFiles,
+ UGraphic,
+ UThemes,
+ SysUtils;
+
+//----------
+//Create - Construct Class - Dummy for now
+//----------
+constructor TPlayListManager.Create;
+begin
+ inherited;
+ LoadPlayLists;
+end;
+
+//----------
+//LoadPlayLists - Load list of Playlists from PlayList Folder
+//----------
+Procedure TPlayListManager.LoadPlayLists;
+var
+ SR: TSearchRec;
+ Len: Integer;
+ PlayListBuffer: TPlayList;
+begin
+ SetLength(Playlists, 0);
+
+ if FindFirst(PlayListPath + '*.upl', 0, SR) = 0 then
+ begin
+ repeat
+ Len := Length(Playlists);
+ SetLength(Playlists, Len +1);
+
+ if not LoadPlayList (Len, Sr.Name) then
+ SetLength(Playlists, Len)
+ else
+ begin
+ // Sort the Playlists - Insertion Sort
+ PlayListBuffer := Playlists[Len];
+ Dec(Len);
+ while (Len >= 0) AND (CompareText(Playlists[Len].Name, PlayListBuffer.Name) >= 0) do
+ begin
+ Playlists[Len+1] := Playlists[Len];
+ Dec(Len);
+ end;
+ Playlists[Len+1] := PlayListBuffer;
+ end;
+
+ until FindNext(SR) <> 0;
+ FindClose(SR);
+ end;
+end;
+
+//----------
+//LoadPlayList - Load a Playlist in the Array
+//----------
+Function TPlayListManager.LoadPlayList(Index: Cardinal; Filename: String): Boolean;
+ var
+ F: TextFile;
+ Line: String;
+ PosDelimiter: Integer;
+ SongID: Integer;
+ Len: Integer;
+
+ Function FindSong(Artist, Title: String): Integer;
+ var I: Integer;
+ begin
+ Result := -1;
+
+ For I := low(CatSongs.Song) to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[I].Title = Title) AND (CatSongs.Song[I].Artist = Artist) then
+ begin
+ Result := I;
+ Break;
+ end;
+ end;
+ end;
+begin
+ if not FileExists(PlayListPath + Filename) then
+ begin
+ Log.LogError('Could not load Playlist: ' + Filename);
+ Result := False;
+ Exit;
+ end;
+ Result := True;
+
+ //Load File
+ AssignFile(F, PlayListPath + FileName);
+ Reset(F);
+
+ //Set Filename
+ PlayLists[Index].Filename := Filename;
+ PlayLists[Index].Name := '';
+
+ //Read Until End of File
+ While not Eof(F) do
+ begin
+ //Read Curent Line
+ Readln(F, Line);
+
+ if (Length(Line) > 0) then
+ begin
+ PosDelimiter := Pos(':', Line);
+ if (PosDelimiter <> 0) then
+ begin
+ //Comment or Name String
+ if (Line[1] = '#') then
+ begin
+ //Found Name Value
+ if (Uppercase(Trim(copy(Line, 2, PosDelimiter - 2))) = 'NAME') then
+ PlayLists[Index].Name := Trim(copy(Line, PosDelimiter + 1,Length(Line) - PosDelimiter))
+
+ end
+ //Song Entry
+ else
+ begin
+ SongID := FindSong(Trim(copy(Line, 1, PosDelimiter - 1)), Trim(copy(Line, PosDelimiter + 1, Length(Line) - PosDelimiter)));
+ if (SongID <> -1) then
+ begin
+ Len := Length(PlayLists[Index].Items);
+ SetLength(PlayLists[Index].Items, Len + 1);
+
+ PlayLists[Index].Items[Len].SongID := SongID;
+
+ PlayLists[Index].Items[Len].Artist := Trim(copy(Line, 1, PosDelimiter - 1));
+ PlayLists[Index].Items[Len].Title := Trim(copy(Line, PosDelimiter + 1, Length(Line) - PosDelimiter));
+ end
+ else Log.LogError('Could not find Song in Playlist: ' + PlayLists[Index].Filename + ', ' + Line);
+ end;
+ end;
+ end;
+ end;
+
+ //If no special name is given, use Filename
+ if PlayLists[Index].Name = '' then
+ begin
+ PlayLists[Index].Name := ChangeFileExt(FileName, '');
+ end;
+
+ //Finish (Close File)
+ CloseFile(F);
+end;
+
+//----------
+//SavePlayList - Saves the specified Playlist
+//----------
+Procedure TPlayListManager.SavePlayList(Index: Cardinal);
+var
+ F: TextFile;
+ I: Integer;
+begin
+ if (Not FileExists(PlaylistPath + Playlists[Index].Filename)) OR (Not FileisReadOnly(PlaylistPath + Playlists[Index].Filename)) then
+ begin
+
+ //open File for Rewriting
+ AssignFile(F, PlaylistPath + Playlists[Index].Filename);
+ try
+ try
+ Rewrite(F);
+
+ //Write Version (not nessecary but helpful)
+ WriteLn(F, '######################################');
+ WriteLn(F, '#Ultrastar Deluxe Playlist Format v1.0');
+ WriteLn(F, '#Playlist "' + Playlists[Index].Name + '" with ' + InttoStr(Length(Playlists[Index].Items)) + ' Songs.');
+ WriteLn(F, '######################################');
+
+ //Write Name Information
+ WriteLn(F, '#Name: ' + Playlists[Index].Name);
+
+ //Write Song Information
+ WriteLn(F, '#Songs:');
+
+ For I := 0 to high(Playlists[Index].Items) do
+ begin
+ WriteLn(F, Playlists[Index].Items[I].Artist + ' : ' + Playlists[Index].Items[I].Title);
+ end;
+ except
+ log.LogError('Could not write Playlistfile "' + Playlists[Index].Name + '"');
+ end;
+ finally
+ CloseFile(F);
+ end;
+ end;
+end;
+
+//----------
+//SetPlayList - Display a Playlist in CatSongs
+//----------
+Procedure TPlayListManager.SetPlayList(Index: Cardinal);
+var
+ I: Integer;
+begin
+ If (Int(Index) > High(PlayLists)) then
+ exit;
+
+ //Hide all Songs
+ For I := 0 to high(CatSongs.Song) do
+ CatSongs.Song[I].Visible := False;
+
+ //Show Songs in PL
+ For I := 0 to high(PlayLists[Index].Items) do
+ begin
+ CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True;
+ end;
+
+ //Set CatSongsMode + Playlist Mode
+ CatSongs.CatNumShow := -3;
+ Mode := smPlayListRandom;
+
+ //Set CurPlaylist
+ CurPlaylist := Index;
+
+ //Show Cat in Topleft:
+ ScreenSong.ShowCatTLCustom(Format(Theme.Playlist.CatText,[Playlists[Index].Name]));
+
+ //Fix SongSelection
+ ScreenSong.Interaction := 0;
+ ScreenSong.SelectNext;
+ ScreenSong.FixSelected;
+
+ //Play correct Music
+ ScreenSong.ChangeMusic;
+end;
+
+//----------
+//AddPlaylist - Adds a Playlist and Returns the Index
+//----------
+Function TPlayListManager.AddPlaylist(Name: String): Cardinal;
+var
+ I: Integer;
+begin
+ Result := Length(Playlists);
+ SetLength(Playlists, Result + 1);
+
+ // Sort the Playlists - Insertion Sort
+ while (Result > 0) AND (CompareText(Playlists[Result - 1].Name, Name) >= 0) do
+ begin
+ Dec(Result);
+ Playlists[Result+1] := Playlists[Result];
+ end;
+ Playlists[Result].Name := Name;
+
+ I := 1;
+ if (not FileExists(PlaylistPath + Name + '.upl')) then
+ Playlists[Result].Filename := Name + '.upl'
+ else
+ begin
+ repeat
+ Inc(I);
+ until not FileExists(PlaylistPath + Name + InttoStr(I) + '.upl');
+ Playlists[Result].Filename := Name + InttoStr(I) + '.upl';
+ end;
+
+ //Save new Playlist
+ SavePlayList(Result);
+end;
+
+//----------
+//DelPlaylist - Deletes a Playlist
+//----------
+Procedure TPlayListManager.DelPlaylist(const Index: Cardinal);
+var
+ I: Integer;
+ Filename: String;
+begin
+ If Int(Index) > High(Playlists) then
+ Exit;
+
+ Filename := PlaylistPath + Playlists[Index].Filename;
+
+ //If not FileExists or File is not Writeable then exit
+ If (Not FileExists(Filename)) OR (FileisReadOnly(Filename)) then
+ Exit;
+
+
+ //Delete Playlist from FileSystem
+ if Not DeleteFile(Filename) then
+ Exit;
+
+ //Delete Playlist from Array
+ //move all PLs to the Hole
+ For I := Index to High(Playlists)-1 do
+ PlayLists[I] := PlayLists[I+1];
+
+ //Delete last Playlist
+ SetLength (Playlists, High(Playlists));
+
+ //If Playlist is Displayed atm
+ //-> Display Songs
+ if (CatSongs.CatNumShow = -3) and (Index = CurPlaylist) then
+ begin
+ ScreenSong.UnLoadDetailedCover;
+ ScreenSong.HideCatTL;
+ CatSongs.SetFilter('', 0);
+ ScreenSong.Interaction := 0;
+ ScreenSong.FixSelected;
+ ScreenSong.ChangeMusic;
+ end;
+end;
+
+//----------
+//AddItem - Adds an Item to a specific Playlist
+//----------
+Procedure TPlayListManager.AddItem(const SongID: Cardinal; const iPlaylist: Integer);
+var
+ P: Cardinal;
+ Len: Cardinal;
+begin
+ if iPlaylist = -1 then
+ P := CurPlaylist
+ else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
+ P := iPlaylist
+ else
+ exit;
+
+ if (Int(SongID) <= High(CatSongs.Song)) AND (NOT CatSongs.Song[SongID].Main) then
+ begin
+ Len := Length(Playlists[P].Items);
+ SetLength(Playlists[P].Items, Len + 1);
+
+ Playlists[P].Items[Len].SongID := SongID;
+ Playlists[P].Items[Len].Title := CatSongs.Song[SongID].Title;
+ Playlists[P].Items[Len].Artist := CatSongs.Song[SongID].Artist;
+
+ //Save Changes
+ SavePlayList(P);
+
+ //Correct Display when Editing current Playlist
+ if (CatSongs.CatNumShow = -3) and (P = CurPlaylist) then
+ SetPlaylist(P);
+ end;
+end;
+
+//----------
+//DelItem - Deletes an Item from a specific Playlist
+//----------
+Procedure TPlayListManager.DelItem(const iItem: Cardinal; const iPlaylist: Integer);
+var
+ I: Integer;
+ P: Cardinal;
+begin
+ if iPlaylist = -1 then
+ P := CurPlaylist
+ else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
+ P := iPlaylist
+ else
+ exit;
+
+ if (Int(iItem) <= high(Playlists[P].Items)) then
+ begin
+ //Move all entrys behind deleted one to Front
+ For I := iItem to High(Playlists[P].Items) - 1 do
+ Playlists[P].Items[I] := Playlists[P].Items[I + 1];
+
+ //Delete Last Entry
+ SetLength(PlayLists[P].Items, Length(PlayLists[P].Items) - 1);
+
+ //Save Changes
+ SavePlayList(P);
+ end;
+
+ //Delete Playlist if Last Song is deleted
+ if (Length(PlayLists[P].Items) = 0) then
+ begin
+ DelPlaylist(P);
+ end
+ //Correct Display when Editing current Playlist
+ else if (CatSongs.CatNumShow = -3) and (P = CurPlaylist) then
+ SetPlaylist(P);
+end;
+
+//----------
+//GetNames - Writes Playlist Names in a Array
+//----------
+Procedure TPlayListManager.GetNames(var PLNames: array of String);
+var
+ I: Integer;
+ Len: Integer;
+begin
+ Len := High(Playlists);
+
+ if (Length(PLNames) <> Len + 1) then
+ exit;
+
+ For I := 0 to Len do
+ PLNames[I] := Playlists[I].Name;
+end;
+
+//----------
+//GetIndexbySongID - Returns Index in the specified Playlist of the given Song
+//----------
+Function TPlayListManager.GetIndexbySongID(const SongID: Cardinal; const iPlaylist: Integer): Integer;
+var
+ P: Integer;
+ I: Integer;
+begin
+ Result := -1;
+
+ if iPlaylist = -1 then
+ P := CurPlaylist
+ else if (iPlaylist >= 0) AND (iPlaylist <= high(Playlists)) then
+ P := iPlaylist
+ else
+ exit;
+
+ For I := 0 to high(Playlists[P].Items) do
+ begin
+ if (Playlists[P].Items[I].SongID = Int(SongID)) then
+ begin
+ Result := I;
+ Break;
+ end;
+ end;
+end;
+
+end.
diff --git a/src/Classes/UPluginInterface.pas b/src/Classes/UPluginInterface.pas
new file mode 100644
index 00000000..77693d0f
--- /dev/null
+++ b/src/Classes/UPluginInterface.pas
@@ -0,0 +1,156 @@
+unit uPluginInterface;
+{*********************
+ uPluginInterface
+ Unit fills a TPluginInterface Structur with Method Pointers
+ Unit Contains all Functions called directly by Plugins
+*********************}
+
+interface
+
+{$I switches.inc}
+
+uses uPluginDefs;
+
+//---------------
+// Methods for Plugin
+//---------------
+ {******** Hook specific Methods ********}
+ {Function Creates a new Hookable Event and Returns the Handle
+ or 0 on Failure. (Name already exists)}
+ Function CreateHookableEvent (EventName: PChar): THandle; stdcall;
+
+ {Function Destroys an Event and Unhooks all Hooks to this Event.
+ 0 on success, not 0 on Failure}
+ Function DestroyHookableEvent (hEvent: THandle): integer; stdcall;
+
+ {Function start calling the Hook Chain
+ 0 if Chain is called until the End, -1 if Event Handle is not valid
+ otherwise Return Value of the Hook that breaks the Chain}
+ Function NotivyEventHooks (hEvent: THandle; wParam: TwParam; lParam: TlParam): integer; stdcall;
+
+ {Function Hooks an Event by Name.
+ Returns Hook Handle on Success, otherwise 0}
+ Function HookEvent (EventName: PChar; HookProc: TUS_Hook): THandle; stdcall;
+
+ {Function Removes the Hook from the Chain
+ Returns 0 on Success}
+ Function UnHookEvent (hHook: THandle): Integer; stdcall;
+
+ {Function Returns Non Zero if a Event with the given Name Exists,
+ otherwise 0}
+ Function EventExists (EventName: PChar): Integer; stdcall;
+
+ {******** Service specific Methods ********}
+ {Function Creates a new Service and Returns the Services Handle
+ or 0 on Failure. (Name already exists)}
+ Function CreateService (ServiceName: PChar; ServiceProc: TUS_Service): THandle; stdcall;
+
+ {Function Destroys a Service.
+ 0 on success, not 0 on Failure}
+ Function DestroyService (hService: THandle): integer; stdcall;
+
+ {Function Calls a Services Proc
+ Returns Services Return Value or SERVICE_NOT_FOUND on Failure}
+ Function CallService (ServiceName: PChar; wParam: TwParam; lParam: TlParam): integer; stdcall;
+
+ {Function Returns Non Zero if a Service with the given Name Exists,
+ otherwise 0}
+ Function ServiceExists (ServiceName: PChar): Integer; stdcall;
+
+implementation
+uses UCore;
+
+{******** Hook specific Methods ********}
+//---------------
+// Function Creates a new Hookable Event and Returns the Handle
+// or 0 on Failure. (Name already exists)
+//---------------
+Function CreateHookableEvent (EventName: PChar): THandle; stdcall;
+begin
+ Result := Core.Hooks.AddEvent(EventName);
+end;
+
+//---------------
+// Function Destroys an Event and Unhooks all Hooks to this Event.
+// 0 on success, not 0 on Failure
+//---------------
+Function DestroyHookableEvent (hEvent: THandle): integer; stdcall;
+begin
+ Result := Core.Hooks.DelEvent(hEvent);
+end;
+
+//---------------
+// Function start calling the Hook Chain
+// 0 if Chain is called until the End, -1 if Event Handle is not valid
+// otherwise Return Value of the Hook that breaks the Chain
+//---------------
+Function NotivyEventHooks (hEvent: THandle; wParam: TwParam; lParam: TlParam): integer; stdcall;
+begin
+ Result := Core.Hooks.CallEventChain(hEvent, wParam, lParam);
+end;
+
+//---------------
+// Function Hooks an Event by Name.
+// Returns Hook Handle on Success, otherwise 0
+//---------------
+Function HookEvent (EventName: PChar; HookProc: TUS_Hook): THandle; stdcall;
+begin
+ Result := Core.Hooks.AddSubscriber(EventName, HookProc);
+end;
+
+//---------------
+// Function Removes the Hook from the Chain
+// Returns 0 on Success
+//---------------
+Function UnHookEvent (hHook: THandle): Integer; stdcall;
+begin
+ Result := Core.Hooks.DelSubscriber(hHook);
+end;
+
+//---------------
+// Function Returns Non Zero if a Event with the given Name Exists,
+// otherwise 0
+//---------------
+Function EventExists (EventName: PChar): Integer; stdcall;
+begin
+ Result := Core.Hooks.EventExists(EventName);
+end;
+
+ {******** Service specific Methods ********}
+//---------------
+// Function Creates a new Service and Returns the Services Handle
+// or 0 on Failure. (Name already exists)
+//---------------
+Function CreateService (ServiceName: PChar; ServiceProc: TUS_Service): THandle; stdcall;
+begin
+ Result := Core.Services.AddService(ServiceName, ServiceProc);
+end;
+
+//---------------
+// Function Destroys a Service.
+// 0 on success, not 0 on Failure
+//---------------
+Function DestroyService (hService: THandle): integer; stdcall;
+begin
+ Result := Core.Services.DelService(hService);
+end;
+
+//---------------
+// Function Calls a Services Proc
+// Returns Services Return Value or SERVICE_NOT_FOUND on Failure
+//---------------
+Function CallService (ServiceName: PChar; wParam: TwParam; lParam: TlParam): integer; stdcall;
+begin
+ Result := Core.Services.CallService(ServiceName, wParam, lParam);
+end;
+
+//---------------
+// Function Returns Non Zero if a Service with the given Name Exists,
+// otherwise 0
+//---------------
+Function ServiceExists (ServiceName: PChar): Integer; stdcall;
+begin
+ Result := Core.Services.ServiceExists(ServiceName);
+end;
+
+end.
diff --git a/src/Classes/URecord.pas b/src/Classes/URecord.pas
new file mode 100644
index 00000000..8a537dc9
--- /dev/null
+++ b/src/Classes/URecord.pas
@@ -0,0 +1,766 @@
+unit URecord;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes,
+ Math,
+ SysUtils,
+ sdl,
+ UCommon,
+ UMusic,
+ UIni;
+
+const
+ BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz)
+ NumHalftones = 36; // C2-B4 (for Whitney and my high voice)
+
+type
+ TCaptureBuffer = class
+ private
+ VoiceStream: TAudioVoiceStream; // stream for voice passthrough
+ AnalysisBufferLock: PSDL_Mutex;
+
+ function GetToneString: string; // converts a tone to its string represenatation;
+
+ procedure BoostBuffer(Buffer: PChar; Size: Cardinal);
+ procedure ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
+
+ // we call it to analyze sound by checking Autocorrelation
+ procedure AnalyzeByAutocorrelation;
+ // use this to check one frequency by Autocorrelation
+ function AnalyzeAutocorrelationFreq(Freq: real): real;
+ public
+ AnalysisBuffer: array[0..4095] of smallint; // newest 4096 samples
+ AnalysisBufferSize: integer; // number of samples of BufferArray to analyze
+
+ LogBuffer: TMemoryStream; // full buffer
+
+ AudioFormat: TAudioFormatInfo;
+
+ // pitch detection
+ // TODO: remove ToneValid, set Tone/ToneAbs=-1 if invalid instead
+ ToneValid: boolean; // true if Tone contains a valid value (otherwise it contains noise)
+ Tone: integer; // tone relative to one octave (e.g. C2=C3=C4). Range: 0-11
+ ToneAbs: integer; // absolute (full range) tone (e.g. C2<>C3). Range: 0..NumHalftones-1
+
+ // methods
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure Clear;
+
+ // use to analyze sound from buffers to get new pitch
+ procedure AnalyzeBuffer;
+ procedure LockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure UnlockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
+
+ function MaxSampleVolume: Single;
+ property ToneString: string READ GetToneString;
+ end;
+
+const
+ DEFAULT_SOURCE_NAME = '[Default]';
+
+type
+ TAudioInputSource = record
+ Name: string;
+ end;
+
+ // soundcard input-devices information
+ TAudioInputDevice = class
+ public
+ CfgIndex: integer; // index of this device in Ini.InputDeviceConfig
+ Name: string; // soundcard name
+ Source: array of TAudioInputSource; // soundcard input-sources
+ SourceRestore: integer; // source-index that will be selected after capturing (-1: not detected)
+ MicSource: integer; // source-index of mic (-1: none detected)
+
+ AudioFormat: TAudioFormatInfo; // capture format info (e.g. 44.1kHz SInt16 stereo)
+ CaptureChannel: array of TCaptureBuffer; // sound-buffer references used for mono or stereo channel's capture data
+
+ destructor Destroy; override;
+
+ procedure LinkCaptureBuffer(ChannelIndex: integer; Sound: TCaptureBuffer);
+
+ // TODO: add Open/Close functions so Start/Stop becomes faster
+ //function Open(): boolean; virtual; abstract;
+ //function Close(): boolean; virtual; abstract;
+ function Start(): boolean; virtual; abstract;
+ function Stop(): boolean; virtual; abstract;
+
+ function GetVolume(): single; virtual; abstract;
+ procedure SetVolume(Volume: single); virtual; abstract;
+ end;
+
+ TAudioInputProcessor = class
+ public
+ Sound: array of TCaptureBuffer; // sound-buffers for every player
+ DeviceList: array of TAudioInputDevice;
+
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure UpdateInputDeviceConfig;
+
+ // handle microphone input
+ procedure HandleMicrophoneData(Buffer: PChar; Size: Cardinal;
+ InputDevice: TAudioInputDevice);
+ end;
+
+ TAudioInputBase = class( TInterfacedObject, IAudioInput )
+ private
+ Started: boolean;
+ protected
+ function UnifyDeviceName(const name: string; deviceIndex: integer): string;
+ public
+ function GetName: String; virtual; abstract;
+ function InitializeRecord: boolean; virtual; abstract;
+ function FinalizeRecord: boolean; virtual;
+
+ procedure CaptureStart;
+ procedure CaptureStop;
+ end;
+
+
+ TSmallIntArray = array [0..(MaxInt div SizeOf(SmallInt))-1] of SmallInt;
+ PSmallIntArray = ^TSmallIntArray;
+
+ function AudioInputProcessor(): TAudioInputProcessor;
+
+implementation
+
+uses
+ ULog,
+ UMain;
+
+var
+ singleton_AudioInputProcessor : TAudioInputProcessor = nil;
+
+
+{ Global }
+
+function AudioInputProcessor(): TAudioInputProcessor;
+begin
+ if singleton_AudioInputProcessor = nil then
+ singleton_AudioInputProcessor := TAudioInputProcessor.create();
+
+ result := singleton_AudioInputProcessor;
+end;
+
+
+{ TAudioInputDevice }
+
+destructor TAudioInputDevice.Destroy;
+begin
+ Stop();
+ Source := nil;
+ CaptureChannel := nil;
+ FreeAndNil(AudioFormat);
+ inherited Destroy;
+end;
+
+procedure TAudioInputDevice.LinkCaptureBuffer(ChannelIndex: integer; Sound: TCaptureBuffer);
+var
+ DeviceCfg: PInputDeviceConfig;
+ OldSound: TCaptureBuffer;
+begin
+ // check bounds
+ if ((ChannelIndex < 0) or (ChannelIndex > High(CaptureChannel))) then
+ Exit;
+
+ // reset previously assigned (old) capture-buffer
+ OldSound := CaptureChannel[ChannelIndex];
+ if (OldSound <> nil) then
+ begin
+ // close voice stream
+ FreeAndNil(OldSound.VoiceStream);
+ // free old audio-format info
+ FreeAndNil(OldSound.AudioFormat);
+ end;
+
+ // set audio-format of new capture-buffer
+ if (Sound <> nil) then
+ begin
+ // copy the input-device audio-format ...
+ Sound.AudioFormat := AudioFormat.Copy;
+ // and adjust it because capture buffers are always mono
+ Sound.AudioFormat.Channels := 1;
+ DeviceCfg := @Ini.InputDeviceConfig[CfgIndex];
+
+ if (Ini.VoicePassthrough = 1) then
+ begin
+ // TODO: map odd players to the left and even players to the right speaker
+ Sound.VoiceStream := AudioPlayback.CreateVoiceStream(CHANNELMAP_FRONT, AudioFormat);
+ end;
+ end;
+
+ // replace old with new buffer (Note: Sound might be nil)
+ CaptureChannel[ChannelIndex] := Sound;
+end;
+
+{ TSound }
+
+constructor TCaptureBuffer.Create;
+begin
+ inherited;
+ LogBuffer := TMemoryStream.Create;
+ AnalysisBufferLock := SDL_CreateMutex();
+ AnalysisBufferSize := Length(AnalysisBuffer);
+end;
+
+destructor TCaptureBuffer.Destroy;
+begin
+ FreeAndNil(LogBuffer);
+ FreeAndNil(VoiceStream);
+ FreeAndNil(AudioFormat);
+ SDL_DestroyMutex(AnalysisBufferLock);
+ inherited;
+end;
+
+procedure TCaptureBuffer.LockAnalysisBuffer();
+begin
+ SDL_mutexP(AnalysisBufferLock);
+end;
+
+procedure TCaptureBuffer.UnlockAnalysisBuffer();
+begin
+ SDL_mutexV(AnalysisBufferLock);
+end;
+
+procedure TCaptureBuffer.Clear;
+begin
+ if assigned(LogBuffer) then
+ LogBuffer.Clear;
+ LockAnalysisBuffer();
+ FillChar(AnalysisBuffer[0], Length(AnalysisBuffer) * SizeOf(SmallInt), 0);
+ UnlockAnalysisBuffer();
+end;
+
+procedure TCaptureBuffer.ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
+var
+ BufferOffset: integer;
+ SampleCount: integer;
+ i: integer;
+begin
+ // apply software boost
+ //BoostBuffer(Buffer, Size);
+
+ // voice passthrough (send data to playback-device)
+ if (assigned(VoiceStream)) then
+ VoiceStream.WriteData(Buffer, BufferSize);
+
+ // we assume that samples are in S16Int format
+ // TODO: support float too
+ if (AudioFormat.Format <> asfS16) then
+ Exit;
+
+ // process BufferArray
+ BufferOffset := 0;
+
+ SampleCount := BufferSize div SizeOf(SmallInt);
+
+ // check if we have more new samples than we can store
+ if (SampleCount > Length(AnalysisBuffer)) then
+ begin
+ // discard the oldest of the new samples
+ BufferOffset := (SampleCount - Length(AnalysisBuffer)) * SizeOf(SmallInt);
+ SampleCount := Length(AnalysisBuffer);
+ end;
+
+
+ LockAnalysisBuffer();
+ try
+
+ // move old samples to the beginning of the array (if necessary)
+ for i := 0 to High(AnalysisBuffer)-SampleCount do
+ AnalysisBuffer[i] := AnalysisBuffer[i+SampleCount];
+
+ // copy new samples to analysis buffer
+ Move(Buffer[BufferOffset], AnalysisBuffer[Length(AnalysisBuffer)-SampleCount],
+ SampleCount * SizeOf(SmallInt));
+
+ finally
+ UnlockAnalysisBuffer();
+ end;
+
+
+ // save capture-data to BufferLong if enabled
+ if (Ini.SavePlayback = 1) then
+ begin
+ // this is just for debugging (approx 15MB per player for a 3min song!!!)
+ // For an in-game replay-mode we need to compress data so we do not
+ // waste that much memory. Maybe ogg-vorbis with voice-preset in fast-mode?
+ // Or we could use a faster but not that efficient lossless compression.
+ LogBuffer.WriteBuffer(Buffer, BufferSize);
+ end;
+end;
+
+procedure TCaptureBuffer.AnalyzeBuffer;
+var
+ Volume: single;
+ MaxVolume: single;
+ SampleIndex: integer;
+ Threshold: single;
+begin
+ ToneValid := false;
+ ToneAbs := -1;
+ Tone := -1;
+
+ LockAnalysisBuffer();
+ try
+
+ // find maximum volume of first 1024 samples
+ MaxVolume := 0;
+ for SampleIndex := 0 to 1023 do
+ begin
+ Volume := Abs(AnalysisBuffer[SampleIndex]) / -Low(Smallint);
+ if Volume > MaxVolume then
+ MaxVolume := Volume;
+ end;
+
+ Threshold := IThresholdVals[Ini.ThresholdIndex];
+
+ // check if signal has an acceptable volume (ignore background-noise)
+ if MaxVolume >= Threshold then
+ begin
+ // analyse the current voice pitch
+ AnalyzeByAutocorrelation;
+ ToneValid := true;
+ end;
+
+ finally
+ UnlockAnalysisBuffer();
+ end;
+end;
+
+procedure TCaptureBuffer.AnalyzeByAutocorrelation;
+var
+ ToneIndex: integer;
+ CurFreq: real;
+ CurWeight: real;
+ MaxWeight: real;
+ MaxTone: integer;
+const
+ HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave)
+begin
+ // prepare to analyze
+ MaxWeight := -1;
+ MaxTone := 0; // this is not needed, but it satifies the compiler
+
+ // analyze halftones
+ // Note: at the lowest tone (~65Hz) and a buffer-size of 4096
+ // at 44.1 (or 48kHz) only 6 (or 5) samples are compared, this might be
+ // too few samples -> use a bigger buffer-size
+ for ToneIndex := 0 to NumHalftones-1 do
+ begin
+ CurFreq := BaseToneFreq * Power(HalftoneBase, ToneIndex);
+ CurWeight := AnalyzeAutocorrelationFreq(CurFreq);
+
+ // TODO: prefer higher frequencies (use >= or use downto)
+ if (CurWeight > MaxWeight) then
+ begin
+ // this frequency has a higher weight
+ MaxWeight := CurWeight;
+ MaxTone := ToneIndex;
+ end;
+ end;
+
+ ToneAbs := MaxTone;
+ Tone := MaxTone mod 12;
+end;
+
+// result medium difference
+function TCaptureBuffer.AnalyzeAutocorrelationFreq(Freq: real): real;
+var
+ Dist: real; // distance (0=equal .. 1=totally different) between correlated samples
+ AccumDist: real; // accumulated distances
+ SampleIndex: integer; // index of sample to analyze
+ CorrelatingSampleIndex: integer; // index of sample one period ahead
+ SamplesPerPeriod: integer; // samples in one period
+begin
+ SampleIndex := 0;
+ SamplesPerPeriod := Round(AudioFormat.SampleRate/Freq);
+ CorrelatingSampleIndex := SampleIndex + SamplesPerPeriod;
+
+ AccumDist := 0;
+
+ // compare correlating samples
+ while (CorrelatingSampleIndex < AnalysisBufferSize) do
+ begin
+ // calc distance (correlation: 1-dist) to corresponding sample in next period
+ Dist := Abs(AnalysisBuffer[SampleIndex] - AnalysisBuffer[CorrelatingSampleIndex]) /
+ High(Word);
+ AccumDist := AccumDist + Dist;
+ Inc(SampleIndex);
+ Inc(CorrelatingSampleIndex);
+ end;
+
+ // return "inverse" average distance (=correlation)
+ Result := 1 - AccumDist / AnalysisBufferSize;
+end;
+
+function TCaptureBuffer.MaxSampleVolume: Single;
+var
+ lSampleIndex: Integer;
+ lMaxVol : Longint;
+begin;
+ LockAnalysisBuffer();
+ try
+ lMaxVol := 0;
+ for lSampleIndex := 0 to High(AnalysisBuffer) do
+ begin
+ if Abs(AnalysisBuffer[lSampleIndex]) > lMaxVol then
+ lMaxVol := Abs(AnalysisBuffer[lSampleIndex]);
+ end;
+ finally
+ UnlockAnalysisBuffer();
+ end;
+
+ result := lMaxVol / -Low(Smallint);
+end;
+
+const
+ ToneStrings: array[0..11] of string = (
+ 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'
+ );
+
+function TCaptureBuffer.GetToneString: string;
+begin
+ if (ToneValid) then
+ Result := ToneStrings[Tone] + IntToStr(ToneAbs div 12 + 2)
+ else
+ Result := '-';
+end;
+
+procedure TCaptureBuffer.BoostBuffer(Buffer: PChar; Size: Cardinal);
+var
+ i: integer;
+ Value: Longint;
+ SampleCount: integer;
+ SampleBuffer: PSmallIntArray; // buffer handled as array of samples
+ Boost: byte;
+begin
+ // TODO: set boost per device
+ {
+ case Ini.MicBoost of
+ 0: Boost := 1;
+ 1: Boost := 2;
+ 2: Boost := 4;
+ 3: Boost := 8;
+ else Boost := 1;
+ end;
+ }
+ Boost := 1;
+
+ // at the moment we will boost SInt16 data only
+ if (AudioFormat.Format = asfS16) then
+ begin
+ // interpret buffer as buffer of bytes
+ SampleBuffer := PSmallIntArray(Buffer);
+ SampleCount := Size div AudioFormat.FrameSize;
+
+ // boost buffer
+ for i := 0 to SampleCount-1 do
+ begin
+ Value := SampleBuffer^[i] * Boost;
+
+ // TODO : JB - This will clip the audio... cant we reduce the "Boost" if the data clips ??
+ if Value > High(Smallint) then
+ Value := High(Smallint);
+
+ if Value < Low(Smallint) then
+ Value := Low(Smallint);
+
+ SampleBuffer^[i] := Value;
+ end;
+ end;
+end;
+
+
+{ TAudioInputProcessor }
+
+constructor TAudioInputProcessor.Create;
+var
+ i: integer;
+begin
+ inherited;
+ SetLength(Sound, 6 {max players});//Ini.Players+1);
+ for i := 0 to High(Sound) do
+ Sound[i] := TCaptureBuffer.Create;
+end;
+
+destructor TAudioInputProcessor.Destroy;
+var
+ i: integer;
+begin
+ for i := 0 to High(Sound) do
+ Sound[i].Free;
+ SetLength(Sound, 0);
+ inherited;
+end;
+
+// updates InputDeviceConfig with current input-device information
+// See: TIni.LoadInputDeviceCfg()
+procedure TAudioInputProcessor.UpdateInputDeviceConfig;
+var
+ deviceIndex: integer;
+ newDevice: boolean;
+ deviceIniIndex: integer;
+ deviceCfg: PInputDeviceConfig;
+ device: TAudioInputDevice;
+ channelCount: integer;
+ channelIndex: integer;
+ i: integer;
+begin
+ // Input devices - append detected soundcards
+ for deviceIndex := 0 to High(DeviceList) do
+ begin
+ newDevice := true;
+ //Search for Card in List
+ for deviceIniIndex := 0 to High(Ini.InputDeviceConfig) do
+ begin
+ deviceCfg := @Ini.InputDeviceConfig[deviceIniIndex];
+ device := DeviceList[deviceIndex];
+
+ if (deviceCfg.Name = Trim(device.Name)) then
+ begin
+ newDevice := false;
+
+ // store highest channel index as an offset for the new channels
+ channelIndex := High(deviceCfg.ChannelToPlayerMap);
+ // add missing channels or remove non-existing ones
+ SetLength(deviceCfg.ChannelToPlayerMap, device.AudioFormat.Channels);
+ // initialize added channels to 0
+ for i := channelIndex+1 to High(deviceCfg.ChannelToPlayerMap) do
+ begin
+ deviceCfg.ChannelToPlayerMap[i] := 0;
+ end;
+
+ // associate ini-index with device
+ device.CfgIndex := deviceIniIndex;
+ break;
+ end;
+ end;
+
+ //If not in List -> Add
+ if newDevice then
+ begin
+ // resize list
+ SetLength(Ini.InputDeviceConfig, Length(Ini.InputDeviceConfig)+1);
+ deviceCfg := @Ini.InputDeviceConfig[High(Ini.InputDeviceConfig)];
+ device := DeviceList[deviceIndex];
+
+ // associate ini-index with device
+ device.CfgIndex := High(Ini.InputDeviceConfig);
+
+ deviceCfg.Name := Trim(device.Name);
+ deviceCfg.Input := 0;
+
+ channelCount := device.AudioFormat.Channels;
+ SetLength(deviceCfg.ChannelToPlayerMap, channelCount);
+
+ for channelIndex := 0 to channelCount-1 do
+ begin
+ // set default at first start of USDX (1st device, 1st channel -> player1)
+ if ((channelIndex = 0) and (device.CfgIndex = 0)) then
+ deviceCfg.ChannelToPlayerMap[0] := 1
+ else
+ deviceCfg.ChannelToPlayerMap[channelIndex] := 0;
+ end;
+ end;
+ end;
+end;
+
+{*
+ * Handles captured microphone input data.
+ * Params:
+ * Buffer - buffer of signed 16bit interleaved stereo PCM-samples.
+ * Interleaved means that a right-channel sample follows a left-
+ * channel sample and vice versa (0:left[0],1:right[0],2:left[1],...).
+ * Length - number of bytes in Buffer
+ * Input - Soundcard-Input used for capture
+ *}
+procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: PChar; Size: Cardinal; InputDevice: TAudioInputDevice);
+var
+ MultiChannelBuffer: PChar; // buffer handled as array of bytes (offset relative to channel)
+ SingleChannelBuffer: PChar; // temporary buffer for new samples per channel
+ SingleChannelBufferSize: integer;
+ ChannelIndex: integer;
+ CaptureChannel: TCaptureBuffer;
+ AudioFormat: TAudioFormatInfo;
+ SampleSize: integer;
+ SampleCount: integer;
+ SamplesPerChannel: integer;
+ i: integer;
+begin
+ AudioFormat := InputDevice.AudioFormat;
+ SampleSize := AudioSampleSize[AudioFormat.Format];
+ SampleCount := Size div SampleSize;
+ SamplesPerChannel := Size div AudioFormat.FrameSize;
+
+ SingleChannelBufferSize := SamplesPerChannel * SampleSize;
+ GetMem(SingleChannelBuffer, SingleChannelBufferSize);
+
+ // process channels
+ for ChannelIndex := 0 to High(InputDevice.CaptureChannel) do
+ begin
+ CaptureChannel := InputDevice.CaptureChannel[ChannelIndex];
+ // check if a capture buffer was assigned, otherwise there is nothing to do
+ if (CaptureChannel <> nil) then
+ begin
+ // set offset according to channel index
+ MultiChannelBuffer := @Buffer[ChannelIndex * SampleSize];
+ // seperate channel-data from interleaved multi-channel (e.g. stereo) data
+ for i := 0 to SamplesPerChannel-1 do
+ begin
+ Move(MultiChannelBuffer[i*AudioFormat.FrameSize],
+ SingleChannelBuffer[i*SampleSize],
+ SampleSize);
+ end;
+ CaptureChannel.ProcessNewBuffer(SingleChannelBuffer, SingleChannelBufferSize);
+ end;
+ end;
+
+ FreeMem(SingleChannelBuffer);
+end;
+
+
+{ TAudioInputBase }
+
+function TAudioInputBase.FinalizeRecord: boolean;
+var
+ i: integer;
+begin
+ for i := 0 to High(AudioInputProcessor.DeviceList) do
+ AudioInputProcessor.DeviceList[i].Free();
+ AudioInputProcessor.DeviceList := nil;
+ Result := true;
+end;
+
+{*
+ * Start capturing on all used input-device.
+ *}
+procedure TAudioInputBase.CaptureStart;
+var
+ S: integer;
+ DeviceIndex: integer;
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+ DeviceUsed: boolean;
+ Player: integer;
+begin
+ if (Started) then
+ CaptureStop();
+
+ // reset buffers
+ for S := 0 to High(AudioInputProcessor.Sound) do
+ AudioInputProcessor.Sound[S].Clear;
+
+ // start capturing on each used device
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ Device := AudioInputProcessor.DeviceList[DeviceIndex];
+ if not assigned(Device) then
+ continue;
+ DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
+
+ DeviceUsed := false;
+
+ // check if device is used
+ for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
+ begin
+ Player := DeviceCfg.ChannelToPlayerMap[ChannelIndex]-1;
+ if (Player < 0) or (Player >= PlayersPlay) then
+ begin
+ Device.LinkCaptureBuffer(ChannelIndex, nil);
+ end
+ else
+ begin
+ Device.LinkCaptureBuffer(ChannelIndex, AudioInputProcessor.Sound[Player]);
+ DeviceUsed := true;
+ end;
+ end;
+
+ // start device if used
+ if (DeviceUsed) then
+ begin
+ //Log.BenchmarkStart(2);
+ Device.Start();
+ //Log.BenchmarkEnd(2);
+ //Log.LogBenchmark('Device.Start', 2) ;
+ end;
+ end;
+
+ Started := true;
+end;
+
+{*
+ * Stop input-capturing on all soundcards.
+ *}
+procedure TAudioInputBase.CaptureStop;
+var
+ DeviceIndex: integer;
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+begin
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ Device := AudioInputProcessor.DeviceList[DeviceIndex];
+ if not assigned(Device) then
+ continue;
+
+ Device.Stop();
+
+ // disconnect capture buffers
+ DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
+ for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
+ Device.LinkCaptureBuffer(ChannelIndex, nil);
+ end;
+
+ Started := false;
+end;
+
+function TAudioInputBase.UnifyDeviceName(const name: string; deviceIndex: integer): string;
+var
+ count: integer; // count of devices with this name
+
+ function IsDuplicate(const name: string): boolean;
+ var
+ i: integer;
+ begin
+ Result := False;
+ // search devices with same description
+ For i := 0 to deviceIndex-1 do
+ begin
+ if (AudioInputProcessor.DeviceList[i].Name = name) then
+ begin
+ Result := True;
+ Break;
+ end;
+ end;
+ end;
+begin
+ count := 1;
+ result := name;
+
+ // if there is another device with the same ID, search for an available name
+ while (IsDuplicate(result)) do
+ begin
+ Inc(count);
+ // set description
+ result := name + ' ('+IntToStr(count)+')';
+ end;
+end;
+
+end.
+
+
+
diff --git a/src/Classes/URingBuffer.pas b/src/Classes/URingBuffer.pas
new file mode 100644
index 00000000..ce51e209
--- /dev/null
+++ b/src/Classes/URingBuffer.pas
@@ -0,0 +1,128 @@
+unit URingBuffer;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils;
+
+type
+ TRingBuffer = class
+ private
+ RingBuffer: PChar;
+ BufferCount: integer;
+ BufferSize: integer;
+ WritePos: integer;
+ ReadPos: integer;
+ public
+ constructor Create(Size: integer);
+ destructor Destroy; override;
+ function Read(Buffer: PChar; Count: integer): integer;
+ function Write(Buffer: PChar; Count: integer): integer;
+ procedure Flush();
+ end;
+
+implementation
+
+uses
+ Math;
+
+constructor TRingBuffer.Create(Size: integer);
+begin
+ BufferSize := Size;
+
+ GetMem(RingBuffer, Size);
+ if (RingBuffer = nil) then
+ raise Exception.Create('No memory');
+end;
+
+destructor TRingBuffer.Destroy;
+begin
+ FreeMem(RingBuffer);
+end;
+
+function TRingBuffer.Read(Buffer: PChar; Count: integer): integer;
+var
+ PartCount: integer;
+begin
+ // adjust output count
+ if (Count > BufferCount) then
+ begin
+ //DebugWriteln('Read too much: ' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
+ Count := BufferCount;
+ end;
+
+ // check if there is something to do
+ if (Count <= 0) then
+ begin
+ Result := Count;
+ Exit;
+ end;
+
+ // copy data to output buffer
+
+ // first step: copy from the area between the read-position and the end of the buffer
+ PartCount := Min(Count, BufferSize - ReadPos);
+ Move(RingBuffer[ReadPos], Buffer[0], PartCount);
+
+ // second step: if we need more data, copy from the beginning of the buffer
+ if (PartCount < Count) then
+ Move(RingBuffer[0], Buffer[0], Count-PartCount);
+
+ // mark the copied part of the buffer as free
+ BufferCount := BufferCount - Count;
+ ReadPos := (ReadPos + Count) mod BufferSize;
+
+ Result := Count;
+end;
+
+function TRingBuffer.Write(Buffer: PChar; Count: integer): integer;
+var
+ PartCount: integer;
+begin
+ // check for a reasonable request
+ if (Count <= 0) then
+ begin
+ Result := Count;
+ Exit;
+ end;
+
+ // skip input data if the input buffer is bigger than the ring-buffer
+ if (Count > BufferSize) then
+ begin
+ //DebugWriteln('Write skip data:' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
+ Buffer := @Buffer[Count - BufferSize];
+ Count := BufferSize;
+ end;
+
+ // first step: copy to the area between the write-position and the end of the buffer
+ PartCount := Min(Count, BufferSize - WritePos);
+ Move(Buffer[0], RingBuffer[WritePos], PartCount);
+
+ // second step: copy data to front of buffer
+ if (PartCount < Count) then
+ Move(Buffer[PartCount], RingBuffer[0], Count-PartCount);
+
+ // update info
+ BufferCount := Min(BufferCount + Count, BufferSize);
+ WritePos := (WritePos + Count) mod BufferSize;
+ // if the buffer is full, we have to reposition the read-position
+ if (BufferCount = BufferSize) then
+ ReadPos := WritePos;
+
+ Result := Count;
+end;
+
+procedure TRingBuffer.Flush();
+begin
+ ReadPos := 0;
+ WritePos := 0;
+ BufferCount := 0;
+end;
+
+end.
\ No newline at end of file
diff --git a/src/Classes/UServices.pas b/src/Classes/UServices.pas
new file mode 100644
index 00000000..6325444c
--- /dev/null
+++ b/src/Classes/UServices.pas
@@ -0,0 +1,358 @@
+unit UServices;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses uPluginDefs,
+ SysUtils;
+{*********************
+ TServiceManager
+ Class for saving, managing and calling of Services.
+ Saves all Services and their Procs
+*********************}
+
+type
+ TServiceName = String[60];
+ PServiceInfo = ^TServiceInfo;
+ TServiceInfo = record
+ Self: THandle; //Handle of this Service
+ Hash: Integer; //4 Bit Hash of the Services Name
+ Name: TServiceName; //Name of this Service
+
+ Owner: Integer; //If < 0 [-(DLLMan Pluginindex + 1)]; 0 - undefined, On Error Full shutdown, If < 0 [ModuleIndex - 1]
+
+ Next: PServiceInfo; //Pointer to the Next Service in teh list
+
+ //Here is s/t tricky
+ //To avoid writing of Wrapping Functions to offer a Service from a Class
+ //We save a Normal Proc or a Method of a Class
+ Case isClass: boolean of
+ False: (Proc: TUS_Service); //Proc that will be called on Event
+ True: (ProcOfClass: TUS_Service_of_Object);
+ end;
+
+ TServiceManager = class
+ private
+ //Managing Service List
+ FirstService: PServiceInfo;
+ LastService: PServiceInfo;
+
+ //Some Speed improvement by caching the last 4 called Services
+ //Most of the time a Service is called multiple times
+ ServiceCache: Array[0..3] of PServiceInfo;
+ NextCacheItem: Byte;
+
+ //Next Service added gets this Handle:
+ NextHandle: THandle;
+ public
+ Constructor Create;
+
+ Function AddService(const ServiceName: PChar; const Proc: TUS_Service = nil; const ProcofClass: TUS_Service_of_Object = nil): THandle;
+ Function DelService(const hService: THandle): integer;
+
+ Function CallService(const ServiceName: PChar; const wParam: TwParam; lParam: TlParam): integer;
+
+ Function NametoHash(const ServiceName: TServiceName): Integer;
+ Function ServiceExists(const ServiceName: PChar): Integer;
+ end;
+
+var
+ ServiceManager: TServiceManager;
+
+implementation
+uses
+ ULog,
+ UCore;
+
+//------------
+// Create - Creates Class and Set Standard Values
+//------------
+Constructor TServiceManager.Create;
+begin
+ inherited;
+
+ FirstService := nil;
+ LastService := nil;
+
+ ServiceCache[0] := nil;
+ ServiceCache[1] := nil;
+ ServiceCache[2] := nil;
+ ServiceCache[3] := nil;
+
+ NextCacheItem := 0;
+
+ NextHandle := 1;
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Succesful created!');
+ {$ENDIF}
+end;
+
+//------------
+// Function Creates a new Service and Returns the Services Handle,
+// 0 on Failure. (Name already exists)
+//------------
+Function TServiceManager.AddService(const ServiceName: PChar; const Proc: TUS_Service; const ProcofClass: TUS_Service_of_Object): THandle;
+var
+ Cur: PServiceInfo;
+begin
+ Result := 0;
+
+ If (@Proc <> nil) or (@ProcOfClass <> nil) then
+ begin
+ If (ServiceExists(ServiceName) = 0) then
+ begin //There is a Proc and the Service does not already exist
+ //Ok Add it!
+
+ //Get Memory
+ GetMem(Cur, SizeOf(TServiceInfo));
+
+ //Fill it with Data
+ Cur.Next := nil;
+
+ If (@Proc = nil) then
+ begin //Use the ProcofClass Method
+ Cur.isClass := True;
+ Cur.ProcOfClass := ProcofClass;
+ end
+ else //Use the normal Proc
+ begin
+ Cur.isClass := False;
+ Cur.Proc := Proc;
+ end;
+
+ Cur.Self := NextHandle;
+ //Zero Name
+ Cur.Name := #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0;
+ Cur.Name := String(ServiceName);
+ Cur.Hash := NametoHash(Cur.Name);
+
+ //Add Owner to Service
+ Cur.Owner := Core.CurExecuted;
+
+ //Add Service to the List
+ If (FirstService = nil) then
+ FirstService := Cur;
+
+ If (LastService <> nil) then
+ LastService.Next := Cur;
+
+ LastService := Cur;
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Service added: ''' + ServiceName + ''', Handle: ' + InttoStr(Cur.Self));
+ {$ENDIF}
+
+ //Inc Next Handle
+ Inc(NextHandle);
+ end
+ {$IFDEF DEBUG}
+ else debugWriteln('ServiceManager: Try to readd Service: ' + ServiceName);
+ {$ENDIF}
+ end;
+end;
+
+//------------
+// Function Destroys a Service, 0 on success, not 0 on Failure
+//------------
+Function TServiceManager.DelService(const hService: THandle): integer;
+var
+ Last, Cur: PServiceInfo;
+ I: Integer;
+begin
+ Result := -1;
+
+ Last := nil;
+ Cur := FirstService;
+
+ //Search for Service to Delete
+ While (Cur <> nil) do
+ begin
+ If (Cur.Self = hService) then
+ begin //Found Service => Delete it
+
+ //Delete from List
+ If (Last = nil) then //Found first Service
+ FirstService := Cur.Next
+ Else //Service behind the first
+ Last.Next := Cur.Next;
+
+ //IF this is the LastService, correct LastService
+ If (Cur = LastService) then
+ LastService := Last;
+
+ //Search for Service in Cache and delete it if found
+ For I := 0 to High(ServiceCache) do
+ If (ServiceCache[I] = Cur) then
+ begin
+ ServiceCache[I] := nil;
+ end;
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Removed Service succesful: ' + Cur.Name);
+ {$ENDIF}
+
+ //Free Memory
+ Freemem(Cur, SizeOf(TServiceInfo));
+
+ //Break the Loop
+ Break;
+ end;
+
+ //Go to Next Service
+ Last := Cur;
+ Cur := Cur.Next;
+ end;
+end;
+
+//------------
+// Function Calls a Services Proc
+// Returns Services Return Value or SERVICE_NOT_FOUND on Failure
+//------------
+Function TServiceManager.CallService(const ServiceName: PChar; const wParam: TwParam; lParam: TlParam): integer;
+var
+ SExists: Integer;
+ Service: PServiceInfo;
+ CurExecutedBackup: Integer; //backup of Core.CurExecuted Attribute
+begin
+ Result := SERVICE_NOT_FOUND;
+ SExists := ServiceExists(ServiceName);
+ If (SExists <> 0) then
+ begin
+ //Backup CurExecuted
+ CurExecutedBackup := Core.CurExecuted;
+
+ Service := Pointer(SExists);
+
+ If (Service.isClass) then
+ //Use Proc of Class
+ Result := Service.ProcOfClass(wParam, lParam)
+ Else
+ //Use normal Proc
+ Result := Service.Proc(wParam, lParam);
+
+ //Restore CurExecuted
+ Core.CurExecuted := CurExecutedBackup;
+ end;
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Service ''' + ServiceName + ''' called. Result: ' + InttoStr(Result));
+ {$ENDIF}
+end;
+
+//------------
+// Generates the Hash for the given Name
+//------------
+Function TServiceManager.NametoHash(const ServiceName: TServiceName): Integer;
+// FIXME: check if the non-asm version is fast enough and use it by default if so
+{$IF Defined(CPUX86_64)}
+{$IFDEF FPC}
+ {$ASMMODE Intel}
+{$ENDIF}
+asm
+ { CL: Counter; RAX: Result; RDX: Current Memory Address }
+ Mov RCX, 14
+ Mov RDX, ServiceName {Save Address of String that should be "Hashed"}
+ Mov RAX, [RDX]
+ @FoldLoop: ADD RDX, 4 {jump 4 Byte(32 Bit) to the next tile }
+ ADD RAX, [RDX] {Add the Value of the next 4 Byte of the String to the Hash}
+ LOOP @FoldLoop {Fold again if there are Chars Left}
+end;
+{$ELSEIF Defined(CPU386) or Defined(CPUI386)}
+{$IFDEF FPC}
+ {$ASMMODE Intel}
+{$ENDIF}
+asm
+ { CL: Counter; EAX: Result; EDX: Current Memory Address }
+ Mov ECX, 14 {Init Counter, Fold 14 Times to get 4 Bytes out of 60}
+ Mov EDX, ServiceName {Save Address of String that should be "Hashed"}
+ Mov EAX, [EDX]
+ @FoldLoop: ADD EDX, 4 {jump 4 Byte(32 Bit) to the next tile }
+ ADD EAX, [EDX] {Add the Value of the next 4 Byte of the String to the Hash}
+ LOOP @FoldLoop {Fold again if there are Chars Left}
+end;
+{$ELSE}
+var
+ i: integer;
+ ptr: ^integer;
+begin
+ ptr := @ServiceName;
+ Result := 0;
+ for i := 1 to 14 do
+ begin
+ Result := Result + ptr^;
+ Inc(ptr);
+ end;
+end;
+{$IFEND}
+
+
+//------------
+// Function Returns Non Zero if a Service with the given Name Exists, otherwise 0
+//------------
+Function TServiceManager.ServiceExists(const ServiceName: PChar): Integer;
+var
+ Name: TServiceName;
+ Hash: Integer;
+ Cur: PServiceInfo;
+ I: Byte;
+begin
+ Result := 0;
+ // to-do : Write a Metbod (in ASM) to Zero and Add in one turn (faster then this dirty hack ;)
+ //Zero Name:
+ Name := #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0 + #0;
+ //Add Service Name
+ Name := String(ServiceName);
+ Hash := NametoHash(Name);
+
+ //First of all Look for the Service in Cache
+ For I := 0 to High(ServiceCache) do
+ begin
+ If (ServiceCache[I] <> nil) AND (ServiceCache[I].Hash = Hash) then
+ begin
+ If (ServiceCache[I].Name = Name) then
+ begin //Found Service in Cache
+ Result := Integer(ServiceCache[I]);
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Found Service in Cache: ''' + ServiceName + '''');
+ {$ENDIF}
+
+ Break;
+ end;
+ end;
+ end;
+
+ If (Result = 0) then
+ begin
+ Cur := FirstService;
+ While (Cur <> nil) do
+ begin
+ If (Cur.Hash = Hash) then
+ begin
+ If (Cur.Name = Name) then
+ begin //Found the Service
+ Result := Integer(Cur);
+
+ {$IFDEF DEBUG}
+ debugWriteln('ServiceManager: Found Service in List: ''' + ServiceName + '''');
+ {$ENDIF}
+
+ //Add to Cache
+ ServiceCache[NextCacheItem] := Cur;
+ NextCacheItem := (NextCacheItem + 1) AND 3;
+ Break;
+ end;
+ end;
+
+ Cur := Cur.Next;
+ end;
+ end;
+end;
+
+end.
diff --git a/src/Classes/USingNotes.pas b/src/Classes/USingNotes.pas
new file mode 100644
index 00000000..3b268d10
--- /dev/null
+++ b/src/Classes/USingNotes.pas
@@ -0,0 +1,13 @@
+unit USingNotes;
+
+interface
+
+{$I switches.inc}
+
+{ Dummy Unit atm
+ For further expantation
+ Placeholder for Class that will handle the Notes Drawing}
+
+implementation
+
+end.
diff --git a/src/Classes/USingScores.pas b/src/Classes/USingScores.pas
new file mode 100644
index 00000000..77d40b84
--- /dev/null
+++ b/src/Classes/USingScores.pas
@@ -0,0 +1,973 @@
+unit USingScores;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses UThemes,
+ gl,
+ UTexture;
+
+//////////////////////////////////////////////////////////////
+// ATTENTION: //
+// Enabled Flag does not Work atm. This should cause Popups //
+// Not to Move and Scores to stay until Renenabling. //
+// To use e.g. in Pause Mode //
+// Also InVisible Flag causes Attributes not to change. //
+// This should be fixed after next Draw when Visible = True,//
+// but not testet yet //
+//////////////////////////////////////////////////////////////
+
+//Some constants containing options that could change by time
+const
+ MaxPlayers = 6; //Maximum of Players that could be added
+ MaxPositions = 6; //Maximum of Score Positions that could be added
+
+type
+ //-----------
+ // TScorePlayer - Record Containing Information about a Players Score
+ //-----------
+ TScorePlayer = record
+ Position: Byte; //Index of the Position where the Player should be Drawn
+ Enabled: Boolean; //Is the Score Display Enabled
+ Visible: Boolean; //Is the Score Display Visible
+ Score: Word; //Current Score of the Player
+ ScoreDisplayed: Word; //Score cur. Displayed(for counting up)
+ ScoreBG: TTexture;//Texture of the Players Scores BG
+ Color: TRGB; //Teh Players Color
+ RBPos: Real; //Cur. Percentille of the Rating Bar
+ RBTarget: Real; //Target Position of Rating Bar
+ RBVisible:Boolean; //Is Rating bar Drawn
+ end;
+ aScorePlayer = array[0..MaxPlayers-1] of TScorePlayer;
+
+ //-----------
+ // TScorePosition - Record Containing Information about a Score Position, that can be used
+ //-----------
+ PScorePosition = ^TScorePosition;
+ TScorePosition = record
+ //The Position is Used for Which Playercount
+ PlayerCount: Byte;
+ // 1 - One Player per Screen
+ // 2 - 2 Players per Screen
+ // 4 - 3 Players per Screen
+ // 6 would be 2 and 3 Players per Screen
+
+ BGX: Real; //X Position of the Score BG
+ BGY: Real; //Y Position of the Score BG
+ BGW: Real; //Width of the Score BG
+ BGH: Real; //Height of the Score BG
+
+ RBX: Real; //X Position of the Rating Bar
+ RBY: Real; //Y Position of the Rating Bar
+ RBW: Real; //Width of the Rating Bar
+ RBH: Real; //Height of the Rating Bar
+
+ TextX: Real; //X Position of the Score Text
+ TextY: Real; //Y Position of the Score Text
+ TextFont: Byte; //Font of the Score Text
+ TextSize: Byte; //Size of the Score Text
+
+ PUW: Real; //Width of the LineBonus Popup
+ PUH: Real; //Height of the LineBonus Popup
+ PUFont: Byte; //Font for the PopUps
+ PUFontSize: Byte; //FontSize for the PopUps
+ PUStartX: Real; //X Start Position of the LineBonus Popup
+ PUStartY: Real; //Y Start Position of the LineBonus Popup
+ PUTargetX: Real; //X Target Position of the LineBonus Popup
+ PUTargetY: Real; //Y Target Position of the LineBonus Popup
+ end;
+ aScorePosition = array[0..MaxPositions-1] of TScorePosition;
+
+ //-----------
+ // TScorePopUp - Record Containing Information about a LineBonus Popup
+ // List, Next Item is Saved in Next attribute
+ //-----------
+ PScorePopUp = ^TScorePopUp;
+ TScorePopUp = record
+ Player: Byte; //Index of the PopUps Player
+ TimeStamp: Cardinal; //Timestamp of Popups Spawn
+ Rating: Byte; //0 to 8, Type of Rating (Cool, bad, etc.)
+ ScoreGiven:Word; //Score that has already been given to the Player
+ ScoreDiff: Word; //Difference Between Cur Score at Spawn and Old Score
+ Next: PScorePopUp; //Next Item in List
+ end;
+ aScorePopUp = array of TScorePopUp;
+
+ //-----------
+ // TSingScores - Class containing Scores Positions and Drawing Scores, Rating Bar + Popups
+ //-----------
+ TSingScores = class
+ private
+ Positions: aScorePosition;
+ aPlayers: aScorePlayer;
+ oPositionCount: Byte;
+ oPlayerCount: Byte;
+
+ //Saves the First and Last Popup of the List
+ FirstPopUp: PScorePopUp;
+ LastPopUp: PScorePopUp;
+
+ //Procedure Draws a Popup by Pointer
+ Procedure DrawPopUp(const PopUp: PScorePopUp);
+
+ //Procedure Draws a Score by Playerindex
+ Procedure DrawScore(const Index: Integer);
+
+ //Procedure Draws the RatingBar by Playerindex
+ Procedure DrawRatingBar(const Index: Integer);
+
+ //Procedure Removes a PopUp w/o destroying the List
+ Procedure KillPopUp(const last, cur: PScorePopUp);
+ public
+ Settings: record //Record containing some Displaying Options
+ Phase1Time: Real; //time for Phase 1 to complete (in msecs)
+ //The Plop Up of the PopUp
+ Phase2Time: Real; //time for Phase 2 to complete (in msecs)
+ //The Moving (mainly Upwards) of the Popup
+ Phase3Time: Real; //time for Phase 3 to complete (in msecs)
+ //The Fade out and Score adding
+
+ PopUpTex: Array [0..8] of TTexture; //Textures for every Popup Rating
+
+ RatingBar_BG_Tex: TTexture; //Rating Bar Texs
+ RatingBar_FG_Tex: TTexture;
+ RatingBar_Bar_Tex: TTexture;
+
+ end;
+
+ Visible: Boolean; //Visibility of all Scores
+ Enabled: Boolean; //Scores are changed, PopUps are Moved etc.
+ RBVisible: Boolean; //Visibility of all Rating Bars
+
+ //Propertys for Reading Position and Playercount
+ Property PositionCount: Byte read oPositionCount;
+ Property PlayerCount: Byte read oPlayerCount;
+ Property Players: aScorePlayer read aPlayers;
+
+ //Constructor just sets some standard Settings
+ Constructor Create;
+
+ //Procedure Adds a Position to Array and Increases Position Count
+ Procedure AddPosition(const pPosition: PScorePosition);
+
+ //Procedure Adds a Player to Array and Increases Player Count
+ Procedure AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word = 0; const Enabled: Boolean = True; const Visible: Boolean = True);
+
+ //Change a Players Visibility, Enable
+ Procedure ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
+ Procedure ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
+
+ //Procedure Deletes all Player Information
+ Procedure ClearPlayers;
+
+ //Procedure Deletes Positions and Playerinformation
+ Procedure Clear;
+
+ //Procedure Loads some Settings and the Positions from Theme
+ Procedure LoadfromTheme;
+
+ //Procedure has to be called after Positions and Players have been added, before first call of Draw
+ //It gives every Player a Score Position
+ Procedure Init;
+
+ //Spawns a new Line Bonus PopUp for the Player
+ Procedure SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
+
+ //Removes all PopUps from Mem
+ Procedure KillAllPopUps;
+
+ //Procedure Draws Scores and Linebonus PopUps
+ Procedure Draw;
+ end;
+
+
+implementation
+
+uses SDL,
+ SysUtils,
+ ULog,
+ UGraphic,
+ TextGL;
+
+//-----------
+//Constructor just sets some standard Settings
+//-----------
+Constructor TSingScores.Create;
+begin
+ inherited;
+
+ //Clear PopupList Pointers
+ FirstPopUp := nil;
+ LastPopUp := nil;
+
+ //Clear Variables
+ Visible := True;
+ Enabled := True;
+ RBVisible := True;
+
+ //Clear Position Index
+ oPositionCount := 0;
+ oPlayerCount := 0;
+
+ Settings.Phase1Time := 350; // plop it up . -> [ ]
+ Settings.Phase2Time := 550; // shift it up ^[ ]^
+ Settings.Phase3Time := 200; // increase score [s++]
+
+ Settings.PopUpTex[0].TexNum := 0;
+ Settings.PopUpTex[1].TexNum := 0;
+ Settings.PopUpTex[2].TexNum := 0;
+ Settings.PopUpTex[3].TexNum := 0;
+ Settings.PopUpTex[4].TexNum := 0;
+ Settings.PopUpTex[5].TexNum := 0;
+ Settings.PopUpTex[6].TexNum := 0;
+ Settings.PopUpTex[7].TexNum := 0;
+ Settings.PopUpTex[8].TexNum := 0;
+
+ Settings.RatingBar_BG_Tex.TexNum := 0;
+ Settings.RatingBar_FG_Tex.TexNum := 0;
+ Settings.RatingBar_Bar_Tex.TexNum := 0;
+end;
+
+//-----------
+//Procedure Adds a Position to Array and Increases Position Count
+//-----------
+Procedure TSingScores.AddPosition(const pPosition: PScorePosition);
+begin
+ if (PositionCount < MaxPositions) then
+ begin
+ Positions[PositionCount] := pPosition^;
+
+ Inc(oPositionCount);
+ end;
+end;
+
+//-----------
+//Procedure Adds a Player to Array and Increases Player Count
+//-----------
+Procedure TSingScores.AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word; const Enabled: Boolean; const Visible: Boolean);
+begin
+ if (PlayerCount < MaxPlayers) then
+ begin
+ aPlayers[PlayerCount].Position := High(byte);
+ aPlayers[PlayerCount].Enabled := Enabled;
+ aPlayers[PlayerCount].Visible := Visible;
+ aPlayers[PlayerCount].Score := Score;
+ aPlayers[PlayerCount].ScoreDisplayed := Score;
+ aPlayers[PlayerCount].ScoreBG := ScoreBG;
+ aPlayers[PlayerCount].Color := Color;
+ aPlayers[PlayerCount].RBPos := 0.5;
+ aPlayers[PlayerCount].RBTarget := 0.5;
+ aPlayers[PlayerCount].RBVisible := True;
+
+ Inc(oPlayerCount);
+ end;
+end;
+
+//-----------
+//Change a Players Visibility
+//-----------
+Procedure TSingScores.ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
+begin
+ if (Index < MaxPlayers) then
+ aPlayers[Index].Visible := pVisible;
+end;
+
+//-----------
+//Change Player Enabled
+//-----------
+Procedure TSingScores.ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
+begin
+ if (Index < MaxPlayers) then
+ aPlayers[Index].Enabled := pEnabled;
+end;
+
+//-----------
+//Procedure Deletes all Player Information
+//-----------
+Procedure TSingScores.ClearPlayers;
+begin
+ KillAllPopUps;
+ oPlayerCount := 0;
+end;
+
+//-----------
+//Procedure Deletes Positions and Playerinformation
+//-----------
+Procedure TSingScores.Clear;
+begin
+ KillAllPopUps;
+ oPlayerCount := 0;
+ oPositionCount := 0;
+end;
+
+//-----------
+//Procedure Loads some Settings and the Positions from Theme
+//-----------
+Procedure TSingScores.LoadfromTheme;
+var I: Integer;
+ Procedure AddbyStatics(const PC: Byte; const ScoreStatic, SingBarStatic: TThemeStatic; ScoreText: TThemeText);
+ var nPosition: TScorePosition;
+ begin
+ nPosition.PlayerCount := PC; //Only for one Player Playing
+
+ nPosition.BGX := ScoreStatic.X;
+ nPosition.BGY := ScoreStatic.Y;
+ nPosition.BGW := ScoreStatic.W;
+ nPosition.BGH := ScoreStatic.H;
+
+ nPosition.TextX := ScoreText.X;
+ nPosition.TextY := ScoreText.Y;
+ nPosition.TextFont := ScoreText.Font;
+ nPosition.TextSize := ScoreText.Size;
+
+ nPosition.RBX := SingBarStatic.X;
+ nPosition.RBY := SingBarStatic.Y;
+ nPosition.RBW := SingBarStatic.W;
+ nPosition.RBH := SingBarStatic.H;
+
+ nPosition.PUW := nPosition.BGW;
+ nPosition.PUH := nPosition.BGH;
+
+ nPosition.PUFont := 2;
+ nPosition.PUFontSize := 6;
+
+ nPosition.PUStartX := nPosition.BGX;
+ nPosition.PUStartY := nPosition.TextY + 65;
+
+ nPosition.PUTargetX := nPosition.BGX;
+ nPosition.PUTargetY := nPosition.TextY;
+
+ AddPosition(@nPosition);
+ end;
+begin
+ Clear;
+
+ //Set Textures
+ //Popup Tex
+ For I := 0 to 8 do
+ Settings.PopUpTex[I] := Tex_SingLineBonusBack[I];
+
+ //Rating Bar Tex
+ Settings.RatingBar_BG_Tex := Tex_SingBar_Back;
+ Settings.RatingBar_FG_Tex := Tex_SingBar_Front;
+ Settings.RatingBar_Bar_Tex := Tex_SingBar_Bar;
+
+ //Load Positions from Theme
+
+ // Player1:
+ AddByStatics(1, Theme.Sing.StaticP1ScoreBG, Theme.Sing.StaticP1SingBar, Theme.Sing.TextP1Score);
+ AddByStatics(2, Theme.Sing.StaticP1TwoPScoreBG, Theme.Sing.StaticP1TwoPSingBar, Theme.Sing.TextP1TwoPScore);
+ AddByStatics(4, Theme.Sing.StaticP1ThreePScoreBG, Theme.Sing.StaticP1ThreePSingBar, Theme.Sing.TextP1ThreePScore);
+
+ // Player2:
+ AddByStatics(2, Theme.Sing.StaticP2RScoreBG, Theme.Sing.StaticP2RSingBar, Theme.Sing.TextP2RScore);
+ AddByStatics(4, Theme.Sing.StaticP2MScoreBG, Theme.Sing.StaticP2MSingBar, Theme.Sing.TextP2MScore);
+
+ // Player3:
+ AddByStatics(4, Theme.Sing.StaticP3RScoreBG, Theme.Sing.StaticP3RScoreBG, Theme.Sing.TextP3RScore);
+end;
+
+//-----------
+//Spawns a new Line Bonus PopUp for the Player
+//-----------
+Procedure TSingScores.SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
+var Cur: PScorePopUp;
+begin
+ if (PlayerIndex < PlayerCount) then
+ begin
+ //Get Memory and Add Data
+ GetMem(Cur, SizeOf(TScorePopUp));
+
+ Cur.Player := PlayerIndex;
+ Cur.TimeStamp := SDL_GetTicks;
+ Cur.Rating := Rating;
+ Cur.ScoreGiven:= 0;
+ If (Players[PlayerIndex].Score < Score) then
+ begin
+ Cur.ScoreDiff := Score - Players[PlayerIndex].Score;
+ aPlayers[PlayerIndex].Score := Score;
+ end
+ else
+ Cur.ScoreDiff := 0;
+ Cur.Next := nil;
+
+ //Log.LogError('TSingScores.SpawnPopUp| Player: ' + InttoStr(PlayerIndex) + ', Score: ' + InttoStr(Score) + ', ScoreDiff: ' + InttoStr(Cur.ScoreDiff));
+
+ //Add it to the Chain
+ if (FirstPopUp = nil) then
+ //the first PopUp in the List
+ FirstPopUp := Cur
+ else
+ //second or earlier popup
+ LastPopUp.Next := Cur;
+
+ //Set new Popup to Last PopUp in the List
+ LastPopUp := Cur;
+ end
+ else
+ Log.LogError('TSingScores: Try to add PopUp for not existing player');
+end;
+
+//-----------
+// Removes a PopUp w/o destroying the List
+//-----------
+Procedure TSingScores.KillPopUp(const last, cur: PScorePopUp);
+var
+ lTempA ,
+ lTempB : real;
+begin
+ //Give Player the Last Points that missing till now
+ aPlayers[Cur.Player].ScoreDisplayed := aPlayers[Cur.Player].ScoreDisplayed + Cur.ScoreDiff - Cur.ScoreGiven;
+
+ //Change Bars Position
+ lTempA := ( aPlayers[Cur.Player].RBTarget + (Cur.ScoreDiff - Cur.ScoreGiven) );
+ lTempB := ( Cur.ScoreDiff * (Cur.Rating / 20 - 0.26) );
+
+ if ( lTempA > 0 ) AND
+ ( lTempB > 0 ) THEN
+ begin
+ aPlayers[Cur.Player].RBTarget := lTempA / lTempB;
+ end;
+
+ If (aPlayers[Cur.Player].RBTarget > 1) then
+ aPlayers[Cur.Player].RBTarget := 1
+ else
+ If (aPlayers[Cur.Player].RBTarget < 0) then
+ aPlayers[Cur.Player].RBTarget := 0;
+
+ //If this is the First PopUp => Make Next PopUp the First
+ If (Cur = FirstPopUp) then
+ FirstPopUp := Cur.Next
+ //Else => Remove Curent Popup from Chain
+ else
+ Last.Next := Cur.Next;
+
+ //If this is the Last PopUp, Make PopUp before the Last
+ If (Cur = LastPopUp) then
+ LastPopUp := Last;
+
+ //Free the Memory
+ FreeMem(Cur, SizeOf(TScorePopUp));
+end;
+
+//-----------
+//Removes all PopUps from Mem
+//-----------
+Procedure TSingScores.KillAllPopUps;
+var
+ Cur: PScorePopUp;
+ Last: PScorePopUp;
+begin
+ Cur := FirstPopUp;
+
+ //Remove all PopUps:
+ While (Cur <> nil) do
+ begin
+ Last := Cur;
+ Cur := Cur.Next;
+ FreeMem(Last, SizeOf(TScorePopUp));
+ end;
+
+ FirstPopUp := nil;
+ LastPopUp := nil;
+end;
+
+//-----------
+//Init - has to be called after Positions and Players have been added, before first call of Draw
+//It gives every Player a Score Position
+//-----------
+Procedure TSingScores.Init;
+var
+ PlC: Array [0..1] of Byte; //Playercount First Screen and Second Screen
+ I, J: Integer;
+ MaxPlayersperScreen: Byte;
+ CurPlayer: Byte;
+
+ Function GetPositionCountbyPlayerCount(bPlayerCount: Byte): Byte;
+ var I: Integer;
+ begin
+ Result := 0;
+ bPlayerCount := 1 shl (bPlayerCount - 1);
+
+ For I := 0 to PositionCount-1 do
+ begin
+ If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
+ Inc(Result);
+ end;
+ end;
+
+ Function GetPositionbyPlayernum(bPlayerCount, bPlayer: Byte): Byte;
+ var I: Integer;
+ begin
+ bPlayerCount := 1 shl (bPlayerCount - 1);
+ Result := High(Byte);
+
+ For I := 0 to PositionCount-1 do
+ begin
+ If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
+ begin
+ If (bPlayer = 0) then
+ begin
+ Result := I;
+ Break;
+ end
+ else
+ Dec(bPlayer);
+ end;
+ end;
+ end;
+
+begin
+ MaxPlayersPerScreen := 0;
+
+ For I := 1 to 6 do
+ begin
+ //If there are enough Positions -> Write to MaxPlayers
+ If (GetPositionCountbyPlayerCount(I) = I) then
+ MaxPlayersPerScreen := I
+ else
+ Break;
+ end;
+
+
+ //Split Players to both Screen or Display on One Screen
+ if (Screens = 2) and (MaxPlayersPerScreen < PlayerCount) then
+ begin
+ PlC[0] := PlayerCount div 2 + PlayerCount mod 2;
+ PlC[1] := PlayerCount div 2;
+ end
+ else
+ begin
+ PlC[0] := PlayerCount;
+ PlC[1] := 0;
+ end;
+
+
+ //Check if there are enough Positions for all Players
+ For I := 0 to Screens - 1 do
+ begin
+ if (PlC[I] > MaxPlayersperScreen) then
+ begin
+ PlC[I] := MaxPlayersperScreen;
+ Log.LogError('More Players than available Positions, TSingScores');
+ end;
+ end;
+
+ CurPlayer := 0;
+ //Give every Player a Position
+ For I := 0 to Screens - 1 do
+ For J := 0 to PlC[I]-1 do
+ begin
+ aPlayers[CurPlayer].Position := GetPositionbyPlayernum(PlC[I], J) OR (I shl 7);
+ //Log.LogError('Player ' + InttoStr(CurPlayer) + ' gets Position: ' + InttoStr(aPlayers[CurPlayer].Position));
+ Inc(CurPlayer);
+ end;
+end;
+
+//-----------
+//Procedure Draws Scores and Linebonus PopUps
+//-----------
+Procedure TSingScores.Draw;
+var
+ I: Integer;
+ CurTime: Cardinal;
+ CurPopUp, LastPopUp: PScorePopUp;
+begin
+ CurTime := SDL_GetTicks;
+
+ If Visible then
+ begin
+ //Draw Popups
+ LastPopUp := nil;
+ CurPopUp := FirstPopUp;
+
+ While (CurPopUp <> nil) do
+ begin
+ if (CurTime - CurPopUp.TimeStamp > Settings.Phase1Time + Settings.Phase2Time + Settings.Phase3Time) then
+ begin
+ KillPopUp(LastPopUp, CurPopUp);
+ if (LastPopUp = nil) then
+ CurPopUp := FirstPopUp
+ else
+ CurPopUp := LastPopUp.Next;
+ end
+ else
+ begin
+ DrawPopUp(CurPopUp);
+ LastPopUp := CurPopUp;
+ CurPopUp := LastPopUp.Next;
+ end;
+ end;
+
+
+ IF (RBVisible) then
+ //Draw Players w/ Rating Bar
+ For I := 0 to PlayerCount-1 do
+ begin
+ DrawScore(I);
+ DrawRatingBar(I);
+ end
+ else
+ //Draw Players w/o Rating Bar
+ For I := 0 to PlayerCount-1 do
+ begin
+ DrawScore(I);
+ end;
+
+ end; //eo Visible
+end;
+
+//-----------
+//Procedure Draws a Popup by Pointer
+//-----------
+Procedure TSingScores.DrawPopUp(const PopUp: PScorePopUp);
+var
+ Progress: Real;
+ CurTime: Cardinal;
+ X, Y, W, H, Alpha: Real;
+ FontSize: Byte;
+ TimeDiff: Cardinal;
+ PIndex: Byte;
+ TextLen: Real;
+ ScoretoAdd: Word;
+ PosDiff: Real;
+begin
+ if (PopUp <> nil) then
+ begin
+ //Only Draw if Player has a Position
+ PIndex := Players[PopUp.Player].Position;
+ If PIndex <> high(byte) then
+ begin
+ //Only Draw if Player is on Cur Screen
+ If ((Players[PopUp.Player].Position AND 128) = 0) = (ScreenAct = 1) then
+ begin
+ CurTime := SDL_GetTicks;
+ If Not (Enabled AND Players[PopUp.Player].Enabled) then
+ //Increase Timestamp with TIem where there is no Movement ...
+ begin
+ //Inc(PopUp.TimeStamp, LastRender);
+ end;
+ TimeDiff := CurTime - PopUp.TimeStamp;
+
+ //Get Position of PopUp
+ PIndex := PIndex AND 127;
+
+
+ //Check for Phase ...
+ If (TimeDiff <= Settings.Phase1Time) then
+ begin
+ //Phase 1 - The Ploping up
+ Progress := TimeDiff / Settings.Phase1Time;
+
+
+ W := Positions[PIndex].PUW * Sin(Progress/2*Pi);
+ H := Positions[PIndex].PUH * Sin(Progress/2*Pi);
+
+ X := Positions[PIndex].PUStartX + (Positions[PIndex].PUW - W)/2;
+ Y := Positions[PIndex].PUStartY + (Positions[PIndex].PUH - H)/2;
+
+ FontSize := Round(Progress * Positions[PIndex].PUFontSize);
+ Alpha := 1;
+ end
+
+ Else If (TimeDiff <= Settings.Phase2Time + Settings.Phase1Time) then
+ begin
+ //Phase 2 - The Moving
+ Progress := (TimeDiff - Settings.Phase1Time) / Settings.Phase2Time;
+
+ W := Positions[PIndex].PUW;
+ H := Positions[PIndex].PUH;
+
+ PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
+ If PosDiff > 0 then
+ PosDiff := PosDiff + W;
+ X := Positions[PIndex].PUStartX + PosDiff * sqr(Progress);
+
+ PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
+ If PosDiff < 0 then
+ PosDiff := PosDiff + Positions[PIndex].BGH;
+ Y := Positions[PIndex].PUStartY + PosDiff * sqr(Progress);
+
+ FontSize := Positions[PIndex].PUFontSize;
+ Alpha := 1 - 0.3 * Progress;
+ end
+
+ else
+ begin
+ //Phase 3 - The Fading out + Score adding
+ Progress := (TimeDiff - Settings.Phase1Time - Settings.Phase2Time) / Settings.Phase3Time;
+
+ If (PopUp.Rating > 0) then
+ begin
+ //Add Scores if Player Enabled
+ If (Enabled AND Players[PopUp.Player].Enabled) then
+ begin
+ ScoreToAdd := Round(PopUp.ScoreDiff * Progress) - PopUp.ScoreGiven;
+ Inc(PopUp.ScoreGiven, ScoreToAdd);
+ aPlayers[PopUp.Player].ScoreDisplayed := Players[PopUp.Player].ScoreDisplayed + ScoreToAdd;
+
+ //Change Bars Position
+ aPlayers[PopUp.Player].RBTarget := aPlayers[PopUp.Player].RBTarget + ScoreToAdd/PopUp.ScoreDiff * (PopUp.Rating / 20 - 0.26);
+ If (aPlayers[PopUp.Player].RBTarget > 1) then
+ aPlayers[PopUp.Player].RBTarget := 1
+ else If (aPlayers[PopUp.Player].RBTarget < 0) then
+ aPlayers[PopUp.Player].RBTarget := 0;
+ end;
+
+ //Set Positions etc.
+ Alpha := 0.7 - 0.7 * Progress;
+
+ W := Positions[PIndex].PUW;
+ H := Positions[PIndex].PUH;
+
+ PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
+ If (PosDiff > 0) then
+ PosDiff := W
+ else
+ PosDiff := 0;
+ X := Positions[PIndex].PUTargetX + PosDiff * Progress;
+
+ PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
+ If (PosDiff < 0) then
+ PosDiff := -Positions[PIndex].BGH
+ else
+ PosDiff := 0;
+ Y := Positions[PIndex].PUTargetY - PosDiff * (1-Progress);
+
+ FontSize := Positions[PIndex].PUFontSize;
+ end
+ else
+ begin
+ //Here the Effect that Should be shown if a PopUp without Score is Drawn
+ //And or Spawn with the GraphicObjects etc.
+ //Some Work for Blindy to do :P
+
+ //ATM: Just Let it Slide in the Scores just like the Normal PopUp
+ Alpha := 0;
+ end;
+ end;
+
+ //Draw PopUp
+
+ if (Alpha > 0) AND (Players[PopUp.Player].Visible) then
+ begin
+ //Draw BG:
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(1,1,1, Alpha);
+ glBindTexture(GL_TEXTURE_2D, Settings.PopUpTex[PopUp.Rating].TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X, Y + H);
+ glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X + W, Y + H);
+ glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, 0); glVertex2f(X + W, Y);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ //Set FontStyle and Size
+ SetFontStyle(Positions[PIndex].PUFont);
+ SetFontItalic(False);
+ SetFontSize(FontSize);
+
+ //Draw Text
+ TextLen := glTextWidth(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
+
+ //Color and Pos
+ SetFontPos (X + (W - TextLen) / 2, Y + 12);
+ glColor4f(1, 1, 1, Alpha);
+
+ //Draw
+ glPrint(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
+ end; //eo Alpha check
+ end; //eo Right Screen
+ end; //eo Player has Position
+ end
+ else
+ Log.LogError('TSingScores: Try to Draw a not existing PopUp');
+end;
+
+//-----------
+//Procedure Draws a Score by Playerindex
+//-----------
+Procedure TSingScores.DrawScore(const Index: Integer);
+var
+ Position: PScorePosition;
+ ScoreStr: String;
+begin
+ //Only Draw if Player has a Position
+ If Players[Index].Position <> high(byte) then
+ begin
+ //Only Draw if Player is on Cur Screen
+ If (((Players[Index].Position AND 128) = 0) = (ScreenAct = 1)) AND Players[Index].Visible then
+ begin
+ Position := @Positions[Players[Index].Position and 127];
+
+ //Draw ScoreBG
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(1,1,1, 1);
+ glBindTexture(GL_TEXTURE_2D, Players[Index].ScoreBG.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Position.BGX, Position.BGY);
+ glTexCoord2f(0, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX, Position.BGY + Position.BGH);
+ glTexCoord2f(Players[Index].ScoreBG.TexW, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX + Position.BGW, Position.BGY + Position.BGH);
+ glTexCoord2f(Players[Index].ScoreBG.TexW, 0); glVertex2f(Position.BGX + Position.BGW, Position.BGY);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ //Draw Score Text
+ SetFontStyle(Position.TextFont);
+ SetFontItalic(False);
+ SetFontSize(Position.TextSize);
+ SetFontPos(Position.TextX, Position.TextY);
+
+ ScoreStr := InttoStr(Players[Index].ScoreDisplayed div 10) + '0';
+ While (Length(ScoreStr) < 5) do
+ ScoreStr := '0' + ScoreStr;
+
+ glPrint(PChar(ScoreStr));
+
+ end; //eo Right Screen
+ end; //eo Player has Position
+end;
+
+
+Procedure TSingScores.DrawRatingBar(const Index: Integer);
+var
+ Position: PScorePosition;
+ R,G,B, Size: Real;
+ Diff: Real;
+begin
+ //Only Draw if Player has a Position
+ if Players[Index].Position <> high(byte) then
+ begin
+ //Only Draw if Player is on Cur Screen
+ if (((Players[Index].Position and 128) = 0) = (ScreenAct = 1) and
+ Players[index].RBVisible and
+ Players[index].Visible) then
+ begin
+ Position := @Positions[Players[Index].Position and 127];
+
+ if (Enabled AND Players[Index].Enabled) then
+ begin
+ //Move Position if Enabled
+ Diff := Players[Index].RBTarget - Players[Index].RBPos;
+ If(Abs(Diff) < 0.02) then
+ aPlayers[Index].RBPos := aPlayers[Index].RBTarget
+ else
+ aPlayers[Index].RBPos := aPlayers[Index].RBPos + Diff*0.1;
+ end;
+
+ //Get Colors for RatingBar
+ if (Players[index].RBPos <= 0.22) then
+ begin
+ R := 1;
+ G := 0;
+ B := 0;
+ end
+ else if (Players[index].RBPos <= 0.42) then
+ begin
+ R := 1;
+ G := Players[index].RBPos*5;
+ B := 0;
+ end
+ else if (Players[index].RBPos <= 0.57) then
+ begin
+ R := 1;
+ G := 1;
+ B := 0;
+ end
+ else if (Players[index].RBPos <= 0.77) then
+ begin
+ R := 1-(Players[index].RBPos-0.57)*5;
+ G := 1;
+ B := 0;
+ end
+ else
+ begin
+ R := 0;
+ G := 1;
+ B := 0;
+ end;
+
+ //Enable all glFuncs Needed
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ //Draw RatingBar BG
+ glColor4f(1, 1, 1, 0.8);
+ glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_BG_Tex.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0);
+ glVertex2f(Position.RBX, Position.RBY);
+
+ glTexCoord2f(0, Settings.RatingBar_BG_Tex.TexH);
+ glVertex2f(Position.RBX, Position.RBY+Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, Settings.RatingBar_BG_Tex.TexH);
+ glVertex2f(Position.RBX+Position.RBW, Position.RBY+Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, 0);
+ glVertex2f(Position.RBX+Position.RBW, Position.RBY);
+ glEnd;
+
+ //Draw Rating bar itself
+ Size := Position.RBX + Position.RBW * Players[Index].RBPos;
+ glColor4f(R, G, B, 1);
+ glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_Bar_Tex.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0);
+ glVertex2f(Position.RBX, Position.RBY);
+
+ glTexCoord2f(0, Settings.RatingBar_Bar_Tex.TexH);
+ glVertex2f(Position.RBX, Position.RBY + Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, Settings.RatingBar_Bar_Tex.TexH);
+ glVertex2f(Size, Position.RBY + Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, 0);
+ glVertex2f(Size, Position.RBY);
+ glEnd;
+
+ //Draw Ratingbar FG (Teh thing with the 3 lines to get better readability)
+ glColor4f(1, 1, 1, 0.6);
+ glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_FG_Tex.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0);
+ glVertex2f(Position.RBX, Position.RBY);
+
+ glTexCoord2f(0, Settings.RatingBar_FG_Tex.TexH);
+ glVertex2f(Position.RBX, Position.RBY + Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, Settings.RatingBar_FG_Tex.TexH);
+ glVertex2f(Position.RBX + Position.RBW, Position.RBY + Position.RBH);
+
+ glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, 0);
+ glVertex2f(Position.RBX + Position.RBW, Position.RBY);
+ glEnd;
+
+ //Disable all Enabled glFuncs
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ end; //eo Right Screen
+ end; //eo Player has Position
+end;
+
+end.
diff --git a/src/Classes/USkins.pas b/src/Classes/USkins.pas
new file mode 100644
index 00000000..88549c9f
--- /dev/null
+++ b/src/Classes/USkins.pas
@@ -0,0 +1,185 @@
+unit USkins;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+type
+ TSkinTexture = record
+ Name: string;
+ FileName: string;
+ end;
+
+ TSkinEntry = record
+ Theme: string;
+ Name: string;
+ Path: string;
+ FileName: string;
+ Creator: string; // not used yet
+ end;
+
+ TSkin = class
+ Skin: array of TSkinEntry;
+ SkinTexture: array of TSkinTexture;
+ SkinPath: string;
+ Color: integer;
+ constructor Create;
+ procedure LoadList;
+ procedure ParseDir(Dir: string);
+ procedure LoadHeader(FileName: string);
+ procedure LoadSkin(Name: string);
+ function GetTextureFileName(TextureName: string): string;
+ function GetSkinNumber(Name: string): integer;
+ procedure onThemeChange;
+ end;
+
+var
+ Skin: TSkin;
+
+implementation
+
+uses IniFiles,
+ Classes,
+ SysUtils,
+ UMain,
+ ULog,
+ UIni;
+
+constructor TSkin.Create;
+begin
+ inherited;
+ LoadList;
+// LoadSkin('Lisek');
+// SkinColor := Color;
+end;
+
+procedure TSkin.LoadList;
+var
+ SR: TSearchRec;
+begin
+ if FindFirst(SkinsPath+'*', faDirectory, SR) = 0 then begin
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ ParseDir(SkinsPath + SR.Name + PathDelim);
+ until FindNext(SR) <> 0;
+ end; // if
+ FindClose(SR);
+end;
+
+procedure TSkin.ParseDir(Dir: string);
+var
+ SR: TSearchRec;
+begin
+ if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then begin
+ repeat
+
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ LoadHeader(Dir + SR.Name);
+
+ until FindNext(SR) <> 0;
+ end;
+end;
+
+procedure TSkin.LoadHeader(FileName: string);
+var
+ SkinIni: TMemIniFile;
+ S: integer;
+begin
+ SkinIni := TMemIniFile.Create(FileName);
+
+ S := Length(Skin);
+ SetLength(Skin, S+1);
+
+ Skin[S].Path := IncludeTrailingPathDelimiter(ExtractFileDir(FileName));
+ Skin[S].FileName := ExtractFileName(FileName);
+ Skin[S].Theme := SkinIni.ReadString('Skin', 'Theme', '');
+ Skin[S].Name := SkinIni.ReadString('Skin', 'Name', '');
+ Skin[S].Creator := SkinIni.ReadString('Skin', 'Creator', '');
+
+ SkinIni.Free;
+end;
+
+procedure TSkin.LoadSkin(Name: string);
+var
+ SkinIni: TMemIniFile;
+ SL: TStringList;
+ T: integer;
+ S: integer;
+begin
+ S := GetSkinNumber(Name);
+ SkinPath := Skin[S].Path;
+
+ SkinIni := TMemIniFile.Create(SkinPath + Skin[S].FileName);
+
+ SL := TStringList.Create;
+ SkinIni.ReadSection('Textures', SL);
+
+ SetLength(SkinTexture, SL.Count);
+ for T := 0 to SL.Count-1 do
+ begin
+ SkinTexture[T].Name := SL.Strings[T];
+ SkinTexture[T].FileName := SkinIni.ReadString('Textures', SL.Strings[T], '');
+ end;
+
+ SL.Free;
+ SkinIni.Free;
+end;
+
+function TSkin.GetTextureFileName(TextureName: string): string;
+var
+ T: integer;
+begin
+ Result := '';
+
+ for T := 0 to High(SkinTexture) do
+ begin
+ if ( SkinTexture[T].Name = TextureName ) AND
+ ( SkinTexture[T].FileName <> '' ) then
+ begin
+ Result := SkinPath + SkinTexture[T].FileName;
+ end;
+ end;
+
+ if ( TextureName <> '' ) AND
+ ( Result <> '' ) THEN
+ begin
+ //Log.LogError('', '-----------------------------------------');
+ //Log.LogError(TextureName+' - '+ Result, 'TSkin.GetTextureFileName');
+ end;
+
+{ Result := SkinPath + 'Bar.jpg';
+ if TextureName = 'Ball' then Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 4) = 'Gray' then Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 6) = 'NoteBG' then Result := SkinPath + 'Ball.bmp';}
+end;
+
+function TSkin.GetSkinNumber(Name: string): integer;
+var
+ S: integer;
+begin
+ Result := 0; // set default to the first available skin
+ for S := 0 to High(Skin) do
+ if Skin[S].Name = Name then Result := S;
+end;
+
+procedure TSkin.onThemeChange;
+var
+ S: integer;
+ Name: String;
+begin
+ Ini.SkinNo:=0;
+ SetLength(ISkin, 0);
+ Name := Uppercase(ITheme[Ini.Theme]);
+ for S := 0 to High(Skin) do
+ if Name = Uppercase(Skin[S].Theme) then begin
+ SetLength(ISkin, Length(ISkin)+1);
+ ISkin[High(ISkin)] := Skin[S].Name;
+ end;
+
+end;
+
+end.
diff --git a/src/Classes/USong.pas b/src/Classes/USong.pas
new file mode 100644
index 00000000..3517bce6
--- /dev/null
+++ b/src/Classes/USong.pas
@@ -0,0 +1,1027 @@
+unit USong;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ {$IFDEF MSWINDOWS}
+ Windows,
+ {$ELSE}
+ {$IFNDEF DARWIN}
+ syscall,
+ {$ENDIF}
+ baseunix,
+ UnixType,
+ {$ENDIF}
+ SysUtils,
+ Classes,
+ UPlatform,
+ ULog,
+ UTexture,
+ UCommon,
+ {$IFDEF DARWIN}
+ cthreads,
+ {$ENDIF}
+ {$IFDEF USE_PSEUDO_THREAD}
+ PseudoThread,
+ {$ENDIF}
+ UCatCovers,
+ UXMLSong;
+
+type
+
+ TSingMode = ( smNormal, smPartyMode, smPlaylistRandom );
+
+ TBPM = record
+ BPM: real;
+ StartBeat: real;
+ end;
+
+ TScore = record
+ Name: WideString;
+ Score: integer;
+ Length: string;
+ end;
+
+ TSong = class
+ FileLineNo : integer; //Line which is readed at Last, for error reporting
+
+ procedure ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
+ procedure NewSentence(LineNumberP: integer; Param1, Param2: integer);
+
+ function ReadTXTHeader( const aFileName : WideString ): boolean;
+ function ReadXMLHeader( const aFileName : WideString ): boolean;
+ public
+ Path: WideString;
+ Folder: WideString; // for sorting by folder
+ fFileName,
+ FileName: WideString;
+
+ // sorting methods
+ Category: array of WideString; // TODO: do we need this?
+ Genre: WideString;
+ Edition: WideString;
+ Language: WideString;
+
+ Title: WideString;
+ Artist: WideString;
+
+ Text: WideString;
+ Creator: WideString;
+
+ Cover: WideString;
+ CoverTex: TTexture;
+ Mp3: WideString;
+ Background: WideString;
+ Video: WideString;
+ VideoGAP: real;
+ VideoLoaded: boolean; // true if the video has been loaded
+ NotesGAP: integer;
+ Start: real; // in seconds
+ Finish: integer; // in miliseconds
+ Relative: boolean;
+ Resolution: integer;
+ BPM: array of TBPM;
+ GAP: real; // in miliseconds
+
+ Score: array[0..2] of array of TScore;
+
+ // these are used when sorting is enabled
+ Visible: boolean; // false if hidden, true if visible
+ Main: boolean; // false for songs, true for category buttons
+ OrderNum: integer; // has a number of category for category buttons and songs
+ OrderTyp: integer; // type of sorting for this button (0=name)
+ CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs
+
+ SongFile: TextFile; // all procedures in this unit operate on this file
+
+ Base : array[0..1] of integer;
+ Rel : array[0..1] of integer;
+ Mult : integer;
+ MultBPM : integer;
+
+ constructor Create (); overload;
+ constructor Create ( const aFileName : WideString ); overload;
+ function LoadSong: boolean;
+ function LoadXMLSong: boolean;
+ function Analyse(): boolean;
+ function AnalyseXML(): boolean;
+ procedure Clear();
+ end;
+
+implementation
+
+uses
+ TextGL,
+ UIni,
+ UMusic, //needed for Lines
+ UMain; //needed for Player
+
+constructor TSong.Create();
+begin
+ inherited;
+end;
+
+constructor TSong.Create( const aFileName : WideString );
+begin
+ inherited Create();
+
+ Mult := 1;
+ MultBPM := 4;
+ fFileName := aFileName;
+
+ if fileexists( aFileName ) then
+ begin
+ self.Path := ExtractFilePath( aFileName );
+ self.Folder := ExtractFilePath( aFileName );
+ self.FileName := ExtractFileName( aFileName );
+ (*
+ if ReadTXTHeader( aFileName ) then
+ begin
+ LoadSong();
+ end
+ else
+ begin
+ Log.LogError('Error Loading SongHeader, abort Song Loading');
+ Exit;
+ end;
+ *)
+ end;
+end;
+
+//Load TXT Song
+function TSong.LoadSong(): boolean;
+
+var
+ TempC: char;
+ Text: string;
+ CP: integer; // Current Player (0 or 1)
+ Count: integer;
+ Both: boolean;
+ Param1: integer;
+ Param2: integer;
+ Param3: integer;
+ ParamS: string;
+ I: integer;
+begin
+ Result := false;
+
+ if not FileExists(Path + PathDelim + FileName) then
+ begin
+ Log.LogError('File not found: "' + Path + PathDelim + FileName + '"', 'TSong.LoadSong()');
+ exit;
+ end;
+
+ MultBPM := 4; // multiply beat-count of note by 4
+ Mult := 1; // accuracy of measurement of note
+ Base[0] := 100; // high number
+ Lines[0].ScoreValue := 0;
+ self.Relative := false;
+ Rel[0] := 0;
+ CP := 0;
+ Both := false;
+
+ if Length(Player) = 2 then
+ Both := true;
+
+ try
+ // Open song file for reading.....
+ FileMode := fmOpenRead;
+ AssignFile(SongFile, fFileName);
+ Reset(SongFile);
+
+ //Clear old Song Header
+ if (self.Path = '') then
+ self.Path := ExtractFilePath(FileName);
+
+ if (self.FileName = '') then
+ self.Filename := ExtractFileName(FileName);
+
+ Result := False;
+
+ Reset(SongFile);
+ FileLineNo := 0;
+ //Search for Note Begining
+ repeat
+ ReadLn(SongFile, Text);
+ Inc(FileLineNo);
+
+ if (EoF(SongFile)) then
+ begin //Song File Corrupted - No Notes
+ CloseFile(SongFile);
+ Log.LogError('Could not load txt File, no Notes found: ' + FileName);
+ Result := False;
+ Exit;
+ end;
+ Read(SongFile, TempC);
+ until ((TempC = ':') or (TempC = 'F') or (TempC = '*'));
+
+ SetLength(Lines, 2);
+ for Count := 0 to High(Lines) do
+ begin
+ SetLength(Lines[Count].Line, 1);
+ Lines[Count].High := 0;
+ Lines[Count].Number := 1;
+ Lines[Count].Current := 0;
+ Lines[Count].Resolution := self.Resolution;
+ Lines[Count].NotesGAP := self.NotesGAP;
+ Lines[Count].Line[0].HighNote := -1;
+ Lines[Count].Line[0].LastLine := False;
+ end;
+
+ // TempC := ':';
+ // TempC := Text[1]; // read from backup variable, don't use default ':' value
+
+ while (TempC <> 'E') AND (not EOF(SongFile)) do
+ begin
+
+ if (TempC = ':') or (TempC = '*') or (TempC = 'F') then
+ begin
+ // read notes
+ Read(SongFile, Param1);
+ Read(SongFile, Param2);
+ Read(SongFile, Param3);
+ Read(SongFile, ParamS);
+
+
+ //Check for ZeroNote
+ if Param2 = 0 then Log.LogError('Found ZeroNote at "'+TempC+' '+IntToStr(Param1)+' '+IntToStr(Param2)+' '+IntToStr(Param3)+ParamS+'" -> Note ignored!') else
+ begin
+ // add notes
+ if not Both then
+ // P1
+ ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
+ else begin
+ // P1 + P2
+ ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
+ ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
+ end;
+ end; //Zeronote check
+ end; // if
+
+ if TempC = '-' then
+ begin
+ // reads sentence
+ Read(SongFile, Param1);
+ if self.Relative then Read(SongFile, Param2); // read one more data for relative system
+
+ // new sentence
+ if not Both then
+ // P1
+ NewSentence(0, (Param1 + Rel[0]) * Mult, Param2)
+ else begin
+ // P1 + P2
+ NewSentence(0, (Param1 + Rel[0]) * Mult, Param2);
+ NewSentence(1, (Param1 + Rel[1]) * Mult, Param2);
+ end;
+ end; // if
+
+ if TempC = 'B' then
+ begin
+ SetLength(self.BPM, Length(self.BPM) + 1);
+ Read(SongFile, self.BPM[High(self.BPM)].StartBeat);
+ self.BPM[High(self.BPM)].StartBeat := self.BPM[High(self.BPM)].StartBeat + Rel[0];
+
+ Read(SongFile, Text);
+ self.BPM[High(self.BPM)].BPM := StrToFloat(Text);
+ self.BPM[High(self.BPM)].BPM := self.BPM[High(self.BPM)].BPM * Mult * MultBPM;
+ end;
+
+
+ if not Both then
+ begin
+ Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
+ Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(PChar(Lines[CP].Line[Lines[CP].High].Lyric));
+ //Total Notes Patch
+ Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
+ for I := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do
+ begin
+ if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then
+ Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
+
+ if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then
+ Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
+ end;
+ //Total Notes Patch End
+ end else begin
+ for Count := 0 to High(Lines) do
+ begin
+ Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
+ Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(PChar(Lines[Count].Line[Lines[Count].High].Lyric));
+ //Total Notes Patch
+ Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
+ for I := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do
+ begin
+ if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then
+ Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
+ if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then
+ Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
+ end;
+ //Total Notes Patch End
+ end;
+ end;
+ Read(SongFile, TempC);
+ Inc(FileLineNo);
+ end; // while}
+
+ for Count := 0 to High(Lines) do
+ begin
+ Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
+ end;
+
+ CloseFile(SongFile);
+ except
+ try
+ CloseFile(SongFile);
+ except
+
+ end;
+
+ Log.LogError('Error Loading File: "' + fFileName + '" in Line ' + inttostr(FileLineNo));
+ exit;
+ end;
+
+ Result := true;
+end;
+
+//Load XML Song
+function TSong.LoadXMLSong(): boolean;
+var
+ //TempC: char;
+ Text: string;
+ CP: integer; // Current Player (0 or 1)
+ Count: integer;
+ Both: boolean;
+ Param1: integer;
+ Param2: integer;
+ Param3: integer;
+ ParamS: string;
+ I,J,X: integer;
+
+ NoteType: Char;
+ SentenceEnd, Rest, Time: Integer;
+ Parser: TParser;
+begin
+ Result := false;
+
+ if not FileExists(Path + PathDelim + FileName) then
+ begin
+ Log.LogError('File not found: "' + Path + PathDelim + FileName + '"', 'TSong.LoadSong()');
+ exit;
+ end;
+
+ MultBPM := 4; // multiply beat-count of note by 4
+ Mult := 1; // accuracy of measurement of note
+ Base[0] := 100; // high number
+ Lines[0].ScoreValue := 0;
+ self.Relative := false;
+ Rel[0] := 0;
+ CP := 0;
+ Both := false;
+
+ if Length(Player) = 2 then
+ Both := true;
+
+ Parser := TParser.Create;
+ Parser.Settings.DashReplacement := '~';
+
+ for Count := 0 to High(Lines) do
+ begin
+ SetLength(Lines[Count].Line, 1);
+ Lines[Count].High := 0;
+ Lines[Count].Number := 1;
+ Lines[Count].Current := 0;
+ Lines[Count].Resolution := self.Resolution;
+ Lines[Count].NotesGAP := self.NotesGAP;
+ Lines[Count].Line[0].HighNote := -1;
+ Lines[Count].Line[0].LastLine := False;
+ end;
+
+//Try to Parse the Song
+
+ if Parser.ParseSong(Path + PathDelim + FileName) then
+ begin
+// Writeln('XML Inputfile Parsed succesful');
+ //Start write parsed information to Song
+ //Notes Part
+ for I := 0 to High(Parser.SongInfo.Sentences) do
+ begin
+ //Add Notes
+ for J := 0 to High(Parser.SongInfo.Sentences[I].Notes) do
+ begin
+ case Parser.SongInfo.Sentences[I].Notes[J].NoteTyp of
+ NT_Normal: NoteType := ':';
+ NT_Golden: NoteType := '*';
+ NT_Freestyle: NoteType := 'F';
+ end;
+
+ Param1:=Parser.SongInfo.Sentences[I].Notes[J].Start; //Note Start
+ Param2:=Parser.SongInfo.Sentences[I].Notes[J].Duration; //Note Duration
+ Param3:=Parser.SongInfo.Sentences[I].Notes[J].Tone; //Note Tone
+ ParamS:=' ' + Parser.SongInfo.Sentences[I].Notes[J].Lyric; //Note Lyric
+
+ if not Both then
+ // P1
+ ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
+ else
+ begin
+ // P1 + P2
+ ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
+ ParseNote(1, NoteType, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
+ end;
+
+ if not Both then
+ begin
+ Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
+ Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(PChar(Lines[CP].Line[Lines[CP].High].Lyric));
+ //Total Notes Patch
+ Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
+ for X := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do
+ begin
+ if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then
+ Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length;
+
+ if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then
+ Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length;
+ end;
+ //Total Notes Patch End
+ end
+ else
+ begin
+ for Count := 0 to High(Lines) do
+ begin
+ Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
+ Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(PChar(Lines[Count].Line[Lines[Count].High].Lyric));
+ //Total Notes Patch
+ Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
+ for X := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do
+ begin
+ if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then
+ Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length;
+ if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then
+ Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length;
+
+ end;
+ //Total Notes Patch End
+ end;
+ end; { end of for loop }
+
+ end; //J Forloop
+
+ //Add Sentence break
+ if (I < High(Parser.SongInfo.Sentences)) then
+ begin
+
+ SentenceEnd := Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Start + Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Duration;
+ Rest := Parser.SongInfo.Sentences[I+1].Notes[0].Start - SentenceEnd;
+
+ //Calculate Time
+ case Rest of
+ 0, 1: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start;
+ 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1;
+ 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2;
+ else
+ if (Rest >= 4) then
+ Time := SentenceEnd + 2
+ else //Sentence overlapping :/
+ Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start;
+ end;
+ // new sentence
+ if not Both then
+ // P1
+ NewSentence(0, (Time + Rel[0]) * Mult, Param2)
+ else
+ begin
+ // P1 + P2
+ NewSentence(0, (Time + Rel[0]) * Mult, Param2);
+ NewSentence(1, (Time + Rel[1]) * Mult, Param2);
+ end;
+
+ end;
+ end;
+ //End write parsed information to Song
+ Parser.Free;
+ end
+ else
+ begin
+ Log.LogError('Could not parse Inputfile: ' + Path + PathDelim + FileName);
+ exit;
+ end;
+
+ for Count := 0 to High(Lines) do
+ begin
+ Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
+ end;
+
+ Result := true;
+end;
+
+function TSong.ReadXMLHeader(const aFileName : WideString): boolean;
+var
+ Line, Identifier, Value: string;
+ Temp : word;
+ Done : byte;
+ Parser : TParser;
+begin
+ Result := true;
+ Done := 0;
+
+//Parse XML
+ Parser := TParser.Create;
+ Parser.Settings.DashReplacement := '~';
+
+
+ if Parser.ParseSong(self.Path + self.FileName) then
+ begin
+ //-----------
+ //Required Attributes
+ //-----------
+
+ //Title
+ self.Title := Parser.SongInfo.Header.Title;
+
+ //Add Title Flag to Done
+ Done := Done or 1;
+
+ //Artist
+ self.Artist := Parser.SongInfo.Header.Artist;
+
+ //Add Artist Flag to Done
+ Done := Done or 2;
+
+ //MP3 File //Test if Exists
+ self.Mp3 := platform.FindSongFile(Path, '*.mp3');
+ if (FileExists(self.Path + self.Mp3)) then
+ //Add Mp3 Flag to Done
+ Done := Done or 4;
+
+ //Beats per Minute
+ SetLength(self.BPM, 1);
+ self.BPM[0].StartBeat := 0;
+
+ self.BPM[0].BPM := (Parser.SongInfo.Header.BPM * Parser.SongInfo.Header.Resolution/4 ) * Mult * MultBPM;
+
+ if self.BPM[0].BPM <> 0 then
+ //Add BPM Flag to Done
+ Done := Done or 8;
+
+ //---------
+ //Additional Header Information
+ //---------
+
+ // Gap
+ self.GAP := Parser.SongInfo.Header.Gap;
+
+ //Cover Picture
+ self.Cover := platform.FindSongFile(Path, '*[CO].jpg');
+
+ //Background Picture
+ self.Background := platform.FindSongFile(Path, '*[BG].jpg');
+
+ // Video File
+ // self.Video := Value
+
+ // Video Gap
+ // self.VideoGAP := song_StrtoFloat( Value )
+
+ //Genre Sorting
+ self.Genre := Parser.SongInfo.Header.Genre;
+
+ //Edition Sorting
+ self.Edition := Parser.SongInfo.Header.Edition;
+
+ //Year Sorting
+ //Parser.SongInfo.Header.Year
+
+ //Language Sorting
+ self.Language := Parser.SongInfo.Header.Language;
+ end else
+ Log.LogError('File Incomplete or not SingStar XML (A): ' + aFileName);
+
+ Parser.Free;
+
+ //Check if all Required Values are given
+ if (Done <> 15) then
+ begin
+ Result := False;
+ if (Done and 8) = 0 then //No BPM Flag
+ Log.LogError('BPM Tag Missing: ' + self.FileName)
+ else if (Done and 4) = 0 then //No MP3 Flag
+ Log.LogError('MP3 Tag/File Missing: ' + self.FileName)
+ else if (Done and 2) = 0 then //No Artist Flag
+ Log.LogError('Artist Tag Missing: ' + self.FileName)
+ else if (Done and 1) = 0 then //No Title Flag
+ Log.LogError('Title Tag Missing: ' + self.FileName)
+ else //unknown Error
+ Log.LogError('File Incomplete or not SingStar XML (B - '+ inttostr(Done) +'): ' + aFileName);
+ end;
+
+end;
+
+
+function TSong.ReadTXTHeader(const aFileName : WideString): boolean;
+
+ function song_StrtoFloat( aValue : string ) : Extended;
+ var
+ lValue : string;
+// lOldDecimalSeparator : Char; // Auto Removed, Unused Variable
+ begin
+ lValue := aValue;
+
+ if (Pos(',', lValue) <> 0) then
+ lValue[Pos(',', lValue)] := '.';
+
+ Result := StrToFloatDef(lValue, 0);
+ end;
+
+var
+ Line, Identifier, Value: string;
+ Temp : word;
+ Done : byte;
+begin
+ Result := true;
+ Done := 0;
+
+ //Read first Line
+ ReadLn (SongFile, Line);
+
+ if (Length(Line)<=0) then
+ begin
+ Log.LogError('File Starts with Empty Line: ' + aFileName);
+ Result := False;
+ Exit;
+ end;
+
+ //Read Lines while Line starts with # or its empty
+ while ( Length(Line) = 0 ) or
+ ( Line[1] = '#' ) do
+ begin
+ //Increase Line Number
+ Inc (FileLineNo);
+ Temp := Pos(':', Line);
+
+ //Line has a Seperator-> Headerline
+ if (Temp <> 0) then
+ begin
+ //Read Identifier and Value
+ Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks
+ Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp));
+
+ //Check the Identifier (If Value is given)
+ if (Length(Value) <> 0) then
+ begin
+
+ //-----------
+ //Required Attributes
+ //-----------
+
+ {$IFDEF UTF8_FILENAMES}
+ if ((Identifier = 'MP3') or (Identifier = 'BACKGROUND') or (Identifier = 'COVER') or (Identifier = 'VIDEO')) then
+ Value := Utf8Encode(Value);
+ {$ENDIF}
+
+ //Title
+ if (Identifier = 'TITLE') then
+ begin
+ self.Title := Value;
+
+ //Add Title Flag to Done
+ Done := Done or 1;
+ end
+
+ //Artist
+ else if (Identifier = 'ARTIST') then
+ begin
+ self.Artist := Value;
+
+ //Add Artist Flag to Done
+ Done := Done or 2;
+ end
+
+ //MP3 File //Test if Exists
+ else if (Identifier = 'MP3') AND
+ (FileExists(self.Path + Value)) then
+ begin
+ self.Mp3 := Value;
+
+ //Add Mp3 Flag to Done
+ Done := Done or 4;
+ end
+
+ //Beats per Minute
+ else if (Identifier = 'BPM') then
+ begin
+ SetLength(self.BPM, 1);
+ self.BPM[0].StartBeat := 0;
+
+ self.BPM[0].BPM := song_StrtoFloat( Value ) * Mult * MultBPM;
+
+ if self.BPM[0].BPM <> 0 then
+ begin
+ //Add BPM Flag to Done
+ Done := Done or 8;
+ end;
+ end
+
+ //---------
+ //Additional Header Information
+ //---------
+
+ // Gap
+ else if (Identifier = 'GAP') then
+ self.GAP := song_StrtoFloat( Value )
+
+ //Cover Picture
+ else if (Identifier = 'COVER') then
+ self.Cover := Value
+
+ //Background Picture
+ else if (Identifier = 'BACKGROUND') then
+ self.Background := Value
+
+ // Video File
+ else if (Identifier = 'VIDEO') then
+ begin
+ if (FileExists(self.Path + Value)) then
+ self.Video := Value
+ else
+ Log.LogError('Can''t find Video File in Song: ' + aFileName);
+ end
+
+ // Video Gap
+ else if (Identifier = 'VIDEOGAP') then
+ self.VideoGAP := song_StrtoFloat( Value )
+
+ //Genre Sorting
+ else if (Identifier = 'GENRE') then
+ self.Genre := Value
+
+ //Edition Sorting
+ else if (Identifier = 'EDITION') then
+ self.Edition := Value
+
+ //Creator Tag
+ else if (Identifier = 'CREATOR') then
+ self.Creator := Value
+
+ //Language Sorting
+ else if (Identifier = 'LANGUAGE') then
+ self.Language := Value
+
+ // Song Start
+ else if (Identifier = 'START') then
+ self.Start := song_StrtoFloat( Value )
+
+ // Song Ending
+ else if (Identifier = 'END') then
+ TryStrtoInt(Value, self.Finish)
+
+ // Resolution
+ else if (Identifier = 'RESOLUTION') then
+ TryStrtoInt(Value, self.Resolution)
+
+ // Notes Gap
+ else if (Identifier = 'NOTESGAP') then
+ TryStrtoInt(Value, self.NotesGAP)
+ // Relative Notes
+ else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then
+ self.Relative := True;
+
+ end;
+ end;
+
+ if not EOf(SongFile) then
+ ReadLn (SongFile, Line)
+ else
+ begin
+ Result := False;
+ Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + aFileName);
+ break;
+ end;
+
+ end;
+
+ if self.Cover = '' then
+ self.Cover := platform.FindSongFile(Path, '*[CO].jpg');
+
+ //Check if all Required Values are given
+ if (Done <> 15) then
+ begin
+ Result := False;
+ if (Done and 8) = 0 then //No BPM Flag
+ Log.LogError('BPM Tag Missing: ' + self.FileName)
+ else if (Done and 4) = 0 then //No MP3 Flag
+ Log.LogError('MP3 Tag/File Missing: ' + self.FileName)
+ else if (Done and 2) = 0 then //No Artist Flag
+ Log.LogError('Artist Tag Missing: ' + self.FileName)
+ else if (Done and 1) = 0 then //No Title Flag
+ Log.LogError('Title Tag Missing: ' + self.FileName)
+ else //unknown Error
+ Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + aFileName);
+ end;
+
+end;
+
+procedure TSong.ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
+//var
+// Space: boolean; // Auto Removed, Unused Variable
+begin
+ case Ini.Solmization of
+ 1: // european
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' sol ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' si ';
+ end;
+ end;
+ 2: // japanese
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' so ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' shi ';
+ end;
+ end;
+ 3: // american
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' sol ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' ti ';
+ end;
+ end;
+ end; // case
+
+ with Lines[LineNumber].Line[Lines[LineNumber].High] do
+ begin
+ SetLength(Note, Length(Note) + 1);
+ HighNote := High(Note);
+
+ Note[HighNote].Start := StartP;
+ if HighNote = 0 then
+ begin
+ if Lines[LineNumber].Number = 1 then
+ Start := -100;
+// Start := Note[HighNote].Start;
+ end;
+
+ Note[HighNote].Length := DurationP;
+
+ // back to the normal system with normal, golden and now freestyle notes
+ case TypeP of
+ 'F': Note[HighNote].NoteType := ntFreestyle;
+ ':': Note[HighNote].NoteType := ntNormal;
+ '*': Note[HighNote].NoteType := ntGolden;
+ end;
+
+ if (Note[HighNote].NoteType = ntGolden) then
+ Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
+
+ if (Note[HighNote].NoteType <> ntFreestyle) then
+ Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
+
+ Note[HighNote].Tone := NoteP;
+ if Note[HighNote].Tone < Base[LineNumber] then Base[LineNumber] := Note[HighNote].Tone;
+
+ Note[HighNote].Text := Copy(LyricS, 2, 100);
+ Lyric := Lyric + Note[HighNote].Text;
+
+ End_ := Note[HighNote].Start + Note[HighNote].Length;
+ end; // with
+end;
+
+procedure TSong.NewSentence(LineNumberP: integer; Param1, Param2: integer);
+var
+ I: integer;
+begin
+
+ // stara czesc //Alter Satz //Update Old Part
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].BaseNote := Base[LineNumberP];
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].LyricWidth := glTextWidth(PChar(Lines[LineNumberP].Line[Lines[LineNumberP].High].Lyric));
+
+ //Total Notes Patch
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := 0;
+ for I := low(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) to high(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) do
+ begin
+ if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType = ntGolden) then
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
+
+ if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType <> ntFreestyle) then
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
+ end;
+ //Total Notes Patch End
+
+
+ // nowa czesc //Neuer Satz //Update New Part
+ SetLength(Lines[LineNumberP].Line, Lines[LineNumberP].Number + 1);
+ Lines[LineNumberP].High := Lines[LineNumberP].High + 1;
+ Lines[LineNumberP].Number := Lines[LineNumberP].Number + 1;
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote := -1;
+
+ if self.Relative then
+ begin
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
+ Rel[LineNumberP] := Rel[LineNumberP] + Param2;
+ end
+ else
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
+
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].LastLine := False;
+
+ Base[LineNumberP] := 100; // high number
+end;
+
+procedure TSong.clear();
+begin
+ //Main Information
+ Title := '';
+ Artist := '';
+
+ //Sortings:
+ Genre := 'Unknown';
+ Edition := 'Unknown';
+ Language := 'Unknown'; //Language Patch
+
+ //Required Information
+ Mp3 := '';
+ {$IFDEF FPC}
+ setlength( BPM, 0 );
+ {$ELSE}
+ BPM := nil;
+ {$ENDIF}
+
+ GAP := 0;
+ Start := 0;
+ Finish := 0;
+
+ //Additional Information
+ Background := '';
+ Cover := '';
+ Video := '';
+ VideoGAP := 0;
+ NotesGAP := 0;
+ Resolution := 4;
+ Creator := '';
+
+end;
+
+function TSong.Analyse(): boolean;
+begin
+ Result := False;
+
+ //Reset LineNo
+ FileLineNo := 0;
+
+ //Open File and set File Pointer to the beginning
+ AssignFile(SongFile, self.Path + self.FileName);
+
+ try
+ Reset(SongFile);
+
+ //Clear old Song Header
+ self.clear;
+
+ //Read Header
+ Result := self.ReadTxTHeader( FileName )
+
+ //And Close File
+ finally
+ CloseFile(SongFile);
+ end;
+end;
+
+
+function TSong.AnalyseXML(): boolean;
+begin
+ Result := False;
+
+ //Reset LineNo
+ FileLineNo := 0;
+
+ //Clear old Song Header
+ self.clear;
+
+ //Read Header
+ Result := self.ReadXMLHeader( FileName );
+
+end;
+
+end.
diff --git a/src/Classes/USongs.pas b/src/Classes/USongs.pas
new file mode 100644
index 00000000..710cd44f
--- /dev/null
+++ b/src/Classes/USongs.pas
@@ -0,0 +1,806 @@
+unit USongs;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+{$IFDEF DARWIN}
+ {$IFDEF DEBUG}
+ {$DEFINE USE_PSEUDO_THREAD}
+ {$ENDIF}
+{$ENDIF}
+
+uses
+ {$IFDEF MSWINDOWS}
+ Windows,
+ DirWatch,
+ {$ELSE}
+ {$IFNDEF DARWIN}
+ syscall,
+ {$ENDIF}
+ baseunix,
+ UnixType,
+ {$ENDIF}
+ SysUtils,
+ Classes,
+ UPlatform,
+ ULog,
+ UTexture,
+ UCommon,
+ {$IFDEF DARWIN}
+ cthreads,
+ {$ENDIF}
+ {$IFDEF USE_PSEUDO_THREAD}
+ PseudoThread,
+ {$ENDIF}
+ USong,
+ UCatCovers;
+
+type
+
+ TBPM = record
+ BPM: real;
+ StartBeat: real;
+ end;
+
+ TScore = record
+ Name: widestring;
+ Score: integer;
+ Length: string;
+ end;
+
+ {$IFDEF USE_PSEUDO_THREAD}
+ TSongs = class( TPseudoThread )
+ {$ELSE}
+ TSongs = class( TThread )
+ {$ENDIF}
+ private
+ fNotify, fWatch : longint;
+ fParseSongDirectory : boolean;
+ fProcessing : boolean;
+ {$ifdef MSWINDOWS}
+ fDirWatch : TDirectoryWatch;
+ {$endif}
+ procedure int_LoadSongList;
+ procedure DoDirChanged(Sender: TObject);
+ protected
+ procedure Execute; override;
+ public
+ SongList : TList; // array of songs
+ Selected : integer; // selected song index
+ constructor Create();
+ destructor Destroy(); override;
+
+
+ procedure LoadSongList; // load all songs
+ procedure BrowseDir(Dir: widestring); // should return number of songs in the future
+ procedure BrowseTXTFiles(Dir: widestring);
+ procedure BrowseXMLFiles(Dir: widestring);
+ procedure Sort(Order: integer);
+ function FindSongFile(Dir, Mask: widestring): widestring;
+ property Processing : boolean read fProcessing;
+ end;
+
+
+ TCatSongs = class
+ Song: array of TSong; // array of categories with songs
+ Selected: integer; // selected song index
+ Order: integer; // order type (0=title)
+ CatNumShow: integer; // Category Number being seen
+ CatCount: integer; //Number of Categorys
+
+ procedure SortSongs();
+ procedure Refresh; // refreshes arrays by recreating them from Songs array
+ procedure ShowCategory(Index: integer); // expands all songs in category
+ procedure HideCategory(Index: integer); // hides all songs in category
+ procedure ClickCategoryButton(Index: integer); // uses ShowCategory and HideCategory when needed
+ procedure ShowCategoryList; //Hides all Songs And Show the List of all Categorys
+ function FindNextVisible(SearchFrom:integer): integer; //Find Next visible Song
+ function VisibleSongs: integer; // returns number of visible songs (for tabs)
+ function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
+
+ function SetFilter(FilterStr: string; const fType: Byte): Cardinal;
+ end;
+
+var
+ Songs: TSongs; // all songs
+ CatSongs: TCatSongs; // categorized songs
+
+const
+ IN_ACCESS = $00000001; //* File was accessed */
+ IN_MODIFY = $00000002; //* File was modified */
+ IN_ATTRIB = $00000004; //* Metadata changed */
+ IN_CLOSE_WRITE = $00000008; //* Writtable file was closed */
+ IN_CLOSE_NOWRITE = $00000010; //* Unwrittable file closed */
+ IN_OPEN = $00000020; //* File was opened */
+ IN_MOVED_FROM = $00000040; //* File was moved from X */
+ IN_MOVED_TO = $00000080; //* File was moved to Y */
+ IN_CREATE = $00000100; //* Subfile was created */
+ IN_DELETE = $00000200; //* Subfile was deleted */
+ IN_DELETE_SELF = $00000400; //* Self was deleted */
+
+
+implementation
+
+uses StrUtils,
+ UGraphic,
+ UCovers,
+ UFiles,
+ UMain,
+ UIni;
+
+constructor TSongs.Create();
+begin
+ // do not start thread BEFORE initialization (suspended = true)
+ inherited Create(true);
+ Self.FreeOnTerminate := true;
+
+ SongList := TList.Create();
+
+ // FIXME: threaded loading does not work this way.
+ // It will just cause crashes but nothing else at the moment.
+ (*
+ {$ifdef MSWINDOWS}
+ fDirWatch := TDirectoryWatch.create(nil);
+ fDirWatch.OnChange := DoDirChanged;
+ fDirWatch.Directory := SongPath;
+ fDirWatch.WatchSubDirs := true;
+ fDirWatch.active := true;
+ {$ENDIF}
+
+ // now we can start the thread
+ Resume();
+ *)
+
+ // until it is fixed, simply load the song-list
+ int_LoadSongList();
+end;
+
+destructor TSongs.Destroy();
+begin
+ FreeAndNil( SongList );
+ inherited;
+end;
+
+procedure TSongs.DoDirChanged(Sender: TObject);
+begin
+ LoadSongList();
+end;
+
+procedure TSongs.Execute();
+var
+ fChangeNotify : THandle;
+begin
+{$IFDEF USE_PSEUDO_THREAD}
+ int_LoadSongList();
+{$ELSE}
+ fParseSongDirectory := true;
+
+ while not terminated do
+ begin
+
+ if fParseSongDirectory then
+ begin
+ Log.LogStatus('Calling int_LoadSongList', 'TSongs.Execute');
+ int_LoadSongList();
+ end;
+
+ Suspend();
+ end;
+{$ENDIF}
+end;
+
+procedure TSongs.int_LoadSongList;
+var
+ I: integer;
+begin
+ try
+ fProcessing := true;
+
+ Log.LogStatus('Searching For Songs', 'SongList');
+
+ // browse directories
+ for I := 0 to SongPaths.Count-1 do
+ BrowseDir(SongPaths[I]);
+
+ if assigned( CatSongs ) then
+ CatSongs.Refresh;
+
+ if assigned( CatCovers ) then
+ CatCovers.Load;
+
+ //if assigned( Covers ) then
+ // Covers.Load;
+
+ if assigned(ScreenSong) then
+ begin
+ ScreenSong.GenerateThumbnails();
+ ScreenSong.OnShow; // refresh ScreenSong
+ end;
+
+ finally
+ Log.LogStatus('Search Complete', 'SongList');
+
+ fParseSongDirectory := false;
+ fProcessing := false;
+ end;
+end;
+
+
+procedure TSongs.LoadSongList;
+begin
+ fParseSongDirectory := true;
+ Resume();
+end;
+
+procedure TSongs.BrowseDir(Dir: widestring);
+begin
+ BrowseTXTFiles(Dir);
+ BrowseXMLFiles(Dir);
+end;
+
+procedure TSongs.BrowseTXTFiles(Dir: widestring);
+var
+ i : integer;
+ Files : TDirectoryEntryArray;
+ lSong : TSong;
+begin
+
+ Files := Platform.DirectoryFindFiles( Dir, '.txt', true);
+
+ for i := 0 to Length(Files)-1 do
+ begin
+ if Files[i].IsDirectory then
+ begin
+ BrowseTXTFiles( Dir + Files[i].Name + PathDelim ); //Recursive Call
+ end
+ else
+ begin
+ lSong := TSong.create( Dir + Files[i].Name );
+
+ if lSong.Analyse then
+ SongList.add( lSong )
+ else
+ begin
+ Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".');
+ freeandnil( lSong );
+ end;
+
+ end;
+ end;
+ SetLength( Files, 0);
+
+end;
+
+procedure TSongs.BrowseXMLFiles(Dir: widestring);
+var
+ i : integer;
+ Files : TDirectoryEntryArray;
+ lSong : TSong;
+begin
+
+ Files := Platform.DirectoryFindFiles( Dir, '.xml', true);
+
+ for i := 0 to Length(Files)-1 do
+ begin
+ if Files[i].IsDirectory then
+ begin
+ BrowseXMLFiles( Dir + Files[i].Name + PathDelim ); //Recursive Call
+ end
+ else
+ begin
+ lSong := TSong.create( Dir + Files[i].Name );
+
+ if lSong.AnalyseXML then
+ SongList.add( lSong )
+ else
+ begin
+ Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".');
+ freeandnil( lSong );
+ end;
+
+ end;
+ end;
+ SetLength( Files, 0);
+
+end;
+
+(*
+ * Comparison functions for sorting
+ *)
+
+function CompareByEdition(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Edition, TSong(Song2).Edition);
+end;
+
+function CompareByGenre(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Genre, TSong(Song2).Genre);
+end;
+
+function CompareByTitle(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Title, TSong(Song2).Title);
+end;
+
+function CompareByArtist(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Artist, TSong(Song2).Artist);
+end;
+
+function CompareByFolder(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Folder, TSong(Song2).Folder);
+end;
+
+function CompareByLanguage(Song1, Song2: Pointer): integer;
+begin
+ Result := CompareText(TSong(Song1).Language, TSong(Song2).Language);
+end;
+
+procedure TSongs.Sort(Order: integer);
+var
+ CompareFunc: TListSortCompare;
+begin
+ // FIXME: what is the difference between artist and artist2, etc.?
+ case Order of
+ sEdition: // by edition
+ CompareFunc := CompareByEdition;
+ sGenre: // by genre
+ CompareFunc := CompareByGenre;
+ sTitle: // by title
+ CompareFunc := CompareByTitle;
+ sArtist: // by artist
+ CompareFunc := CompareByArtist;
+ sFolder: // by folder
+ CompareFunc := CompareByFolder;
+ sTitle2: // by title2
+ CompareFunc := CompareByTitle;
+ sArtist2: // by artist2
+ CompareFunc := CompareByArtist;
+ sLanguage: // by Language
+ CompareFunc := CompareByLanguage;
+ else
+ Log.LogCritical('Unsupported comparison', 'TSongs.Sort');
+ Exit; // suppress warning
+ end; // case
+
+ // Note: Do not use TList.Sort() as it uses QuickSort which is instable.
+ // For example, if a list is sorted by title first and
+ // by artist afterwards, the songs of an artist will not be sorted by title anymore.
+ // The stable MergeSort guarantees to maintain this order.
+ MergeSort(SongList, CompareFunc);
+end;
+
+function TSongs.FindSongFile(Dir, Mask: widestring): widestring;
+var
+ SR: TSearchRec; // for parsing song directory
+begin
+ Result := '';
+ if FindFirst(Dir + Mask, faDirectory, SR) = 0 then
+ begin
+ Result := SR.Name;
+ end; // if
+ FindClose(SR);
+end;
+
+procedure TCatSongs.SortSongs();
+begin
+ case Ini.Sorting of
+ sEdition: begin
+ Songs.Sort(sTitle);
+ Songs.Sort(sArtist);
+ Songs.Sort(sEdition);
+ end;
+ sGenre: begin
+ Songs.Sort(sTitle);
+ Songs.Sort(sArtist);
+ Songs.Sort(sGenre);
+ end;
+ sLanguage: begin
+ Songs.Sort(sTitle);
+ Songs.Sort(sArtist);
+ Songs.Sort(sLanguage);
+ end;
+ sFolder: begin
+ Songs.Sort(sTitle);
+ Songs.Sort(sArtist);
+ Songs.Sort(sFolder);
+ end;
+ sTitle: begin
+ Songs.Sort(sTitle);
+ end;
+ sArtist: begin
+ Songs.Sort(sTitle);
+ Songs.Sort(sArtist);
+ end;
+ sTitle2: begin
+ Songs.Sort(sArtist2);
+ Songs.Sort(sTitle2);
+ end;
+ sArtist2: begin
+ Songs.Sort(sTitle2);
+ Songs.Sort(sArtist2);
+ end;
+ end; // case
+end;
+
+procedure TCatSongs.Refresh;
+var
+ SongIndex: integer;
+ CurSong: TSong;
+ CatIndex: integer; // index of current song in Song
+ Letter: char; // current letter for sorting using letter
+ CurCategory: string; // current edition for sorting using edition, genre etc.
+ Order: integer; // number used for ordernum
+ LetterTmp: char;
+ CatNumber: integer; // Number of Song in Category
+
+ procedure AddCategoryButton(const CategoryName: string);
+ var
+ PrevCatBtnIndex: integer;
+ begin
+ Inc(Order);
+ CatIndex := Length(Song);
+ SetLength(Song, CatIndex+1);
+ Song[CatIndex] := TSong.Create();
+ Song[CatIndex].Artist := '[' + CategoryName + ']';
+ Song[CatIndex].Main := true;
+ Song[CatIndex].OrderTyp := 0;
+ Song[CatIndex].OrderNum := Order;
+ Song[CatIndex].Cover := CatCovers.GetCover(Ini.Sorting, CategoryName);
+ Song[CatIndex].Visible := true;
+
+ // set number of songs in previous category
+ PrevCatBtnIndex := CatIndex - CatNumber - 1;
+ if ((PrevCatBtnIndex >= 0) and Song[PrevCatBtnIndex].Main) then
+ Song[PrevCatBtnIndex].CatNumber := CatNumber;
+
+ CatNumber := 0;
+ end;
+
+begin
+ CatNumShow := -1;
+
+ SortSongs();
+
+ CurCategory := '';
+ Order := 0;
+ CatNumber := 0;
+
+ // Note: do NOT set Letter to ' ', otherwise no category-button will be
+ // created for songs beginning with ' ' if songs of this category exist.
+ // TODO: trim song-properties so ' ' will not occur as first chararcter.
+ Letter := #0;
+
+ // clear song-list
+ for SongIndex := 0 to Songs.SongList.Count-1 do
+ begin
+ // free category buttons
+ // Note: do NOT delete songs, they are just references to Songs.SongList entries
+ CurSong := TSong(Songs.SongList[SongIndex]);
+ if (CurSong.Main) then
+ CurSong.Free;
+ end;
+ SetLength(Song, 0);
+
+ for SongIndex := 0 to Songs.SongList.Count-1 do
+ begin
+ CurSong := TSong(Songs.SongList[SongIndex]);
+ // if tabs are on, add section buttons for each new section
+ if (Ini.Tabs = 1) then
+ begin
+ if (Ini.Sorting = sEdition) and
+ (CompareText(CurCategory, CurSong.Edition) <> 0) then
+ begin
+ CurCategory := CurSong.Edition;
+
+ // TODO: remove this block if it is not needed anymore
+ {
+ if CurSection = 'Singstar Part 2' then CoverName := 'Singstar';
+ if CurSection = 'Singstar German' then CoverName := 'Singstar';
+ if CurSection = 'Singstar Spanish' then CoverName := 'Singstar';
+ if CurSection = 'Singstar Italian' then CoverName := 'Singstar';
+ if CurSection = 'Singstar French' then CoverName := 'Singstar';
+ if CurSection = 'Singstar 80s Polish' then CoverName := 'Singstar 80s';
+ }
+
+ // add Category Button
+ AddCategoryButton(CurCategory);
+ end
+
+ else if (Ini.Sorting = sGenre) and
+ (CompareText(CurCategory, CurSong.Genre) <> 0) then
+ begin
+ CurCategory := CurSong.Genre;
+ // add Genre Button
+ AddCategoryButton(CurCategory);
+ end
+
+ else if (Ini.Sorting = sLanguage) and
+ (CompareText(CurCategory, CurSong.Language) <> 0) then
+ begin
+ CurCategory := CurSong.Language;
+ // add Language Button
+ AddCategoryButton(CurCategory);
+ end
+
+ else if (Ini.Sorting = sTitle) and
+ (Length(CurSong.Title) >= 1) and
+ (Letter <> UpperCase(CurSong.Title)[1]) then
+ begin
+ Letter := Uppercase(CurSong.Title)[1];
+ // add a letter Category Button
+ AddCategoryButton(Letter);
+ end
+
+ else if (Ini.Sorting = sArtist) and
+ (Length(CurSong.Artist) >= 1) and
+ (Letter <> UpperCase(CurSong.Artist)[1]) then
+ begin
+ Letter := UpperCase(CurSong.Artist)[1];
+ // add a letter Category Button
+ AddCategoryButton(Letter);
+ end
+
+ else if (Ini.Sorting = sFolder) and
+ (CompareText(CurCategory, CurSong.Folder) <> 0) then
+ begin
+ CurCategory := CurSong.Folder;
+ // add folder tab
+ AddCategoryButton(CurCategory);
+ end
+
+ else if (Ini.Sorting = sTitle2) and
+ (Length(CurSong.Title) >= 1) then
+ begin
+ // pack all numbers into a category named '#'
+ if (CurSong.Title[1] >= '0') and (CurSong.Title[1] <= '9') then
+ LetterTmp := '#'
+ else
+ LetterTmp := UpperCase(CurSong.Title)[1];
+
+ if (Letter <> LetterTmp) then
+ begin
+ Letter := LetterTmp;
+ // add a letter Category Button
+ AddCategoryButton(Letter);
+ end;
+ end
+
+ else if (Ini.Sorting = sArtist2) and
+ (Length(CurSong.Artist)>=1) then
+ begin
+ // pack all numbers into a category named '#'
+ if (CurSong.Artist[1] >= '0') and (CurSong.Artist[1] <= '9') then
+ LetterTmp := '#'
+ else
+ LetterTmp := UpperCase(CurSong.Artist)[1];
+
+ if (Letter <> LetterTmp) then
+ begin
+ Letter := LetterTmp;
+ // add a letter Category Button
+ AddCategoryButton(Letter);
+ end;
+ end;
+ end;
+
+ CatIndex := Length(Song);
+ SetLength(Song, CatIndex+1);
+
+ Inc(CatNumber); // increase number of songs in category
+
+ // copy reference to current song
+ Song[CatIndex] := CurSong;
+
+ // set song's category info
+ CurSong.OrderNum := Order; // assigns category
+ CurSong.CatNumber := CatNumber;
+
+ if (Ini.Tabs = 0) then
+ CurSong.Visible := true
+ else if (Ini.Tabs = 1) then
+ CurSong.Visible := false;
+
+ {
+ if (Ini.Tabs = 1) and (Order = 1) then
+ begin
+ //open first tab
+ CurSong.Visible := true;
+ end;
+ CurSong.Visible := true;
+ }
+ end;
+
+ // set CatNumber of last category
+ if (Ini.Tabs_at_startup = 1) and (High(Song) >= 1) then
+ begin
+ // set number of songs in previous category
+ SongIndex := CatIndex - CatNumber;
+ if ((SongIndex >= 0) and Song[SongIndex].Main) then
+ Song[SongIndex].CatNumber := CatNumber;
+ end;
+
+ // update number of categories
+ CatCount := Order;
+end;
+
+procedure TCatSongs.ShowCategory(Index: integer);
+var
+ S: integer; // song
+begin
+ CatNumShow := Index;
+ for S := 0 to high(CatSongs.Song) do
+ begin
+{
+ if (CatSongs.Song[S].OrderNum = Index) and (not CatSongs.Song[S].Main) then
+ CatSongs.Song[S].Visible := true
+ else
+ CatSongs.Song[S].Visible := false;
+}
+// KMS: This should be the same, but who knows :-)
+ CatSongs.Song[S].Visible := ( (CatSongs.Song[S].OrderNum = Index) and (not CatSongs.Song[S].Main) );
+ end;
+end;
+
+procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category
+var
+ S: integer; // song
+begin
+ for S := 0 to high(CatSongs.Song) do
+ begin
+ if not CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := false // hides all at now
+ end;
+end;
+
+procedure TCatSongs.ClickCategoryButton(Index: integer);
+var
+ Num, S: integer;
+begin
+ Num := CatSongs.Song[Index].OrderNum;
+ if Num <> CatNumShow then
+ begin
+ ShowCategory(Num);
+ end
+ else
+ begin
+ ShowCategoryList;
+ end;
+end;
+
+//Hide Categorys when in Category Hack
+procedure TCatSongs.ShowCategoryList;
+var
+ Num, S: integer;
+begin
+ // Hide All Songs Show All Cats
+ for S := 0 to high(CatSongs.Song) do
+ CatSongs.Song[S].Visible := CatSongs.Song[S].Main;
+ CatSongs.Selected := CatNumShow; //Show last shown Category
+ CatNumShow := -1;
+end;
+//Hide Categorys when in Category Hack End
+
+//Wrong song selected when tabs on bug
+function TCatSongs.FindNextVisible(SearchFrom:integer): integer;//Find next Visible Song
+var
+ I: integer;
+begin
+ Result := -1;
+ I := SearchFrom + 1;
+ while not CatSongs.Song[I].Visible do
+ begin
+ Inc (I);
+ if (I>high(CatSongs.Song)) then
+ I := low(CatSongs.Song);
+ if (I = SearchFrom) then //Make One Round and no song found->quit
+ break;
+ end;
+end;
+//Wrong song selected when tabs on bug End
+
+(**
+ * Returns the number of visible songs.
+ *)
+function TCatSongs.VisibleSongs: integer;
+var
+ SongIndex: integer;
+begin
+ Result := 0;
+ for SongIndex := 0 to High(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[SongIndex].Visible) then
+ Inc(Result);
+ end;
+end;
+
+(**
+ * Returns the index of a song in the subset of all visible songs.
+ * If all songs are visible, the result will be equal to the Index parameter.
+ *)
+function TCatSongs.VisibleIndex(Index: integer): integer;
+var
+ SongIndex: integer;
+begin
+ Result := 0;
+ for SongIndex := 0 to Index-1 do
+ begin
+ if (CatSongs.Song[SongIndex].Visible) then
+ Inc(Result);
+ end;
+end;
+
+function TCatSongs.SetFilter(FilterStr: string; const fType: Byte): Cardinal;
+var
+ I, J: integer;
+ cString: string;
+ SearchStr: array of string;
+begin
+ {fType: 0: All
+ 1: Title
+ 2: Artist}
+ FilterStr := Trim(FilterStr);
+ if FilterStr<>'' then
+ begin
+ Result := 0;
+ //Create Search Array
+ SetLength(SearchStr, 1);
+ I := Pos (' ', FilterStr);
+ while (I <> 0) do
+ begin
+ SetLength (SearchStr, Length(SearchStr) + 1);
+ cString := Copy(FilterStr, 1, I-1);
+ if (cString <> ' ') and (cString <> '') then
+ SearchStr[High(SearchStr)-1] := cString;
+ Delete (FilterStr, 1, I);
+
+ I := Pos (' ', FilterStr);
+ end;
+ //Copy last Word
+ if (FilterStr <> ' ') and (FilterStr <> '') then
+ SearchStr[High(SearchStr)] := FilterStr;
+
+ for I:=0 to High(Song) do
+ begin
+ if not Song[i].Main then
+ begin
+ case fType of
+ 0: cString := Song[I].Artist + ' ' + Song[i].Title + ' ' + Song[i].Folder;
+ 1: cString := Song[I].Title;
+ 2: cString := Song[I].Artist;
+ end;
+ Song[i].Visible:=True;
+ //Look for every Searched Word
+ for J := 0 to High(SearchStr) do
+ begin
+ Song[i].Visible := Song[i].Visible and AnsiContainsText(cString, SearchStr[J])
+ end;
+ if Song[i].Visible then
+ Inc(Result);
+ end
+ else
+ Song[i].Visible:=False;
+ end;
+ CatNumShow := -2;
+ end
+ else
+ begin
+ for i:=0 to High(Song) do
+ begin
+ Song[i].Visible := (Ini.Tabs=1) = Song[i].Main;
+ CatNumShow := -1;
+ end;
+ Result := 0;
+ end;
+end;
+
+// -----------------------------------------------------------------------------
+
+end.
diff --git a/src/Classes/UTextClasses.pas b/src/Classes/UTextClasses.pas
new file mode 100644
index 00000000..9a12e1f5
--- /dev/null
+++ b/src/Classes/UTextClasses.pas
@@ -0,0 +1,60 @@
+unit UTextClasses;
+
+interface
+
+{$I switches.inc}
+
+uses
+ gl,
+ SDL,
+ UTexture,
+ Classes,
+// SDL_ttf,
+ ULog;
+
+{
+// okay i just outline what should be here, so we can create a nice and clean implementation of sdl_ttf
+// based up on this uml: http://jnr.sourceforge.net/fusion_images/www_FRS.png
+// thanks to Bob Pendelton and Koshmaar!
+// (1) let's start with a glyph, this represents one character in a word
+
+type
+ TGlyph = record
+ character : Char; // unsigned char, uchar is something else in delphi
+ glyphsSolid[8] : GlyphTexture; // fast, but not that
+ glyphsBlended[8] : GlyphTexture; // slower than solid, but it look's more pretty
+
+//this class has a method, which should be a deconstructor (mog is on his way to understand the principles of oop :P)
+ deconstructor procedure ReleaseTextures();
+end;
+
+// (2) okay, we now need the stuff that's even beneath this glyph - we're right at the birth of text in here :P
+
+ GlyphTexture = record
+ textureID : GLuint; // we need this for caching the letters, if the texture wasn't created before create it, should be very fast because of this one
+ width,
+ height : Cardinal;
+ charWidth,
+ charHeight : Integer;
+ advance : Integer; // don't know yet for what this one is
+}
+
+{
+// after the glyph is done, we now start to build whole words - this one is pretty important, and does most of the work we need
+ TGlyphsContainer = record
+ glyphs array of TGlyph;
+ FontName array of string;
+ refCount : uChar; // unsigned char, uchar is something else in delphi
+ font : PTTF_font;
+ size,
+ lineSkip : Cardinal; // vertical distance between multi line text output
+ descent : Integer;
+
+
+
+}
+
+
+implementation
+
+end.
diff --git a/src/Classes/UTexture.pas b/src/Classes/UTexture.pas
new file mode 100644
index 00000000..4879760a
--- /dev/null
+++ b/src/Classes/UTexture.pas
@@ -0,0 +1,525 @@
+unit UTexture;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ gl,
+ glu,
+ glext,
+ Classes,
+ SysUtils,
+ UCommon,
+ SDL,
+ SDL_Image;
+
+type
+ PTexture = ^TTexture;
+ TTexture = record
+ TexNum: GLuint;
+ X: real;
+ Y: real;
+ Z: real;
+ W: real;
+ H: real;
+ ScaleW: real; // for dynamic scalling while leaving width constant
+ ScaleH: real; // for dynamic scalling while leaving height constant
+ Rot: real; // 0 - 2*pi
+ Int: real; // intensity
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ TexW: real; // percentage of width to use [0..1]
+ TexH: real; // percentage of height to use [0..1]
+ TexX1: real;
+ TexY1: real;
+ TexX2: real;
+ TexY2: real;
+ Alpha: real;
+ Name: string; // experimental for handling cache images. maybe it's useful for dynamic skins
+ end;
+
+type
+ TTextureType = (
+ TEXTURE_TYPE_PLAIN, // Plain (alpha = 1)
+ TEXTURE_TYPE_TRANSPARENT, // Alpha is used
+ TEXTURE_TYPE_COLORIZED // Alpha is used; Hue of the HSV color-model will be replaced by a new value
+ );
+
+const
+ TextureTypeStr: array[TTextureType] of string = (
+ 'Plain',
+ 'Transparent',
+ 'Colorized'
+ );
+
+function TextureTypeToStr(TexType: TTextureType): string;
+function ParseTextureType(const TypeStr: string; Default: TTextureType): TTextureType;
+
+procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: TTextureType);
+
+type
+ PTextureEntry = ^TTextureEntry;
+ TTextureEntry = record
+ Name: string;
+ Typ: TTextureType;
+ Color: Cardinal;
+
+ // we use normal TTexture, it's easier to implement and if needed - we copy ready data
+ Texture: TTexture; // Full-size texture
+ TextureCache: TTexture; // Thumbnail texture
+ end;
+
+ TTextureDatabase = class
+ private
+ Texture: array of TTextureEntry;
+ public
+ procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
+ function FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
+ end;
+
+ TTextureUnit = class
+ private
+ TextureDatabase: TTextureDatabase;
+ public
+ Limit: integer;
+
+ procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean = false); overload;
+ procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean = false); overload;
+ function GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean = false): TTexture; overload;
+ function GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean = false): TTexture; overload;
+ function LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload;
+ function LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload;
+ function LoadTexture(const Identifier: string): TTexture; overload;
+ function CreateTexture(Data: PChar; const Name: string; Width, Height: word; BitsPerPixel: byte): TTexture;
+ procedure UnloadTexture(const Name: string; Typ: TTextureType; FromCache: boolean); overload;
+ procedure UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean); overload;
+ //procedure FlushTextureDatabase();
+
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+var
+ Texture: TTextureUnit;
+
+implementation
+
+uses
+ DateUtils,
+ StrUtils,
+ Math,
+ ULog,
+ UCovers,
+ UThemes,
+ UImage;
+
+procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: TTextureType);
+var
+ TempSurface: PSDL_Surface;
+ NeededPixFmt: PSDL_Pixelformat;
+begin
+ if (Typ = TEXTURE_TYPE_PLAIN) then
+ NeededPixFmt := @PixelFmt_RGB
+ else if (Typ = TEXTURE_TYPE_TRANSPARENT) or
+ (Typ = TEXTURE_TYPE_COLORIZED) then
+ NeededPixFmt := @PixelFmt_RGBA
+ else
+ NeededPixFmt := @PixelFmt_RGB;
+
+ if not PixelformatEquals(TexSurface^.format, NeededPixFmt) then
+ begin
+ TempSurface := TexSurface;
+ TexSurface := SDL_ConvertSurface(TempSurface, NeededPixFmt, SDL_SWSURFACE);
+ SDL_FreeSurface(TempSurface);
+ end;
+end;
+
+{ TTextureDatabase }
+
+procedure TTextureDatabase.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
+var
+ TextureIndex: integer;
+begin
+ TextureIndex := FindTexture(Tex.Name, Typ, Color);
+ if (TextureIndex = -1) then
+ begin
+ TextureIndex := Length(Texture);
+ SetLength(Texture, TextureIndex+1);
+
+ Texture[TextureIndex].Name := Tex.Name;
+ Texture[TextureIndex].Typ := Typ;
+ Texture[TextureIndex].Color := Color;
+ end;
+
+ if (Cache) then
+ Texture[TextureIndex].TextureCache := Tex
+ else
+ Texture[TextureIndex].Texture := Tex;
+end;
+
+function TTextureDatabase.FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
+var
+ TextureIndex: integer;
+ CurrentTexture: PTextureEntry;
+begin
+ Result := -1;
+ for TextureIndex := 0 to High(Texture) do
+ begin
+ CurrentTexture := @Texture[TextureIndex];
+ if (CurrentTexture.Name = Name) and
+ (CurrentTexture.Typ = Typ) then
+ begin
+ // colorized textures must match in their color too
+ if (CurrentTexture.Typ <> TEXTURE_TYPE_COLORIZED) or
+ (CurrentTexture.Color = Color) then
+ begin
+ Result := TextureIndex;
+ Break;
+ end;
+ end;
+ end;
+end;
+
+
+{ TTextureUnit }
+
+constructor TTextureUnit.Create;
+begin
+ inherited Create;
+ TextureDatabase := TTextureDatabase.Create;
+end;
+
+destructor TTextureUnit.Destroy;
+begin
+ TextureDatabase.Free;
+ inherited Destroy;
+end;
+
+
+procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean);
+begin
+ TextureDatabase.AddTexture(Tex, Typ, 0, Cache);
+end;
+
+procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
+begin
+ TextureDatabase.AddTexture(Tex, Typ, Color, Cache);
+end;
+
+function TTextureUnit.LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture;
+begin
+ // FIXME: what is the FromRegistry parameter supposed to do?
+ Result := LoadTexture(Identifier, Typ, Col);
+end;
+
+function TTextureUnit.LoadTexture(const Identifier: string): TTexture;
+begin
+ Result := LoadTexture(Identifier, TEXTURE_TYPE_PLAIN, 0);
+end;
+
+function TTextureUnit.LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture;
+var
+ TexSurface: PSDL_Surface;
+ MipmapSurface: PSDL_Surface;
+ newWidth, newHeight: Cardinal;
+ oldWidth, oldHeight: Cardinal;
+ ActTex: GLuint;
+begin
+ // zero texture data
+ FillChar(Result, SizeOf(Result), 0);
+
+ // load texture data into memory
+ TexSurface := LoadImage(Identifier);
+ if not assigned(TexSurface) then
+ begin
+ Log.LogError('Could not load texture: "' + Identifier +' '+ TextureTypeToStr(Typ) +'"',
+ 'TTextureUnit.LoadTexture');
+ Exit;
+ end;
+
+ // convert pixel format as needed
+ AdjustPixelFormat(TexSurface, Typ);
+
+ // adjust texture size (scale down, if necessary)
+ newWidth := TexSurface.W;
+ newHeight := TexSurface.H;
+
+ if (newWidth > Limit) then
+ newWidth := Limit;
+
+ if (newHeight > Limit) then
+ newHeight := Limit;
+
+ if (TexSurface.W > newWidth) or (TexSurface.H > newHeight) then
+ ScaleImage(TexSurface, newWidth, newHeight);
+
+ // now we might colorize the whole thing
+ if (Typ = TEXTURE_TYPE_COLORIZED) then
+ ColorizeImage(TexSurface, Col);
+
+ // save actual dimensions of our texture
+ oldWidth := newWidth;
+ oldHeight := newHeight;
+
+ // make texture dimensions be powers of 2
+ newWidth := Round(Power(2, Ceil(Log2(newWidth))));
+ newHeight := Round(Power(2, Ceil(Log2(newHeight))));
+ if (newHeight <> oldHeight) or (newWidth <> oldWidth) then
+ FitImage(TexSurface, newWidth, newHeight);
+
+ // at this point we have the image in memory...
+ // scaled to be at most 1024x1024 pixels large
+ // scaled so that dimensions are powers of 2
+ // and converted to either RGB or RGBA
+
+ // if we got a Texture of Type Plain, Transparent or Colorized,
+ // then we're done manipulating it
+ // and could now create our openGL texture from it
+
+ // prepare OpenGL texture
+ glGenTextures(1, @ActTex);
+
+ glBindTexture(GL_TEXTURE_2D, ActTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ // load data into gl texture
+ if (Typ = TEXTURE_TYPE_TRANSPARENT) or
+ (Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, newWidth, newHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, TexSurface.pixels);
+ end
+ else //if Typ = TEXTURE_TYPE_PLAIN then
+ begin
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, TexSurface.pixels);
+ end;
+
+ // setup texture struct
+ with Result do
+ begin
+ X := 0;
+ Y := 0;
+ Z := 0;
+ W := 0;
+ H := 0;
+ ScaleW := 1;
+ ScaleH := 1;
+ Rot := 0;
+ TexNum := ActTex;
+ TexW := oldWidth / newWidth;
+ TexH := oldHeight / newHeight;
+
+ Int := 1;
+ ColR := 1;
+ ColG := 1;
+ ColB := 1;
+ Alpha := 1;
+
+ // new test - default use whole texure, taking TexW and TexH as const and changing these
+ TexX1 := 0;
+ TexY1 := 0;
+ TexX2 := 1;
+ TexY2 := 1;
+
+ Name := Identifier;
+ end;
+
+ SDL_FreeSurface(TexSurface);
+end;
+
+function TTextureUnit.GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean): TTexture;
+begin
+ Result := GetTexture(Name, Typ, 0, FromCache);
+end;
+
+function TTextureUnit.GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean): TTexture;
+var
+ TextureIndex: integer;
+ CoverIndex: integer;
+begin
+ if (Name = '') then
+ begin
+ // zero texture data
+ FillChar(Result, SizeOf(Result), 0);
+ Exit;
+ end;
+
+ if (FromCache) then
+ begin
+ (*
+ // use cache texture
+ CoverIndex := Covers.FindCover(Name);
+
+ if TextureDatabase.Texture[TextureIndex].TextureCache.TexNum = 0 then
+ begin
+ // load texture
+ Covers.PrepareData(Name);
+ TextureDatabase.Texture[TextureIndex].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[CoverIndex].Width, Covers.Cover[CoverIndex].Height, 24);
+ end;
+ *)
+
+ // use texture
+ TextureIndex := TextureDatabase.FindTexture(Name, Typ, Col);
+ if (TextureIndex > -1) then
+ Result := TextureDatabase.Texture[TextureIndex].TextureCache;
+ Exit;
+ end;
+
+ // find texture entry in database
+ TextureIndex := TextureDatabase.FindTexture(Name, Typ, Col);
+ if (TextureIndex = -1) then
+ begin
+ // create texture entry in database
+ TextureIndex := Length(TextureDatabase.Texture);
+ SetLength(TextureDatabase.Texture, TextureIndex+1);
+
+ TextureDatabase.Texture[TextureIndex].Name := Name;
+ TextureDatabase.Texture[TextureIndex].Typ := Typ;
+ TextureDatabase.Texture[TextureIndex].Color := Col;
+
+ // inform database that no textures have been loaded into memory
+ TextureDatabase.Texture[TextureIndex].Texture.TexNum := 0;
+ TextureDatabase.Texture[TextureIndex].TextureCache.TexNum := 0;
+ end;
+
+ // load full texture
+ if (TextureDatabase.Texture[TextureIndex].Texture.TexNum = 0) then
+ TextureDatabase.Texture[TextureIndex].Texture := LoadTexture(false, Name, Typ, Col);
+
+ // use texture
+ Result := TextureDatabase.Texture[TextureIndex].Texture;
+end;
+
+function TTextureUnit.CreateTexture(Data: PChar; const Name: string; Width, Height: word; BitsPerPixel: byte): TTexture;
+var
+ Error: integer;
+ ActTex: GLuint;
+begin
+ glGenTextures(1, @ActTex); // ActText = new texture number
+ glBindTexture(GL_TEXTURE_2D, ActTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
+
+ {
+ if Mipmapping then
+ begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
+ if Error > 0 then
+ Log.LogError('gluBuild2DMipmaps() failed', 'TTextureUnit.CreateTexture');
+ end;
+ }
+
+ Result.X := 0;
+ Result.Y := 0;
+ Result.Z := 0;
+ Result.W := 0;
+ Result.H := 0;
+ Result.ScaleW := 1;
+ Result.ScaleH := 1;
+ Result.Rot := 0;
+ Result.TexNum := ActTex;
+ Result.TexW := 1;
+ Result.TexH := 1;
+
+ Result.Int := 1;
+ Result.ColR := 1;
+ Result.ColG := 1;
+ Result.ColB := 1;
+ Result.Alpha := 1;
+
+ // new test - default use whole texure, taking TexW and TexH as const and changing these
+ Result.TexX1 := 0;
+ Result.TexY1 := 0;
+ Result.TexX2 := 1;
+ Result.TexY2 := 1;
+
+ Result.Name := Name;
+end;
+
+procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; FromCache: boolean);
+begin
+ UnloadTexture(Name, Typ, 0, FromCache);
+end;
+
+procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean);
+var
+ T: integer;
+ TexNum: GLuint;
+begin
+ T := TextureDatabase.FindTexture(Name, Typ, Col);
+
+ if not FromCache then
+ begin
+ TexNum := TextureDatabase.Texture[T].Texture.TexNum;
+ if TexNum > 0 then
+ begin
+ glDeleteTextures(1, PGLuint(@TexNum));
+ TextureDatabase.Texture[T].Texture.TexNum := 0;
+ //Log.LogError('Unload texture no '+IntToStr(TexNum));
+ end;
+ end
+ else
+ begin
+ TexNum := TextureDatabase.Texture[T].TextureCache.TexNum;
+ if TexNum > 0 then
+ begin
+ glDeleteTextures(1, @TexNum);
+ TextureDatabase.Texture[T].TextureCache.TexNum := 0;
+ //Log.LogError('Unload texture cache no '+IntToStr(TexNum));
+ end;
+ end;
+end;
+
+(* This needs some work
+procedure TTextureUnit.FlushTextureDatabase();
+var
+ i: integer;
+ Tex: ^TTexture;
+begin
+ for i := 0 to High(TextureDatabase.Texture) do
+ begin
+ // only delete non-cached entries
+ if (TextureDatabase.Texture[i].Texture.TexNum > 0) then
+ begin
+ Tex := @TextureDatabase.Texture[i].Texture;
+ glDeleteTextures(1, PGLuint(Tex^.TexNum));
+ Tex^.TexNum := 0;
+ end;
+ end;
+end;
+*)
+
+function TextureTypeToStr(TexType: TTextureType): string;
+begin
+ Result := TextureTypeStr[TexType];
+end;
+
+function ParseTextureType(const TypeStr: string; Default: TTextureType): TTextureType;
+var
+ TexType: TTextureType;
+ UpCaseStr: string;
+begin
+ UpCaseStr := UpperCase(TypeStr);
+ for TexType := Low(TextureTypeStr) to High(TextureTypeStr) do
+ begin
+ if (UpCaseStr = UpperCase(TextureTypeStr[TexType])) then
+ begin
+ Result := TexType;
+ Exit;
+ end;
+ end;
+ Log.LogWarn('Unknown texture-type: "' + TypeStr + '"', 'ParseTextureType');
+ Result := TEXTURE_TYPE_PLAIN;
+end;
+
+end.
diff --git a/src/Classes/UThemes.pas b/src/Classes/UThemes.pas
new file mode 100644
index 00000000..fca75c24
--- /dev/null
+++ b/src/Classes/UThemes.pas
@@ -0,0 +1,2234 @@
+unit UThemes;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ ULog,
+ IniFiles,
+ SysUtils,
+ Classes,
+ UTexture;
+
+type
+ TRGB = record
+ R: single;
+ G: single;
+ B: single;
+ end;
+
+ TRGBA = record
+ R, G, B, A: Double;
+ end;
+
+ TThemeBackground = record
+ Tex: string;
+ end;
+
+ TThemeStatic = record
+ X: integer;
+ Y: integer;
+ Z: real;
+ W: integer;
+ H: integer;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Tex: string;
+ Typ: TTextureType;
+ TexX1: real;
+ TexY1: real;
+ TexX2: real;
+ TexY2: real;
+ //Reflection
+ Reflection: boolean;
+ Reflectionspacing: Real;
+ end;
+ AThemeStatic = array of TThemeStatic;
+
+ TThemeText = record
+ X: integer;
+ Y: integer;
+ W: integer;
+ Z: real;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Font: integer;
+ Size: integer;
+ Align: integer;
+ Text: string;
+ //Reflection
+ Reflection: boolean;
+ ReflectionSpacing: Real;
+ end;
+ AThemeText = array of TThemeText;
+
+ TThemeButton = record
+ Text: AThemeText;
+ X: integer;
+ Y: integer;
+ Z: Real;
+ W: integer;
+ H: integer;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Int: real;
+ DColor: string;
+ DColR: real;
+ DColG: real;
+ DColB: real;
+ DInt: real;
+ Tex: string;
+ Typ: TTextureType;
+
+ Visible: Boolean;
+
+ //Reflection Mod
+ Reflection: boolean;
+ Reflectionspacing: Real;
+ //Fade Mod
+ SelectH: integer;
+ SelectW: integer;
+ Fade: boolean;
+ FadeText: boolean;
+ DeSelectReflectionspacing : Real;
+ FadeTex: string;
+ FadeTexPos: integer;
+
+ //Button Collection Mod
+ Parent: Byte; //Number of the Button Collection this Button is assigned to. IF 0: No Assignement
+ end;
+
+ //Button Collection Mod
+ TThemeButtonCollection = record
+ Style: TThemeButton;
+ ChildCount: Byte; //No of assigned Childs
+ FirstChild: Byte; //No of Child on whose Interaction Position the Button should be
+ end;
+
+ AThemeButtonCollection = array of TThemeButtonCollection;
+ PAThemeButtonCollection = ^AThemeButtonCollection;
+
+ TThemeSelectSlide = record
+ Tex: string;
+ TexSBG: string;
+ X: integer;
+ Y: integer;
+ W: integer;
+ H: integer;
+ Z: real;
+
+ TextSize: integer;
+
+ //SBGW Mod
+ SBGW: integer;
+
+ Text: string;
+ ColR, ColG, ColB, Int: real;
+ DColR, DColG, DColB, DInt: real;
+ TColR, TColG, TColB, TInt: real;
+ TDColR, TDColG, TDColB, TDInt: real;
+ SBGColR, SBGColG, SBGColB, SBGInt: real;
+ SBGDColR, SBGDColG, SBGDColB, SBGDInt: real;
+ STColR, STColG, STColB, STInt: real;
+ STDColR, STDColG, STDColB, STDInt: real;
+ SkipX: integer;
+ end;
+
+ PThemeBasic = ^TThemeBasic;
+ TThemeBasic = class
+ Background: TThemeBackground;
+ Text: AThemeText;
+ Static: AThemeStatic;
+
+ //Button Collection Mod
+ ButtonCollection: AThemeButtonCollection;
+ end;
+
+ TThemeLoading = class(TThemeBasic)
+ StaticAnimation: TThemeStatic;
+ TextLoading: TThemeText;
+ end;
+
+ TThemeMain = class(TThemeBasic)
+ ButtonSolo: TThemeButton;
+ ButtonMulti: TThemeButton;
+ ButtonStat: TThemeButton;
+ ButtonEditor: TThemeButton;
+ ButtonOptions: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ TextDescriptionLong: TThemeText;
+ Description: array[0..5] of string;
+ DescriptionLong: array[0..5] of string;
+ end;
+
+ TThemeName = class(TThemeBasic)
+ ButtonPlayer: array[1..6] of TThemeButton;
+ end;
+
+ TThemeLevel = class(TThemeBasic)
+ ButtonEasy: TThemeButton;
+ ButtonMedium: TThemeButton;
+ ButtonHard: TThemeButton;
+ end;
+
+ TThemeSong = class(TThemeBasic)
+ TextArtist: TThemeText;
+ TextTitle: TThemeText;
+ TextNumber: TThemeText;
+
+ //Video Icon Mod
+ VideoIcon: TThemeStatic;
+
+ //Show Cat in TopLeft Mod
+ TextCat: TThemeText;
+ StaticCat: TThemeStatic;
+
+ //Cover Mod
+ Cover: record
+ Reflections: Boolean;
+ X: Integer;
+ Y: Integer;
+ Z: Integer;
+ W: Integer;
+ H: Integer;
+ Style: Integer;
+ end;
+
+ //Equalizer Mod
+ Equalizer: record
+ Visible: Boolean;
+ Direction: Boolean;
+ Alpha: real;
+ X: Integer;
+ Y: Integer;
+ Z: Real;
+ W: Integer;
+ H: Integer;
+ Space: Integer;
+ Bands: Integer;
+ Length: Integer;
+ ColR, ColG, ColB: Real;
+ end;
+
+
+ //Party and Non Party specific Statics and Texts
+ StaticParty: AThemeStatic;
+ TextParty: AThemeText;
+
+ StaticNonParty: AThemeStatic;
+ TextNonParty: AThemeText;
+
+ //Party Mode
+ StaticTeam1Joker1: TThemeStatic;
+ StaticTeam1Joker2: TThemeStatic;
+ StaticTeam1Joker3: TThemeStatic;
+ StaticTeam1Joker4: TThemeStatic;
+ StaticTeam1Joker5: TThemeStatic;
+ StaticTeam2Joker1: TThemeStatic;
+ StaticTeam2Joker2: TThemeStatic;
+ StaticTeam2Joker3: TThemeStatic;
+ StaticTeam2Joker4: TThemeStatic;
+ StaticTeam2Joker5: TThemeStatic;
+ StaticTeam3Joker1: TThemeStatic;
+ StaticTeam3Joker2: TThemeStatic;
+ StaticTeam3Joker3: TThemeStatic;
+ StaticTeam3Joker4: TThemeStatic;
+ StaticTeam3Joker5: TThemeStatic;
+
+
+ end;
+
+ TThemeSing = class(TThemeBasic)
+
+ //TimeBar mod
+ StaticTimeProgress: TThemeStatic;
+ TextTimeText : TThemeText;
+ //eoa TimeBar mod
+
+ StaticP1: TThemeStatic;
+ TextP1: TThemeText;
+ StaticP1ScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP1Score: TThemeText;
+
+ //moveable singbar mod
+ StaticP1SingBar: TThemeStatic;
+ StaticP1ThreePSingBar: TThemeStatic;
+ StaticP1TwoPSingBar: TThemeStatic;
+ StaticP2RSingBar: TThemeStatic;
+ StaticP2MSingBar: TThemeStatic;
+ StaticP3SingBar: TThemeStatic;
+ //eoa moveable singbar
+
+ //added for ps3 skin
+ //game in 2/4 player modi
+ StaticP1TwoP: TThemeStatic;
+ StaticP1TwoPScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP1TwoP: TThemeText;
+ TextP1TwoPScore: TThemeText;
+ //game in 3/6 player modi
+ StaticP1ThreeP: TThemeStatic;
+ StaticP1ThreePScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP1ThreeP: TThemeText;
+ TextP1ThreePScore: TThemeText;
+ //eoa
+
+ StaticP2R: TThemeStatic;
+ StaticP2RScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP2R: TThemeText;
+ TextP2RScore: TThemeText;
+
+ StaticP2M: TThemeStatic;
+ StaticP2MScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP2M: TThemeText;
+ TextP2MScore: TThemeText;
+
+ StaticP3R: TThemeStatic;
+ StaticP3RScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP3R: TThemeText;
+ TextP3RScore: TThemeText;
+
+ //Linebonus Translations
+ LineBonusText: Array [0..8] of String;
+
+ //Pause Popup
+ PausePopUp: TThemeStatic;
+ end;
+
+ TThemeScore = class(TThemeBasic)
+ TextArtist: TThemeText;
+ TextTitle: TThemeText;
+
+ TextArtistTitle: TThemeText;
+
+ PlayerStatic: array[1..6] of AThemeStatic;
+ PlayerTexts: array[1..6] of AThemeText;
+
+ TextName: array[1..6] of TThemeText;
+ TextScore: array[1..6] of TThemeText;
+
+ TextNotes: array[1..6] of TThemeText;
+ TextNotesScore: array[1..6] of TThemeText;
+ TextLineBonus: array[1..6] of TThemeText;
+ TextLineBonusScore: array[1..6] of TThemeText;
+ TextGoldenNotes: array[1..6] of TThemeText;
+ TextGoldenNotesScore: array[1..6] of TThemeText;
+ TextTotal: array[1..6] of TThemeText;
+ TextTotalScore: array[1..6] of TThemeText;
+
+ StaticBoxLightest: array[1..6] of TThemeStatic;
+ StaticBoxLight: array[1..6] of TThemeStatic;
+ StaticBoxDark: array[1..6] of TThemeStatic;
+
+ StaticRatings: array[1..6] of TThemeStatic;
+
+ StaticBackLevel: array[1..6] of TThemeStatic;
+ StaticBackLevelRound: array[1..6] of TThemeStatic;
+ StaticLevel: array[1..6] of TThemeStatic;
+ StaticLevelRound: array[1..6] of TThemeStatic;
+
+// Description: array[0..5] of string;}
+ end;
+
+ TThemeTop5 = class(TThemeBasic)
+ TextLevel: TThemeText;
+ TextArtistTitle: TThemeText;
+
+ StaticNumber: AThemeStatic;
+ TextNumber: AThemeText;
+ TextName: AThemeText;
+ TextScore: AThemeText;
+ end;
+
+ TThemeOptions = class(TThemeBasic)
+ ButtonGame: TThemeButton;
+ ButtonGraphics: TThemeButton;
+ ButtonSound: TThemeButton;
+ ButtonLyrics: TThemeButton;
+ ButtonThemes: TThemeButton;
+ ButtonRecord: TThemeButton;
+ ButtonAdvanced: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ Description: array[0..7] of string;
+ end;
+
+ TThemeOptionsGame = class(TThemeBasic)
+ SelectPlayers: TThemeSelectSlide;
+ SelectDifficulty: TThemeSelectSlide;
+ SelectLanguage: TThemeSelectSlide;
+ SelectTabs: TThemeSelectSlide;
+ SelectSorting: TThemeSelectSlide;
+ SelectDebug: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsGraphics = class(TThemeBasic)
+ SelectFullscreen: TThemeSelectSlide;
+ SelectResolution: TThemeSelectSlide;
+ SelectDepth: TThemeSelectSlide;
+ SelectVisualizer: TThemeSelectSlide;
+ SelectOscilloscope: TThemeSelectSlide;
+ SelectLineBonus: TThemeSelectSlide;
+ SelectMovieSize: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsSound = class(TThemeBasic)
+ SelectMicBoost: TThemeSelectSlide;
+ SelectBackgroundMusic: TThemeSelectSlide;
+ SelectClickAssist: TThemeSelectSlide;
+ SelectBeatClick: TThemeSelectSlide;
+ SelectThreshold: TThemeSelectSlide;
+ SelectSlidePreviewVolume: TThemeSelectSlide;
+ SelectSlidePreviewFading: TThemeSelectSlide;
+ SelectSlideVoicePassthrough: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsLyrics = class(TThemeBasic)
+ SelectLyricsFont: TThemeSelectSlide;
+ SelectLyricsEffect: TThemeSelectSlide;
+// SelectSolmization: TThemeSelectSlide;
+ SelectNoteLines: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsThemes = class(TThemeBasic)
+ SelectTheme: TThemeSelectSlide;
+ SelectSkin: TThemeSelectSlide;
+ SelectColor: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsRecord = class(TThemeBasic)
+ SelectSlideCard: TThemeSelectSlide;
+ SelectSlideInput: TThemeSelectSlide;
+ SelectSlideChannel: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsAdvanced = class(TThemeBasic)
+ SelectLoadAnimation: TThemeSelectSlide;
+ SelectEffectSing: TThemeSelectSlide;
+ SelectScreenFade: TThemeSelectSlide;
+ SelectLineBonus: TThemeSelectSlide;
+ SelectAskbeforeDel: TThemeSelectSlide;
+ SelectOnSongClick: TThemeSelectSlide;
+ SelectPartyPopup: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ //Error- and Check-Popup
+ TThemeError = class(TThemeBasic)
+ Button1: TThemeButton;
+ TextError: TThemeText;
+ end;
+
+ TThemeCheck = class(TThemeBasic)
+ Button1: TThemeButton;
+ Button2: TThemeButton;
+ TextCheck: TThemeText;
+ end;
+
+
+ //ScreenSong Menue
+ TThemeSongMenu = class(TThemeBasic)
+ Button1: TThemeButton;
+ Button2: TThemeButton;
+ Button3: TThemeButton;
+ Button4: TThemeButton;
+
+ SelectSlide3: TThemeSelectSlide;
+
+ TextMenu: TThemeText;
+ end;
+
+ TThemeSongJumpTo = class(TThemeBasic)
+ ButtonSearchText: TThemeButton;
+ SelectSlideType: TThemeSelectSlide;
+ TextFound: TThemeText;
+
+ //Translated Texts
+ Songsfound: String;
+ NoSongsfound: String;
+ CatText: String;
+ IType: array [0..2] of String;
+ end;
+
+ //Party Screens
+ TThemePartyNewRound = class(TThemeBasic)
+ TextRound1: TThemeText;
+ TextRound2: TThemeText;
+ TextRound3: TThemeText;
+ TextRound4: TThemeText;
+ TextRound5: TThemeText;
+ TextRound6: TThemeText;
+ TextRound7: TThemeText;
+ TextWinner1: TThemeText;
+ TextWinner2: TThemeText;
+ TextWinner3: TThemeText;
+ TextWinner4: TThemeText;
+ TextWinner5: TThemeText;
+ TextWinner6: TThemeText;
+ TextWinner7: TThemeText;
+ TextNextRound: TThemeText;
+ TextNextRoundNo: TThemeText;
+ TextNextPlayer1: TThemeText;
+ TextNextPlayer2: TThemeText;
+ TextNextPlayer3: TThemeText;
+
+ StaticRound1: TThemeStatic;
+ StaticRound2: TThemeStatic;
+ StaticRound3: TThemeStatic;
+ StaticRound4: TThemeStatic;
+ StaticRound5: TThemeStatic;
+ StaticRound6: TThemeStatic;
+ StaticRound7: TThemeStatic;
+
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ TextTeam1Players: TThemeText;
+ TextTeam2Players: TThemeText;
+ TextTeam3Players: TThemeText;
+
+ StaticTeam1: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+ StaticNextPlayer1: TThemeStatic;
+ StaticNextPlayer2: TThemeStatic;
+ StaticNextPlayer3: TThemeStatic;
+ end;
+
+ TThemePartyScore = class(TThemeBasic)
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ StaticTeam1: TThemeStatic;
+ StaticTeam1BG: TThemeStatic;
+ StaticTeam1Deco: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam2BG: TThemeStatic;
+ StaticTeam2Deco: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+ StaticTeam3BG: TThemeStatic;
+ StaticTeam3Deco: TThemeStatic;
+
+ DecoTextures: record
+ ChangeTextures: Boolean;
+
+ FirstTexture: String;
+ FirstTyp: TTextureType;
+ FirstColor: String;
+
+ SecondTexture: String;
+ SecondTyp: TTextureType;
+ SecondColor: String;
+
+ ThirdTexture: String;
+ ThirdTyp: TTextureType;
+ ThirdColor: String;
+ end;
+
+
+ TextWinner: TThemeText;
+ end;
+
+ TThemePartyWin = class(TThemeBasic)
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ StaticTeam1: TThemeStatic;
+ StaticTeam1BG: TThemeStatic;
+ StaticTeam1Deco: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam2BG: TThemeStatic;
+ StaticTeam2Deco: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+ StaticTeam3BG: TThemeStatic;
+ StaticTeam3Deco: TThemeStatic;
+
+ TextWinner: TThemeText;
+ end;
+
+ TThemePartyOptions = class(TThemeBasic)
+ SelectLevel: TThemeSelectSlide;
+ SelectPlayList: TThemeSelectSlide;
+ SelectPlayList2: TThemeSelectSlide;
+ SelectRounds: TThemeSelectSlide;
+ SelectTeams: TThemeSelectSlide;
+ SelectPlayers1: TThemeSelectSlide;
+ SelectPlayers2: TThemeSelectSlide;
+ SelectPlayers3: TThemeSelectSlide;
+
+ {ButtonNext: TThemeButton;
+ ButtonPrev: TThemeButton;}
+ end;
+
+ TThemePartyPlayer = class(TThemeBasic)
+ Team1Name: TThemeButton;
+ Player1Name: TThemeButton;
+ Player2Name: TThemeButton;
+ Player3Name: TThemeButton;
+ Player4Name: TThemeButton;
+
+ Team2Name: TThemeButton;
+ Player5Name: TThemeButton;
+ Player6Name: TThemeButton;
+ Player7Name: TThemeButton;
+ Player8Name: TThemeButton;
+
+ Team3Name: TThemeButton;
+ Player9Name: TThemeButton;
+ Player10Name: TThemeButton;
+ Player11Name: TThemeButton;
+ Player12Name: TThemeButton;
+
+ {ButtonNext: TThemeButton;
+ ButtonPrev: TThemeButton;}
+ end;
+
+ //Stats Screens
+ TThemeStatMain = class(TThemeBasic)
+ ButtonScores: TThemeButton;
+ ButtonSingers: TThemeButton;
+ ButtonSongs: TThemeButton;
+ ButtonBands: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextOverview: TThemeText;
+ end;
+
+ TThemeStatDetail = class(TThemeBasic)
+ ButtonNext: TThemeButton;
+ ButtonPrev: TThemeButton;
+ ButtonReverse: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ TextPage: TThemeText;
+ TextList: AThemeText;
+
+ Description: array[0..3] of string;
+ DescriptionR: array[0..3] of string;
+ FormatStr: array[0..3] of string;
+ PageStr: String;
+ end;
+
+ //Playlist Translations
+ TThemePlaylist = record
+ CatText: string;
+ end;
+
+ TTheme = class
+ private
+ {$IFDEF THEMESAVE}
+ ThemeIni: TIniFile;
+ {$ELSE}
+ ThemeIni: TMemIniFile;
+ {$ENDIF}
+
+ LastThemeBasic: TThemeBasic;
+ procedure create_theme_objects();
+ public
+
+ Loading: TThemeLoading;
+ Main: TThemeMain;
+ Name: TThemeName;
+ Level: TThemeLevel;
+ Song: TThemeSong;
+ Sing: TThemeSing;
+ Score: TThemeScore;
+ Top5: TThemeTop5;
+ Options: TThemeOptions;
+ OptionsGame: TThemeOptionsGame;
+ OptionsGraphics: TThemeOptionsGraphics;
+ OptionsSound: TThemeOptionsSound;
+ OptionsLyrics: TThemeOptionsLyrics;
+ OptionsThemes: TThemeOptionsThemes;
+ OptionsRecord: TThemeOptionsRecord;
+ OptionsAdvanced: TThemeOptionsAdvanced;
+ //error and check popup
+ ErrorPopup: TThemeError;
+ CheckPopup: TThemeCheck;
+ //ScreenSong extensions
+ SongMenu: TThemeSongMenu;
+ SongJumpto: TThemeSongJumpTo;
+ //Party Screens:
+ PartyNewRound: TThemePartyNewRound;
+ PartyScore: TThemePartyScore;
+ PartyWin: TThemePartyWin;
+ PartyOptions: TThemePartyOptions;
+ PartyPlayer: TThemePartyPlayer;
+
+ //Stats Screens:
+ StatMain: TThemeStatMain;
+ StatDetail: TThemeStatDetail;
+
+ Playlist: TThemePlaylist;
+
+ ILevel: array[0..2] of String;
+
+ constructor Create(FileName: string); overload; // Initialize theme system
+ constructor Create(FileName: string; Color: integer); overload; // Initialize theme system with color
+ function LoadTheme(FileName: string; sColor: integer): boolean; // Load some theme settings from file
+
+ procedure LoadColors;
+
+ procedure ThemeLoadBasic(Theme: TThemeBasic; Name: string);
+ procedure ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
+ procedure ThemeLoadText(var ThemeText: TThemeText; Name: string);
+ procedure ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
+ procedure ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
+ procedure ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
+ procedure ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection = nil);
+ procedure ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
+ procedure ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string);
+ procedure ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
+
+ procedure ThemeSave(FileName: string);
+ procedure ThemeSaveBasic(Theme: TThemeBasic; Name: string);
+ procedure ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
+ procedure ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
+ procedure ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
+ procedure ThemeSaveText(ThemeText: TThemeText; Name: string);
+ procedure ThemeSaveTexts(ThemeText: AThemeText; Name: string);
+ procedure ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
+
+ end;
+
+ TColor = record
+ Name: string;
+ RGB: TRGB;
+ end;
+
+function ColorExists(Name: string): integer;
+procedure LoadColor(var R, G, B: real; ColorName: string);
+function GetSystemColor(Color: integer): TRGB;
+function ColorSqrt(RGB: TRGB): TRGB;
+
+var
+ //Skin: TSkin;
+ Theme: TTheme;
+ Color: array of TColor;
+
+implementation
+
+uses
+ UCommon,
+ ULanguage,
+ USkins,
+ UIni;
+
+constructor TTheme.Create(FileName: string);
+begin
+ Create(FileName, 0);
+end;
+
+constructor TTheme.Create(FileName: string; Color: integer);
+begin
+ inherited Create();
+
+ Loading := TThemeLoading.Create;
+ Main := TThemeMain.Create;
+ Name := TThemeName.Create;
+ Level := TThemeLevel.Create;
+ Song := TThemeSong.Create;
+ Sing := TThemeSing.Create;
+ Score := TThemeScore.Create;
+ Top5 := TThemeTop5.Create;
+ Options := TThemeOptions.Create;
+ OptionsGame := TThemeOptionsGame.Create;
+ OptionsGraphics := TThemeOptionsGraphics.Create;
+ OptionsSound := TThemeOptionsSound.Create;
+ OptionsLyrics := TThemeOptionsLyrics.Create;
+ OptionsThemes := TThemeOptionsThemes.Create;
+ OptionsRecord := TThemeOptionsRecord.Create;
+ OptionsAdvanced := TThemeOptionsAdvanced.Create;
+
+ ErrorPopup := TThemeError.Create;
+ CheckPopup := TThemeCheck.Create;
+
+ SongMenu := TThemeSongMenu.Create;
+ SongJumpto := TThemeSongJumpto.Create;
+ //Party Screens
+ PartyNewRound := TThemePartyNewRound.Create;
+ PartyWin := TThemePartyWin.Create;
+ PartyScore := TThemePartyScore.Create;
+ PartyOptions := TThemePartyOptions.Create;
+ PartyPlayer := TThemePartyPlayer.Create;
+
+ //Stats Screens:
+ StatMain := TThemeStatMain.Create;
+ StatDetail := TThemeStatDetail.Create;
+
+ LoadTheme(FileName, Color);
+
+end;
+
+
+function TTheme.LoadTheme(FileName: string; sColor: integer): boolean;
+var
+ I: integer;
+ Path: string;
+begin
+ Result := false;
+
+ create_theme_objects();
+
+ Log.LogStatus('Loading: '+ FileName, 'TTheme.LoadTheme');
+
+ FileName := AdaptFilePaths( FileName );
+
+ if not FileExists(FileName) then
+ begin
+ Log.LogError('Theme does not exist ('+ FileName +')', 'TTheme.LoadTheme');
+ end;
+
+ if FileExists(FileName) then
+ begin
+ Result := true;
+
+ {$IFDEF THEMESAVE}
+ ThemeIni := TIniFile.Create(FileName);
+ {$ELSE}
+ ThemeIni := TMemIniFile.Create(FileName);
+ {$ENDIF}
+
+ if ThemeIni.ReadString('Theme', 'Name', '') <> '' then
+ begin
+
+ {Skin.SkinName := ThemeIni.ReadString('Theme', 'Name', 'Singstar');
+ Skin.SkinPath := 'Skins\' + Skin.SkinName + '\';
+ Skin.SkinReg := false; }
+ Skin.Color := sColor;
+
+ Skin.LoadSkin(ISkin[Ini.SkinNo]);
+
+ LoadColors;
+
+// ThemeIni.Free;
+// ThemeIni := TIniFile.Create('Themes\Singstar\Main.ini');
+
+ // Loading
+ ThemeLoadBasic(Loading, 'Loading');
+ ThemeLoadText(Loading.TextLoading, 'LoadingTextLoading');
+ ThemeLoadStatic(Loading.StaticAnimation, 'LoadingStaticAnimation');
+
+ // Main
+ ThemeLoadBasic(Main, 'Main');
+
+ ThemeLoadText(Main.TextDescription, 'MainTextDescription');
+ ThemeLoadText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
+ ThemeLoadButton(Main.ButtonSolo, 'MainButtonSolo');
+ ThemeLoadButton(Main.ButtonMulti, 'MainButtonMulti');
+ ThemeLoadButton(Main.ButtonStat, 'MainButtonStats');
+ ThemeLoadButton(Main.ButtonEditor, 'MainButtonEditor');
+ ThemeLoadButton(Main.ButtonOptions, 'MainButtonOptions');
+ ThemeLoadButton(Main.ButtonExit, 'MainButtonExit');
+
+ //Main Desc Text Translation Start
+
+ Main.Description[0] := Language.Translate('SING_SING');
+ Main.DescriptionLong[0] := Language.Translate('SING_SING_DESC');
+ Main.Description[1] := Language.Translate('SING_MULTI');
+ Main.DescriptionLong[1] := Language.Translate('SING_MULTI_DESC');
+ Main.Description[2] := Language.Translate('SING_STATS');
+ Main.DescriptionLong[2] := Language.Translate('SING_STATS_DESC');
+ Main.Description[3] := Language.Translate('SING_EDITOR');
+ Main.DescriptionLong[3] := Language.Translate('SING_EDITOR_DESC');
+ Main.Description[4] := Language.Translate('SING_GAME_OPTIONS');
+ Main.DescriptionLong[4] := Language.Translate('SING_GAME_OPTIONS_DESC');
+ Main.Description[5] := Language.Translate('SING_EXIT');
+ Main.DescriptionLong[5] := Language.Translate('SING_EXIT_DESC');
+
+ //Main Desc Text Translation End
+
+ Main.TextDescription.Text := Main.Description[0];
+ Main.TextDescriptionLong.Text := Main.DescriptionLong[0];
+
+ // Name
+ ThemeLoadBasic(Name, 'Name');
+
+ for I := 1 to 6 do
+ ThemeLoadButton(Name.ButtonPlayer[I], 'NameButtonPlayer'+IntToStr(I));
+
+ // Level
+ ThemeLoadBasic(Level, 'Level');
+
+ ThemeLoadButton(Level.ButtonEasy, 'LevelButtonEasy');
+ ThemeLoadButton(Level.ButtonMedium, 'LevelButtonMedium');
+ ThemeLoadButton(Level.ButtonHard, 'LevelButtonHard');
+
+
+ // Song
+ ThemeLoadBasic(Song, 'Song');
+
+ ThemeLoadText(Song.TextArtist, 'SongTextArtist');
+ ThemeLoadText(Song.TextTitle, 'SongTextTitle');
+ ThemeLoadText(Song.TextNumber, 'SongTextNumber');
+
+ //Video Icon Mod
+ ThemeLoadStatic(Song.VideoIcon, 'SongVideoIcon');
+
+ //Show Cat in TopLeft Mod
+ ThemeLoadStatic(Song.StaticCat, 'SongStaticCat');
+ ThemeLoadText(Song.TextCat, 'SongTextCat');
+
+ //Load Cover Pos and Size from Theme Mod
+ Song.Cover.X := ThemeIni.ReadInteger('SongCover', 'X', 300);
+ Song.Cover.Y := ThemeIni.ReadInteger('SongCover', 'Y', 190);
+ Song.Cover.W := ThemeIni.ReadInteger('SongCover', 'W', 300);
+ Song.Cover.H := ThemeIni.ReadInteger('SongCover', 'H', 200);
+ Song.Cover.Style := ThemeIni.ReadInteger('SongCover', 'Style', 4);
+ Song.Cover.Reflections := (ThemeIni.ReadInteger('SongCover', 'Reflections', 0) = 1);
+ //Load Cover Pos and Size from Theme Mod End
+
+ //Load Equalizer Pos and Size from Theme Mod
+ Song.Equalizer.Visible := (ThemeIni.ReadInteger('SongEqualizer', 'Visible', 0) = 1);
+ Song.Equalizer.Direction := (ThemeIni.ReadInteger('SongEqualizer', 'Direction', 0) = 1);
+ Song.Equalizer.Alpha := ThemeIni.ReadInteger('SongEqualizer', 'Alpha', 1);
+ Song.Equalizer.Space := ThemeIni.ReadInteger('SongEqualizer', 'Space', 1);
+ Song.Equalizer.X := ThemeIni.ReadInteger('SongEqualizer', 'X', 0);
+ Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 0);
+ Song.Equalizer.Z := ThemeIni.ReadInteger('SongEqualizer', 'Z', 1);
+ Song.Equalizer.W := ThemeIni.ReadInteger('SongEqualizer', 'PieceW', 8);
+ Song.Equalizer.H := ThemeIni.ReadInteger('SongEqualizer', 'PieceH', 8);
+ Song.Equalizer.Bands := ThemeIni.ReadInteger('SongEqualizer', 'Bands', 5);
+ Song.Equalizer.Length := ThemeIni.ReadInteger('SongEqualizer', 'Length', 12);
+
+ //Color
+ I := ColorExists(ThemeIni.ReadString('SongEqualizer', 'Color', 'Black'));
+ if I >= 0 then begin
+ Song.Equalizer.ColR := Color[I].RGB.R;
+ Song.Equalizer.ColG := Color[I].RGB.G;
+ Song.Equalizer.ColB := Color[I].RGB.B;
+ end
+ else begin
+ Song.Equalizer.ColR := 0;
+ Song.Equalizer.ColG := 0;
+ Song.Equalizer.ColB := 0;
+ end;
+ //Load Equalizer Pos and Size from Theme Mod End
+
+ //Party and Non Party specific Statics and Texts
+ ThemeLoadStatics (Song.StaticParty, 'SongStaticParty');
+ ThemeLoadTexts (Song.TextParty, 'SongTextParty');
+
+ ThemeLoadStatics (Song.StaticNonParty, 'SongStaticNonParty');
+ ThemeLoadTexts (Song.TextNonParty, 'SongTextNonParty');
+
+ //Party Mode
+ ThemeLoadStatic(Song.StaticTeam1Joker1, 'SongStaticTeam1Joker1');
+ ThemeLoadStatic(Song.StaticTeam1Joker2, 'SongStaticTeam1Joker2');
+ ThemeLoadStatic(Song.StaticTeam1Joker3, 'SongStaticTeam1Joker3');
+ ThemeLoadStatic(Song.StaticTeam1Joker4, 'SongStaticTeam1Joker4');
+ ThemeLoadStatic(Song.StaticTeam1Joker5, 'SongStaticTeam1Joker5');
+
+ ThemeLoadStatic(Song.StaticTeam2Joker1, 'SongStaticTeam2Joker1');
+ ThemeLoadStatic(Song.StaticTeam2Joker2, 'SongStaticTeam2Joker2');
+ ThemeLoadStatic(Song.StaticTeam2Joker3, 'SongStaticTeam2Joker3');
+ ThemeLoadStatic(Song.StaticTeam2Joker4, 'SongStaticTeam2Joker4');
+ ThemeLoadStatic(Song.StaticTeam2Joker5, 'SongStaticTeam2Joker5');
+
+ ThemeLoadStatic(Song.StaticTeam3Joker1, 'SongStaticTeam3Joker1');
+ ThemeLoadStatic(Song.StaticTeam3Joker2, 'SongStaticTeam3Joker2');
+ ThemeLoadStatic(Song.StaticTeam3Joker3, 'SongStaticTeam3Joker3');
+ ThemeLoadStatic(Song.StaticTeam3Joker4, 'SongStaticTeam3Joker4');
+ ThemeLoadStatic(Song.StaticTeam3Joker5, 'SongStaticTeam3Joker5');
+
+
+ // Sing
+ ThemeLoadBasic(Sing, 'Sing');
+
+ //TimeBar mod
+ ThemeLoadStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
+ ThemeLoadText(Sing.TextTimeText, 'SingTimeText');
+ //eoa TimeBar mod
+
+ //moveable singbar mod
+ ThemeLoadStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
+ ThemeLoadStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
+ ThemeLoadStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
+ ThemeLoadStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
+ ThemeLoadStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
+ ThemeLoadStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
+ //eoa moveable singbar
+
+ ThemeLoadStatic(Sing.StaticP1, 'SingP1Static');
+ ThemeLoadText(Sing.TextP1, 'SingP1Text');
+ ThemeLoadStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
+ ThemeLoadText(Sing.TextP1Score, 'SingP1TextScore');
+ //Added for ps3 skin
+ //This one is shown in 2/4P mode
+ //if it exists, otherwise the one Player equivaltents are used
+ if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
+ begin
+ ThemeLoadStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
+ ThemeLoadText(Sing.TextP1TwoP, 'SingP1TwoPText');
+ ThemeLoadStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
+ ThemeLoadText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
+ end
+ else
+ begin
+ Sing.StaticP1TwoP := Sing.StaticP1;
+ Sing.TextP1TwoP := Sing.TextP1;
+ Sing.StaticP1TwoPScoreBG := Sing.StaticP1ScoreBG;
+ Sing.TextP1TwoPScore := Sing.TextP1Score;
+ end;
+
+ //This one is shown in 3/6P mode
+ //if it exists, otherwise the one Player equivaltents are used
+ if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
+ begin
+ ThemeLoadStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
+ ThemeLoadText(Sing.TextP1ThreeP, 'SingP1ThreePText');
+ ThemeLoadStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
+ ThemeLoadText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
+ end
+ else
+ begin
+ Sing.StaticP1ThreeP := Sing.StaticP1;
+ Sing.TextP1ThreeP := Sing.TextP1;
+ Sing.StaticP1ThreePScoreBG := Sing.StaticP1ScoreBG;
+ Sing.TextP1ThreePScore := Sing.TextP1Score;
+ end;
+ //eoa
+ ThemeLoadStatic(Sing.StaticP2R, 'SingP2RStatic');
+ ThemeLoadText(Sing.TextP2R, 'SingP2RText');
+ ThemeLoadStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
+ ThemeLoadText(Sing.TextP2RScore, 'SingP2RTextScore');
+
+ ThemeLoadStatic(Sing.StaticP2M, 'SingP2MStatic');
+ ThemeLoadText(Sing.TextP2M, 'SingP2MText');
+ ThemeLoadStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
+ ThemeLoadText(Sing.TextP2MScore, 'SingP2MTextScore');
+
+ ThemeLoadStatic(Sing.StaticP3R, 'SingP3RStatic');
+ ThemeLoadText(Sing.TextP3R, 'SingP3RText');
+ ThemeLoadStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
+ ThemeLoadText(Sing.TextP3RScore, 'SingP3RTextScore');
+
+ //Line Bonus Texts
+ Sing.LineBonusText[0] := Language.Translate('POPUP_AWFUL');
+ Sing.LineBonusText[1] := Sing.LineBonusText[0];
+ Sing.LineBonusText[2] := Language.Translate('POPUP_POOR');
+ Sing.LineBonusText[3] := Language.Translate('POPUP_BAD');
+ Sing.LineBonusText[4] := Language.Translate('POPUP_NOTBAD');
+ Sing.LineBonusText[5] := Language.Translate('POPUP_GOOD');
+ Sing.LineBonusText[6] := Language.Translate('POPUP_GREAT');
+ Sing.LineBonusText[7] := Language.Translate('POPUP_AWESOME');
+ Sing.LineBonusText[8] := Language.Translate('POPUP_PERFECT');
+
+ //PausePopup
+ ThemeLoadStatic(Sing.PausePopUp, 'PausePopUpStatic');
+
+ // Score
+ ThemeLoadBasic(Score, 'Score');
+
+ ThemeLoadText(Score.TextArtist, 'ScoreTextArtist');
+ ThemeLoadText(Score.TextTitle, 'ScoreTextTitle');
+ ThemeLoadText(Score.TextArtistTitle, 'ScoreTextArtistTitle');
+
+ for I := 1 to 6 do begin
+ ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
+ ThemeLoadTexts(Score.PlayerTexts[I], 'ScorePlayer' + IntToStr(I) + 'Text');
+
+ ThemeLoadText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
+ ThemeLoadText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
+ ThemeLoadText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
+ ThemeLoadText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
+ ThemeLoadText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
+ ThemeLoadText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
+ ThemeLoadText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
+ ThemeLoadText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
+ ThemeLoadText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
+ ThemeLoadText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
+
+ ThemeLoadStatic(Score.StaticBoxLightest[I], 'ScoreStaticBoxLightest' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBoxLight[I], 'ScoreStaticBoxLight' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBoxDark[I], 'ScoreStaticBoxDark' + IntToStr(I));
+
+ ThemeLoadStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
+
+ ThemeLoadStatic(Score.StaticRatings[I], 'ScoreStaticRatingPicture' + IntToStr(I));
+ end;
+
+ // Top5
+ ThemeLoadBasic(Top5, 'Top5');
+
+ ThemeLoadText(Top5.TextLevel, 'Top5TextLevel');
+ ThemeLoadText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
+ ThemeLoadStatics(Top5.StaticNumber, 'Top5StaticNumber');
+ ThemeLoadTexts(Top5.TextNumber, 'Top5TextNumber');
+ ThemeLoadTexts(Top5.TextName, 'Top5TextName');
+ ThemeLoadTexts(Top5.TextScore, 'Top5TextScore');
+
+ // Options
+ ThemeLoadBasic(Options, 'Options');
+
+ ThemeLoadButton(Options.ButtonGame, 'OptionsButtonGame');
+ ThemeLoadButton(Options.ButtonGraphics, 'OptionsButtonGraphics');
+ ThemeLoadButton(Options.ButtonSound, 'OptionsButtonSound');
+ ThemeLoadButton(Options.ButtonLyrics, 'OptionsButtonLyrics');
+ ThemeLoadButton(Options.ButtonThemes, 'OptionsButtonThemes');
+ ThemeLoadButton(Options.ButtonRecord, 'OptionsButtonRecord');
+ ThemeLoadButton(Options.ButtonAdvanced, 'OptionsButtonAdvanced');
+ ThemeLoadButton(Options.ButtonExit, 'OptionsButtonExit');
+
+ Options.Description[0] := Language.Translate('SING_OPTIONS_GAME_DESC');
+ Options.Description[1] := Language.Translate('SING_OPTIONS_GRAPHICS_DESC');
+ Options.Description[2] := Language.Translate('SING_OPTIONS_SOUND_DESC');
+ Options.Description[3] := Language.Translate('SING_OPTIONS_LYRICS_DESC');
+ Options.Description[4] := Language.Translate('SING_OPTIONS_THEMES_DESC');
+ Options.Description[5] := Language.Translate('SING_OPTIONS_RECORD_DESC');
+ Options.Description[6] := Language.Translate('SING_OPTIONS_ADVANCED_DESC');
+ Options.Description[7] := Language.Translate('SING_OPTIONS_EXIT');
+
+ ThemeLoadText(Options.TextDescription, 'OptionsTextDescription');
+ Options.TextDescription.Text := Options.Description[0];
+
+ // Options Game
+ ThemeLoadBasic(OptionsGame, 'OptionsGame');
+
+ ThemeLoadSelectSlide(OptionsGame.SelectPlayers, 'OptionsGameSelectPlayers');
+ ThemeLoadSelectSlide(OptionsGame.SelectDifficulty, 'OptionsGameSelectDifficulty');
+ ThemeLoadSelectSlide(OptionsGame.SelectLanguage, 'OptionsGameSelectSlideLanguage');
+ ThemeLoadSelectSlide(OptionsGame.SelectTabs, 'OptionsGameSelectTabs');
+ ThemeLoadSelectSlide(OptionsGame.SelectSorting, 'OptionsGameSelectSlideSorting');
+ ThemeLoadSelectSlide(OptionsGame.SelectDebug, 'OptionsGameSelectDebug');
+ ThemeLoadButton(OptionsGame.ButtonExit, 'OptionsGameButtonExit');
+
+ // Options Graphics
+ ThemeLoadBasic(OptionsGraphics, 'OptionsGraphics');
+
+ ThemeLoadSelectSlide(OptionsGraphics.SelectFullscreen, 'OptionsGraphicsSelectFullscreen');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectResolution, 'OptionsGraphicsSelectSlideResolution');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectDepth, 'OptionsGraphicsSelectDepth');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectVisualizer, 'OptionsGraphicsSelectVisualizer');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectOscilloscope, 'OptionsGraphicsSelectOscilloscope');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectLineBonus, 'OptionsGraphicsSelectLineBonus');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectMovieSize, 'OptionsGraphicsSelectMovieSize');
+ ThemeLoadButton(OptionsGraphics.ButtonExit, 'OptionsGraphicsButtonExit');
+
+ // Options Sound
+ ThemeLoadBasic(OptionsSound, 'OptionsSound');
+
+ ThemeLoadSelectSlide(OptionsSound.SelectBackgroundMusic, 'OptionsSoundSelectBackgroundMusic');
+ ThemeLoadSelectSlide(OptionsSound.SelectMicBoost, 'OptionsSoundSelectMicBoost');
+ ThemeLoadSelectSlide(OptionsSound.SelectClickAssist, 'OptionsSoundSelectClickAssist');
+ ThemeLoadSelectSlide(OptionsSound.SelectBeatClick, 'OptionsSoundSelectBeatClick');
+ ThemeLoadSelectSlide(OptionsSound.SelectThreshold, 'OptionsSoundSelectThreshold');
+ //Song Preview
+ ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewVolume, 'OptionsSoundSelectSlidePreviewVolume');
+ ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewFading, 'OptionsSoundSelectSlidePreviewFading');
+ ThemeLoadSelectSlide(OptionsSound.SelectSlideVoicePassthrough, 'OptionsSoundSelectVoicePassthrough');
+
+ ThemeLoadButton(OptionsSound.ButtonExit, 'OptionsSoundButtonExit');
+
+ // Options Lyrics
+ ThemeLoadBasic(OptionsLyrics, 'OptionsLyrics');
+
+ ThemeLoadSelectSlide(OptionsLyrics.SelectLyricsFont, 'OptionsLyricsSelectLyricsFont');
+ ThemeLoadSelectSlide(OptionsLyrics.SelectLyricsEffect, 'OptionsLyricsSelectLyricsEffect');
+ //ThemeLoadSelectSlide(OptionsLyrics.SelectSolmization, 'OptionsLyricsSelectSolmization');
+ ThemeLoadSelectSlide(OptionsLyrics.SelectNoteLines, 'OptionsLyricsSelectNoteLines');
+ ThemeLoadButton(OptionsLyrics.ButtonExit, 'OptionsLyricsButtonExit');
+
+ // Options Themes
+ ThemeLoadBasic(OptionsThemes, 'OptionsThemes');
+
+ ThemeLoadSelectSlide(OptionsThemes.SelectTheme, 'OptionsThemesSelectTheme');
+ ThemeLoadSelectSlide(OptionsThemes.SelectSkin, 'OptionsThemesSelectSkin');
+ ThemeLoadSelectSlide(OptionsThemes.SelectColor, 'OptionsThemesSelectColor');
+ ThemeLoadButton(OptionsThemes.ButtonExit, 'OptionsThemesButtonExit');
+
+ // Options Record
+ ThemeLoadBasic(OptionsRecord, 'OptionsRecord');
+
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideCard, 'OptionsRecordSelectSlideCard');
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideInput, 'OptionsRecordSelectSlideInput');
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideChannel, 'OptionsRecordSelectSlideChannel');
+ ThemeLoadButton(OptionsRecord.ButtonExit, 'OptionsRecordButtonExit');
+
+ //Options Advanced
+ ThemeLoadBasic(OptionsAdvanced, 'OptionsAdvanced');
+
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectLoadAnimation, 'OptionsAdvancedSelectLoadAnimation');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectScreenFade, 'OptionsAdvancedSelectScreenFade');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectEffectSing, 'OptionsAdvancedSelectEffectSing');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectLineBonus, 'OptionsAdvancedSelectLineBonus');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectOnSongClick, 'OptionsAdvancedSelectSlideOnSongClick');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectAskbeforeDel, 'OptionsAdvancedSelectAskbeforeDel');
+ ThemeLoadSelectSlide(OptionsAdvanced.SelectPartyPopup, 'OptionsAdvancedSelectPartyPopup');
+ ThemeLoadButton (OptionsAdvanced.ButtonExit, 'OptionsAdvancedButtonExit');
+
+ //error and check popup
+ ThemeLoadBasic (ErrorPopup, 'ErrorPopup');
+ ThemeLoadButton(ErrorPopup.Button1, 'ErrorPopupButton1');
+ ThemeLoadText (ErrorPopup.TextError,'ErrorPopupText');
+ ThemeLoadBasic (CheckPopup, 'CheckPopup');
+ ThemeLoadButton(CheckPopup.Button1, 'CheckPopupButton1');
+ ThemeLoadButton(CheckPopup.Button2, 'CheckPopupButton2');
+ ThemeLoadText(CheckPopup.TextCheck , 'CheckPopupText');
+
+ //Song Menu
+ ThemeLoadBasic (SongMenu, 'SongMenu');
+ ThemeLoadButton(SongMenu.Button1, 'SongMenuButton1');
+ ThemeLoadButton(SongMenu.Button2, 'SongMenuButton2');
+ ThemeLoadButton(SongMenu.Button3, 'SongMenuButton3');
+ ThemeLoadButton(SongMenu.Button4, 'SongMenuButton4');
+ ThemeLoadSelectSlide(SongMenu.SelectSlide3, 'SongMenuSelectSlide3');
+
+ ThemeLoadText(SongMenu.TextMenu, 'SongMenuTextMenu');
+
+ //Song Jumpto
+ ThemeLoadBasic (SongJumpto, 'SongJumpto');
+ ThemeLoadButton(SongJumpto.ButtonSearchText, 'SongJumptoButtonSearchText');
+ ThemeLoadSelectSlide(SongJumpto.SelectSlideType, 'SongJumptoSelectSlideType');
+ ThemeLoadText(SongJumpto.TextFound, 'SongJumptoTextFound');
+ //Translations
+ SongJumpto.IType[0] := Language.Translate('SONG_JUMPTO_TYPE1');
+ SongJumpto.IType[1] := Language.Translate('SONG_JUMPTO_TYPE2');
+ SongJumpto.IType[2] := Language.Translate('SONG_JUMPTO_TYPE3');
+ SongJumpto.SongsFound := Language.Translate('SONG_JUMPTO_SONGSFOUND');
+ SongJumpto.NoSongsFound := Language.Translate('SONG_JUMPTO_NOSONGSFOUND');
+ SongJumpto.CatText := Language.Translate('SONG_JUMPTO_CATTEXT');
+
+ //Party Screens:
+ //Party NewRound
+ ThemeLoadBasic(PartyNewRound, 'PartyNewRound');
+
+ ThemeLoadText (PartyNewRound.TextRound1, 'PartyNewRoundTextRound1');
+ ThemeLoadText (PartyNewRound.TextRound2, 'PartyNewRoundTextRound2');
+ ThemeLoadText (PartyNewRound.TextRound3, 'PartyNewRoundTextRound3');
+ ThemeLoadText (PartyNewRound.TextRound4, 'PartyNewRoundTextRound4');
+ ThemeLoadText (PartyNewRound.TextRound5, 'PartyNewRoundTextRound5');
+ ThemeLoadText (PartyNewRound.TextRound6, 'PartyNewRoundTextRound6');
+ ThemeLoadText (PartyNewRound.TextRound7, 'PartyNewRoundTextRound7');
+ ThemeLoadText (PartyNewRound.TextWinner1, 'PartyNewRoundTextWinner1');
+ ThemeLoadText (PartyNewRound.TextWinner2, 'PartyNewRoundTextWinner2');
+ ThemeLoadText (PartyNewRound.TextWinner3, 'PartyNewRoundTextWinner3');
+ ThemeLoadText (PartyNewRound.TextWinner4, 'PartyNewRoundTextWinner4');
+ ThemeLoadText (PartyNewRound.TextWinner5, 'PartyNewRoundTextWinner5');
+ ThemeLoadText (PartyNewRound.TextWinner6, 'PartyNewRoundTextWinner6');
+ ThemeLoadText (PartyNewRound.TextWinner7, 'PartyNewRoundTextWinner7');
+ ThemeLoadText (PartyNewRound.TextNextRound, 'PartyNewRoundTextNextRound');
+ ThemeLoadText (PartyNewRound.TextNextRoundNo, 'PartyNewRoundTextNextRoundNo');
+ ThemeLoadText (PartyNewRound.TextNextPlayer1, 'PartyNewRoundTextNextPlayer1');
+ ThemeLoadText (PartyNewRound.TextNextPlayer2, 'PartyNewRoundTextNextPlayer2');
+ ThemeLoadText (PartyNewRound.TextNextPlayer3, 'PartyNewRoundTextNextPlayer3');
+
+ ThemeLoadStatic (PartyNewRound.StaticRound1, 'PartyNewRoundStaticRound1');
+ ThemeLoadStatic (PartyNewRound.StaticRound2, 'PartyNewRoundStaticRound2');
+ ThemeLoadStatic (PartyNewRound.StaticRound3, 'PartyNewRoundStaticRound3');
+ ThemeLoadStatic (PartyNewRound.StaticRound4, 'PartyNewRoundStaticRound4');
+ ThemeLoadStatic (PartyNewRound.StaticRound5, 'PartyNewRoundStaticRound5');
+ ThemeLoadStatic (PartyNewRound.StaticRound6, 'PartyNewRoundStaticRound6');
+ ThemeLoadStatic (PartyNewRound.StaticRound7, 'PartyNewRoundStaticRound7');
+
+ ThemeLoadText (PartyNewRound.TextScoreTeam1, 'PartyNewRoundTextScoreTeam1');
+ ThemeLoadText (PartyNewRound.TextScoreTeam2, 'PartyNewRoundTextScoreTeam2');
+ ThemeLoadText (PartyNewRound.TextScoreTeam3, 'PartyNewRoundTextScoreTeam3');
+ ThemeLoadText (PartyNewRound.TextNameTeam1, 'PartyNewRoundTextNameTeam1');
+ ThemeLoadText (PartyNewRound.TextNameTeam2, 'PartyNewRoundTextNameTeam2');
+ ThemeLoadText (PartyNewRound.TextNameTeam3, 'PartyNewRoundTextNameTeam3');
+
+ ThemeLoadText (PartyNewRound.TextTeam1Players, 'PartyNewRoundTextTeam1Players');
+ ThemeLoadText (PartyNewRound.TextTeam2Players, 'PartyNewRoundTextTeam2Players');
+ ThemeLoadText (PartyNewRound.TextTeam3Players, 'PartyNewRoundTextTeam3Players');
+
+ ThemeLoadStatic (PartyNewRound.StaticTeam1, 'PartyNewRoundStaticTeam1');
+ ThemeLoadStatic (PartyNewRound.StaticTeam2, 'PartyNewRoundStaticTeam2');
+ ThemeLoadStatic (PartyNewRound.StaticTeam3, 'PartyNewRoundStaticTeam3');
+ ThemeLoadStatic (PartyNewRound.StaticNextPlayer1, 'PartyNewRoundStaticNextPlayer1');
+ ThemeLoadStatic (PartyNewRound.StaticNextPlayer2, 'PartyNewRoundStaticNextPlayer2');
+ ThemeLoadStatic (PartyNewRound.StaticNextPlayer3, 'PartyNewRoundStaticNextPlayer3');
+
+ //Party Score
+ ThemeLoadBasic(PartyScore, 'PartyScore');
+
+ ThemeLoadText (PartyScore.TextScoreTeam1, 'PartyScoreTextScoreTeam1');
+ ThemeLoadText (PartyScore.TextScoreTeam2, 'PartyScoreTextScoreTeam2');
+ ThemeLoadText (PartyScore.TextScoreTeam3, 'PartyScoreTextScoreTeam3');
+ ThemeLoadText (PartyScore.TextNameTeam1, 'PartyScoreTextNameTeam1');
+ ThemeLoadText (PartyScore.TextNameTeam2, 'PartyScoreTextNameTeam2');
+ ThemeLoadText (PartyScore.TextNameTeam3, 'PartyScoreTextNameTeam3');
+
+ ThemeLoadStatic (PartyScore.StaticTeam1, 'PartyScoreStaticTeam1');
+ ThemeLoadStatic (PartyScore.StaticTeam1BG, 'PartyScoreStaticTeam1BG');
+ ThemeLoadStatic (PartyScore.StaticTeam1Deco, 'PartyScoreStaticTeam1Deco');
+ ThemeLoadStatic (PartyScore.StaticTeam2, 'PartyScoreStaticTeam2');
+ ThemeLoadStatic (PartyScore.StaticTeam2BG, 'PartyScoreStaticTeam2BG');
+ ThemeLoadStatic (PartyScore.StaticTeam2Deco, 'PartyScoreStaticTeam2Deco');
+ ThemeLoadStatic (PartyScore.StaticTeam3, 'PartyScoreStaticTeam3');
+ ThemeLoadStatic (PartyScore.StaticTeam3BG, 'PartyScoreStaticTeam3BG');
+ ThemeLoadStatic (PartyScore.StaticTeam3Deco, 'PartyScoreStaticTeam3Deco');
+
+ //Load Party Score DecoTextures Object
+ PartyScore.DecoTextures.ChangeTextures := (ThemeIni.ReadInteger('PartyScoreDecoTextures', 'ChangeTextures', 0) = 1);
+ PartyScore.DecoTextures.FirstTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTexture', '');
+ PartyScore.DecoTextures.FirstTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTyp', ''), TEXTURE_TYPE_COLORIZED);
+ PartyScore.DecoTextures.FirstColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstColor', 'Black');
+
+ PartyScore.DecoTextures.SecondTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTexture', '');
+ PartyScore.DecoTextures.SecondTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTyp', ''), TEXTURE_TYPE_COLORIZED);
+ PartyScore.DecoTextures.SecondColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondColor', 'Black');
+
+ PartyScore.DecoTextures.ThirdTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTexture', '');
+ PartyScore.DecoTextures.ThirdTyp := ParseTextureType(ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTyp', ''), TEXTURE_TYPE_COLORIZED);
+ PartyScore.DecoTextures.ThirdColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdColor', 'Black');
+
+ ThemeLoadText (PartyScore.TextWinner, 'PartyScoreTextWinner');
+
+ //Party Win
+ ThemeLoadBasic(PartyWin, 'PartyWin');
+
+ ThemeLoadText (PartyWin.TextScoreTeam1, 'PartyWinTextScoreTeam1');
+ ThemeLoadText (PartyWin.TextScoreTeam2, 'PartyWinTextScoreTeam2');
+ ThemeLoadText (PartyWin.TextScoreTeam3, 'PartyWinTextScoreTeam3');
+ ThemeLoadText (PartyWin.TextNameTeam1, 'PartyWinTextNameTeam1');
+ ThemeLoadText (PartyWin.TextNameTeam2, 'PartyWinTextNameTeam2');
+ ThemeLoadText (PartyWin.TextNameTeam3, 'PartyWinTextNameTeam3');
+
+ ThemeLoadStatic (PartyWin.StaticTeam1, 'PartyWinStaticTeam1');
+ ThemeLoadStatic (PartyWin.StaticTeam1BG, 'PartyWinStaticTeam1BG');
+ ThemeLoadStatic (PartyWin.StaticTeam1Deco, 'PartyWinStaticTeam1Deco');
+ ThemeLoadStatic (PartyWin.StaticTeam2, 'PartyWinStaticTeam2');
+ ThemeLoadStatic (PartyWin.StaticTeam2BG, 'PartyWinStaticTeam2BG');
+ ThemeLoadStatic (PartyWin.StaticTeam2Deco, 'PartyWinStaticTeam2Deco');
+ ThemeLoadStatic (PartyWin.StaticTeam3, 'PartyWinStaticTeam3');
+ ThemeLoadStatic (PartyWin.StaticTeam3BG, 'PartyWinStaticTeam3BG');
+ ThemeLoadStatic (PartyWin.StaticTeam3Deco, 'PartyWinStaticTeam3Deco');
+
+ ThemeLoadText (PartyWin.TextWinner, 'PartyWinTextWinner');
+
+ //Party Options
+ ThemeLoadBasic(PartyOptions, 'PartyOptions');
+ ThemeLoadSelectSlide(PartyOptions.SelectLevel, 'PartyOptionsSelectLevel');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayList, 'PartyOptionsSelectPlayList');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayList2, 'PartyOptionsSelectPlayList2');
+ ThemeLoadSelectSlide(PartyOptions.SelectRounds, 'PartyOptionsSelectRounds');
+ ThemeLoadSelectSlide(PartyOptions.SelectTeams, 'PartyOptionsSelectTeams');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers1, 'PartyOptionsSelectPlayers1');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers2, 'PartyOptionsSelectPlayers2');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers3, 'PartyOptionsSelectPlayers3');
+
+ {ThemeLoadButton (ButtonNext, 'ButtonNext');
+ ThemeLoadButton (ButtonPrev, 'ButtonPrev');}
+
+ //Party Player
+ ThemeLoadBasic(PartyPlayer, 'PartyPlayer');
+ ThemeLoadButton(PartyPlayer.Team1Name, 'PartyPlayerTeam1Name');
+ ThemeLoadButton(PartyPlayer.Player1Name, 'PartyPlayerPlayer1Name');
+ ThemeLoadButton(PartyPlayer.Player2Name, 'PartyPlayerPlayer2Name');
+ ThemeLoadButton(PartyPlayer.Player3Name, 'PartyPlayerPlayer3Name');
+ ThemeLoadButton(PartyPlayer.Player4Name, 'PartyPlayerPlayer4Name');
+
+ ThemeLoadButton(PartyPlayer.Team2Name, 'PartyPlayerTeam2Name');
+ ThemeLoadButton(PartyPlayer.Player5Name, 'PartyPlayerPlayer5Name');
+ ThemeLoadButton(PartyPlayer.Player6Name, 'PartyPlayerPlayer6Name');
+ ThemeLoadButton(PartyPlayer.Player7Name, 'PartyPlayerPlayer7Name');
+ ThemeLoadButton(PartyPlayer.Player8Name, 'PartyPlayerPlayer8Name');
+
+ ThemeLoadButton(PartyPlayer.Team3Name, 'PartyPlayerTeam3Name');
+ ThemeLoadButton(PartyPlayer.Player9Name, 'PartyPlayerPlayer9Name');
+ ThemeLoadButton(PartyPlayer.Player10Name, 'PartyPlayerPlayer10Name');
+ ThemeLoadButton(PartyPlayer.Player11Name, 'PartyPlayerPlayer11Name');
+ ThemeLoadButton(PartyPlayer.Player12Name, 'PartyPlayerPlayer12Name');
+
+ {ThemeLoadButton(ButtonNext, 'PartyPlayerButtonNext');
+ ThemeLoadButton(ButtonPrev, 'PartyPlayerButtonPrev');}
+
+ ThemeLoadBasic(StatMain, 'StatMain');
+
+ ThemeLoadButton(StatMain.ButtonScores, 'StatMainButtonScores');
+ ThemeLoadButton(StatMain.ButtonSingers, 'StatMainButtonSingers');
+ ThemeLoadButton(StatMain.ButtonSongs, 'StatMainButtonSongs');
+ ThemeLoadButton(StatMain.ButtonBands, 'StatMainButtonBands');
+ ThemeLoadButton(StatMain.ButtonExit, 'StatMainButtonExit');
+
+ ThemeLoadText (StatMain.TextOverview, 'StatMainTextOverview');
+
+
+ ThemeLoadBasic(StatDetail, 'StatDetail');
+
+ ThemeLoadButton(StatDetail.ButtonNext, 'StatDetailButtonNext');
+ ThemeLoadButton(StatDetail.ButtonPrev, 'StatDetailButtonPrev');
+ ThemeLoadButton(StatDetail.ButtonReverse, 'StatDetailButtonReverse');
+ ThemeLoadButton(StatDetail.ButtonExit, 'StatDetailButtonExit');
+
+ ThemeLoadText (StatDetail.TextDescription, 'StatDetailTextDescription');
+ ThemeLoadText (StatDetail.TextPage, 'StatDetailTextPage');
+ ThemeLoadTexts(StatDetail.TextList, 'StatDetailTextList');
+
+ //Translate Texts
+ StatDetail.Description[0] := Language.Translate('STAT_DESC_SCORES');
+ StatDetail.Description[1] := Language.Translate('STAT_DESC_SINGERS');
+ StatDetail.Description[2] := Language.Translate('STAT_DESC_SONGS');
+ StatDetail.Description[3] := Language.Translate('STAT_DESC_BANDS');
+
+ StatDetail.DescriptionR[0] := Language.Translate('STAT_DESC_SCORES_REVERSED');
+ StatDetail.DescriptionR[1] := Language.Translate('STAT_DESC_SINGERS_REVERSED');
+ StatDetail.DescriptionR[2] := Language.Translate('STAT_DESC_SONGS_REVERSED');
+ StatDetail.DescriptionR[3] := Language.Translate('STAT_DESC_BANDS_REVERSED');
+
+ StatDetail.FormatStr[0] := Language.Translate('STAT_FORMAT_SCORES');
+ StatDetail.FormatStr[1] := Language.Translate('STAT_FORMAT_SINGERS');
+ StatDetail.FormatStr[2] := Language.Translate('STAT_FORMAT_SONGS');
+ StatDetail.FormatStr[3] := Language.Translate('STAT_FORMAT_BANDS');
+
+ StatDetail.PageStr := Language.Translate('STAT_PAGE');
+
+ //Playlist Translations
+ Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT');
+
+ //Level Translations
+ //Fill ILevel
+ ILevel[0] := Language.Translate('SING_EASY');
+ ILevel[1] := Language.Translate('SING_MEDIUM');
+ ILevel[2] := Language.Translate('SING_HARD');
+ end;
+
+ ThemeIni.Free;
+ end;
+end;
+
+procedure TTheme.ThemeLoadBasic(Theme: TThemeBasic; Name: string);
+begin
+ ThemeLoadBackground(Theme.Background, Name);
+ ThemeLoadTexts(Theme.Text, Name + 'Text');
+ ThemeLoadStatics(Theme.Static, Name + 'Static');
+ ThemeLoadButtonCollections(Theme.ButtonCollection, Name + 'ButtonCollection');
+
+ LastThemeBasic := Theme;
+end;
+
+procedure TTheme.ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
+begin
+ ThemeBackground.Tex := ThemeIni.ReadString(Name + 'Background', 'Tex', '');
+end;
+
+procedure TTheme.ThemeLoadText(var ThemeText: TThemeText; Name: string);
+var
+ C: integer;
+begin
+ ThemeText.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeText.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeText.W := ThemeIni.ReadInteger(Name, 'W', 0);
+
+ ThemeText.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
+
+ ThemeText.ColR := ThemeIni.ReadFloat(Name, 'ColR', 0);
+ ThemeText.ColG := ThemeIni.ReadFloat(Name, 'ColG', 0);
+ ThemeText.ColB := ThemeIni.ReadFloat(Name, 'ColB', 0);
+
+ ThemeText.Font := ThemeIni.ReadInteger(Name, 'Font', 0);
+ ThemeText.Size := ThemeIni.ReadInteger(Name, 'Size', 0);
+ ThemeText.Align := ThemeIni.ReadInteger(Name, 'Align', 0);
+
+ ThemeText.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
+ ThemeText.Color := ThemeIni.ReadString(Name, 'Color', '');
+
+ //Reflection
+ ThemeText.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0)) = 1;
+ ThemeText.Reflectionspacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
+
+ C := ColorExists(ThemeText.Color);
+ if C >= 0 then begin
+ ThemeText.ColR := Color[C].RGB.R;
+ ThemeText.ColG := Color[C].RGB.G;
+ ThemeText.ColB := Color[C].RGB.B;
+ end;
+end;
+
+procedure TTheme.ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
+var
+ T: integer;
+begin
+ T := 1;
+ while ThemeIni.SectionExists(Name + IntToStr(T)) do begin
+ SetLength(ThemeText, T);
+ ThemeLoadText(ThemeText[T-1], Name + IntToStr(T));
+ Inc(T);
+ end;
+end;
+
+procedure TTheme.ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
+var
+ C: integer;
+begin
+ ThemeStatic.Tex := ThemeIni.ReadString(Name, 'Tex', '');
+
+ ThemeStatic.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeStatic.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeStatic.Z := ThemeIni.ReadFloat (Name, 'Z', 0);
+ ThemeStatic.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeStatic.H := ThemeIni.ReadInteger(Name, 'H', 0);
+
+ ThemeStatic.Typ := ParseTextureType(ThemeIni.ReadString(Name, 'Type', ''), TEXTURE_TYPE_PLAIN);
+ ThemeStatic.Color := ThemeIni.ReadString(Name, 'Color', '');
+
+ C := ColorExists(ThemeStatic.Color);
+ if C >= 0 then begin
+ ThemeStatic.ColR := Color[C].RGB.R;
+ ThemeStatic.ColG := Color[C].RGB.G;
+ ThemeStatic.ColB := Color[C].RGB.B;
+ end;
+
+ ThemeStatic.TexX1 := ThemeIni.ReadFloat(Name, 'TexX1', 0);
+ ThemeStatic.TexY1 := ThemeIni.ReadFloat(Name, 'TexY1', 0);
+ ThemeStatic.TexX2 := ThemeIni.ReadFloat(Name, 'TexX2', 1);
+ ThemeStatic.TexY2 := ThemeIni.ReadFloat(Name, 'TexY2', 1);
+
+ //Reflection Mod
+ ThemeStatic.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
+ ThemeStatic.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
+end;
+
+procedure TTheme.ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
+var
+ S: integer;
+begin
+ S := 1;
+ while ThemeIni.SectionExists(Name + IntToStr(S)) do begin
+ SetLength(ThemeStatic, S);
+ ThemeLoadStatic(ThemeStatic[S-1], Name + IntToStr(S));
+ Inc(S);
+ end;
+end;
+
+//Button Collection Mod
+procedure TTheme.ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
+var T: Integer;
+begin
+ //Load Collection Style
+ ThemeLoadButton(Collection.Style, Name);
+
+ //Load Other Attributes
+ T := ThemeIni.ReadInteger (Name, 'FirstChild', 0);
+ if (T > 0) And (T < 256) then
+ Collection.FirstChild := T
+ else
+ Collection.FirstChild := 0;
+end;
+
+procedure TTheme.ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string);
+var
+ I: integer;
+begin
+ I := 1;
+ while ThemeIni.SectionExists(Name + IntToStr(I)) do begin
+ SetLength(Collections, I);
+ ThemeLoadButtonCollection(Collections[I-1], Name + IntToStr(I));
+ Inc(I);
+ end;
+end;
+//End Button Collection Mod
+
+procedure TTheme.ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection);
+var
+ C: integer;
+ TLen: integer;
+ T: integer;
+ Collections2: PAThemeButtonCollection;
+begin
+ if not ThemeIni.SectionExists(Name) then
+ begin
+ ThemeButton.Visible := False;
+ exit;
+ end;
+ ThemeButton.Tex := ThemeIni.ReadString(Name, 'Tex', '');
+ ThemeButton.X := ThemeIni.ReadInteger (Name, 'X', 0);
+ ThemeButton.Y := ThemeIni.ReadInteger (Name, 'Y', 0);
+ ThemeButton.Z := ThemeIni.ReadFloat (Name, 'Z', 0);
+ ThemeButton.W := ThemeIni.ReadInteger (Name, 'W', 0);
+ ThemeButton.H := ThemeIni.ReadInteger (Name, 'H', 0);
+ ThemeButton.Typ := ParseTextureType(ThemeIni.ReadString(Name, 'Type', ''), TEXTURE_TYPE_PLAIN);
+
+ //Reflection Mod
+ ThemeButton.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
+ ThemeButton.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
+
+ ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
+ ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
+ ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
+ ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
+ ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
+ ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
+ ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
+
+ ThemeButton.Color := ThemeIni.ReadString(Name, 'Color', '');
+ C := ColorExists(ThemeButton.Color);
+ if C >= 0 then begin
+ ThemeButton.ColR := Color[C].RGB.R;
+ ThemeButton.ColG := Color[C].RGB.G;
+ ThemeButton.ColB := Color[C].RGB.B;
+ end;
+
+ ThemeButton.DColor := ThemeIni.ReadString(Name, 'DColor', '');
+ C := ColorExists(ThemeButton.DColor);
+ if C >= 0 then begin
+ ThemeButton.DColR := Color[C].RGB.R;
+ ThemeButton.DColG := Color[C].RGB.G;
+ ThemeButton.DColB := Color[C].RGB.B;
+ end;
+
+ ThemeButton.Visible := (ThemeIni.ReadInteger(Name, 'Visible', 1) = 1);
+
+ //Fade Mod
+ ThemeButton.SelectH := ThemeIni.ReadInteger (Name, 'SelectH', ThemeButton.H);
+ ThemeButton.SelectW := ThemeIni.ReadInteger (Name, 'SelectW', ThemeButton.W);
+
+ ThemeButton.DeSelectReflectionspacing := ThemeIni.ReadFloat(Name, 'DeSelectReflectionSpacing', ThemeButton.Reflectionspacing);
+
+ ThemeButton.Fade := (ThemeIni.ReadInteger(Name, 'Fade', 0) = 1);
+ ThemeButton.FadeText := (ThemeIni.ReadInteger(Name, 'FadeText', 0) = 1);
+
+
+ ThemeButton.FadeTex := ThemeIni.ReadString(Name, 'FadeTex', '');
+ ThemeButton.FadeTexPos:= ThemeIni.ReadInteger(Name, 'FadeTexPos', 0);
+ if (ThemeButton.FadeTexPos > 4) Or (ThemeButton.FadeTexPos < 0) then
+ ThemeButton.FadeTexPos := 0;
+
+ //Button Collection Mod
+ T := ThemeIni.ReadInteger(Name, 'Parent', 0);
+
+ //Set Collections to Last Basic Collections if no valid Value
+ if (Collections = nil) then
+ Collections2 := @LastThemeBasic.ButtonCollection
+ else
+ Collections2 := Collections;
+ //Test for valid Value
+ if (Collections2 <> nil) AND (T > 0) AND (T <= Length(Collections2^)) then
+ begin
+ Inc(Collections2^[T-1].ChildCount);
+ ThemeButton.Parent := T;
+ end
+ else
+ ThemeButton.Parent := 0;
+
+ //Read ButtonTexts
+ TLen := ThemeIni.ReadInteger(Name, 'Texts', 0);
+ SetLength(ThemeButton.Text, TLen);
+ for T := 1 to TLen do
+ ThemeLoadText(ThemeButton.Text[T-1], Name + 'Text' + IntToStr(T));
+end;
+
+procedure TTheme.ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
+var
+ C: integer;
+begin
+ ThemeSelectS.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
+
+ ThemeSelectS.Tex := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'Tex', '');
+ ThemeSelectS.TexSBG := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'TexSBG', '');
+
+ ThemeSelectS.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeSelectS.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeSelectS.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeSelectS.H := ThemeIni.ReadInteger(Name, 'H', 0);
+
+ ThemeSelectS.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
+
+ ThemeSelectS.TextSize := ThemeIni.ReadInteger(Name, 'TextSize', 10);
+
+ ThemeSelectS.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0);
+
+ ThemeSelectS.SBGW := ThemeIni.ReadInteger(Name, 'SBGW', 450);
+
+ LoadColor(ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeIni.ReadString(Name, 'Color', ''));
+ ThemeSelectS.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ LoadColor(ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeIni.ReadString(Name, 'DColor', ''));
+ ThemeSelectS.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
+
+ LoadColor(ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeIni.ReadString(Name, 'TColor', ''));
+ ThemeSelectS.TInt := ThemeIni.ReadFloat(Name, 'TInt', 1);
+ LoadColor(ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeIni.ReadString(Name, 'TDColor', ''));
+ ThemeSelectS.TDInt := ThemeIni.ReadFloat(Name, 'TDInt', 1);
+
+ LoadColor(ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeIni.ReadString(Name, 'SBGColor', ''));
+ ThemeSelectS.SBGInt := ThemeIni.ReadFloat(Name, 'SBGInt', 1);
+ LoadColor(ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeIni.ReadString(Name, 'SBGDColor', ''));
+ ThemeSelectS.SBGDInt := ThemeIni.ReadFloat(Name, 'SBGDInt', 1);
+
+ LoadColor(ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeIni.ReadString(Name, 'STColor', ''));
+ ThemeSelectS.STInt := ThemeIni.ReadFloat(Name, 'STInt', 1);
+ LoadColor(ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeIni.ReadString(Name, 'STDColor', ''));
+ ThemeSelectS.STDInt := ThemeIni.ReadFloat(Name, 'STDInt', 1);
+end;
+
+procedure TTheme.LoadColors;
+var
+ SL: TStringList;
+ C: integer;
+ S: string;
+ Col: integer;
+ RGB: TRGB;
+begin
+ SL := TStringList.Create;
+ ThemeIni.ReadSection('Colors', SL);
+
+ // normal colors
+ SetLength(Color, SL.Count);
+ for C := 0 to SL.Count-1 do begin
+ Color[C].Name := SL.Strings[C];
+
+ S := ThemeIni.ReadString('Colors', SL.Strings[C], '');
+
+ Color[C].RGB.R := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
+ Delete(S, 1, Pos(' ', S));
+
+ Color[C].RGB.G := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
+ Delete(S, 1, Pos(' ', S));
+
+ Color[C].RGB.B := StrToInt(S)/255;
+ end;
+
+ // skin color
+ SetLength(Color, SL.Count + 3);
+ C := SL.Count;
+ Color[C].Name := 'ColorDark';
+ Color[C].RGB := GetSystemColor(Skin.Color); //Ini.Color);
+
+ C := C+1;
+ Color[C].Name := 'ColorLight';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'ColorLightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // players colors
+ SetLength(Color, Length(Color)+18);
+
+ // P1
+ C := C+1;
+ Color[C].Name := 'P1Dark';
+ Color[C].RGB := GetSystemColor(0); // 0 - blue
+
+ C := C+1;
+ Color[C].Name := 'P1Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P1Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P2
+ C := C+1;
+ Color[C].Name := 'P2Dark';
+ Color[C].RGB := GetSystemColor(3); // 3 - red
+
+ C := C+1;
+ Color[C].Name := 'P2Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P2Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P3
+ C := C+1;
+ Color[C].Name := 'P3Dark';
+ Color[C].RGB := GetSystemColor(1); // 1 - green
+
+ C := C+1;
+ Color[C].Name := 'P3Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P3Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P4
+ C := C+1;
+ Color[C].Name := 'P4Dark';
+ Color[C].RGB := GetSystemColor(4); // 4 - brown
+
+ C := C+1;
+ Color[C].Name := 'P4Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P4Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P5
+ C := C+1;
+ Color[C].Name := 'P5Dark';
+ Color[C].RGB := GetSystemColor(5); // 5 - yellow
+
+ C := C+1;
+ Color[C].Name := 'P5Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P5Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P6
+ C := C+1;
+ Color[C].Name := 'P6Dark';
+ Color[C].RGB := GetSystemColor(6); // 6 - violet
+
+ C := C+1;
+ Color[C].Name := 'P6Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P6Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+
+ SL.Free;
+end;
+
+function ColorExists(Name: string): integer;
+var
+ C: integer;
+begin
+ Result := -1;
+ for C := 0 to High(Color) do
+ if Color[C].Name = Name then Result := C;
+end;
+
+procedure LoadColor(var R, G, B: real; ColorName: string);
+var
+ C: integer;
+begin
+ C := ColorExists(ColorName);
+ if C >= 0 then begin
+ R := Color[C].RGB.R;
+ G := Color[C].RGB.G;
+ B := Color[C].RGB.B;
+ end;
+end;
+
+function GetSystemColor(Color: integer): TRGB;
+begin
+ case Color of
+ 0: begin
+ // blue
+ Result.R := 71/255;
+ Result.G := 175/255;
+ Result.B := 247/255;
+ end;
+ 1: begin
+ // green
+ Result.R := 63/255;
+ Result.G := 191/255;
+ Result.B := 63/255;
+ end;
+ 2: begin
+ // pink
+ Result.R := 255/255;
+{ Result.G := 63/255;
+ Result.B := 192/255;}
+ Result.G := 175/255;
+ Result.B := 247/255;
+ end;
+ 3: begin
+ // red
+ Result.R := 247/255;
+ Result.G := 71/255;
+ Result.B := 71/255;
+ end;
+ //'Violet', 'Orange', 'Yellow', 'Brown', 'Black'
+ //New Theme-Color Patch
+ 4: begin
+ // violet
+ Result.R := 230/255;
+ Result.G := 63/255;
+ Result.B := 230/255;
+ end;
+ 5: begin
+ // orange
+ Result.R := 255/255;
+ Result.G := 144/255;
+ Result.B := 0;
+ end;
+ 6: begin
+ // yellow
+ Result.R := 230/255;
+ Result.G := 230/255;
+ Result.B := 95/255;
+ end;
+ 7: begin
+ // brown
+ Result.R := 192/255;
+ Result.G := 127/255;
+ Result.B := 31/255;
+ end;
+ 8: begin
+ // black
+ Result.R := 0;
+ Result.G := 0;
+ Result.B := 0;
+ end;
+ //New Theme-Color Patch End
+
+ end;
+end;
+
+function ColorSqrt(RGB: TRGB): TRGB;
+begin
+ Result.R := sqrt(RGB.R);
+ Result.G := sqrt(RGB.G);
+ Result.B := sqrt(RGB.B);
+end;
+
+procedure TTheme.ThemeSave(FileName: string);
+var
+ I: integer;
+begin
+ {$IFDEF THEMESAVE}
+ ThemeIni := TIniFile.Create(FileName);
+ {$ELSE}
+ ThemeIni := TMemIniFile.Create(FileName);
+ {$ENDIF}
+
+ ThemeSaveBasic(Loading, 'Loading');
+
+ ThemeSaveBasic(Main, 'Main');
+ ThemeSaveText(Main.TextDescription, 'MainTextDescription');
+ ThemeSaveText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
+ ThemeSaveButton(Main.ButtonSolo, 'MainButtonSolo');
+ ThemeSaveButton(Main.ButtonEditor, 'MainButtonEditor');
+ ThemeSaveButton(Main.ButtonOptions, 'MainButtonOptions');
+ ThemeSaveButton(Main.ButtonExit, 'MainButtonExit');
+
+ ThemeSaveBasic(Name, 'Name');
+ for I := 1 to 6 do
+ ThemeSaveButton(Name.ButtonPlayer[I], 'NameButtonPlayer' + IntToStr(I));
+
+ ThemeSaveBasic(Level, 'Level');
+ ThemeSaveButton(Level.ButtonEasy, 'LevelButtonEasy');
+ ThemeSaveButton(Level.ButtonMedium, 'LevelButtonMedium');
+ ThemeSaveButton(Level.ButtonHard, 'LevelButtonHard');
+
+ ThemeSaveBasic(Song, 'Song');
+ ThemeSaveText(Song.TextArtist, 'SongTextArtist');
+ ThemeSaveText(Song.TextTitle, 'SongTextTitle');
+ ThemeSaveText(Song.TextNumber, 'SongTextNumber');
+
+ //Show CAt in Top Left Mod
+ ThemeSaveText(Song.TextCat, 'SongTextCat');
+ ThemeSaveStatic(Song.StaticCat, 'SongStaticCat');
+
+ ThemeSaveBasic(Sing, 'Sing');
+
+ //TimeBar mod
+ ThemeSaveStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
+ ThemeSaveText(Sing.TextTimeText, 'SingTimeText');
+ //eoa TimeBar mod
+
+ ThemeSaveStatic(Sing.StaticP1, 'SingP1Static');
+ ThemeSaveText(Sing.TextP1, 'SingP1Text');
+ ThemeSaveStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
+ ThemeSaveText(Sing.TextP1Score, 'SingP1TextScore');
+
+ //moveable singbar mod
+ ThemeSaveStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
+ ThemeSaveStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
+ ThemeSaveStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
+ ThemeSaveStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
+ ThemeSaveStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
+ ThemeSaveStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
+ //eoa moveable singbar
+
+ //Added for ps3 skin
+ //This one is shown in 2/4P mode
+ ThemeSaveStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
+ ThemeSaveText(Sing.TextP1TwoP, 'SingP1TwoPText');
+ ThemeSaveStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
+ ThemeSaveText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
+
+ //This one is shown in 3/6P mode
+ ThemeSaveStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
+ ThemeSaveText(Sing.TextP1ThreeP, 'SingP1ThreePText');
+ ThemeSaveStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
+ ThemeSaveText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
+ //eoa
+
+ ThemeSaveStatic(Sing.StaticP2R, 'SingP2RStatic');
+ ThemeSaveText(Sing.TextP2R, 'SingP2RText');
+ ThemeSaveStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
+ ThemeSaveText(Sing.TextP2RScore, 'SingP2RTextScore');
+
+ ThemeSaveStatic(Sing.StaticP2M, 'SingP2MStatic');
+ ThemeSaveText(Sing.TextP2M, 'SingP2MText');
+ ThemeSaveStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
+ ThemeSaveText(Sing.TextP2MScore, 'SingP2MTextScore');
+
+ ThemeSaveStatic(Sing.StaticP3R, 'SingP3RStatic');
+ ThemeSaveText(Sing.TextP3R, 'SingP3RText');
+ ThemeSaveStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
+ ThemeSaveText(Sing.TextP3RScore, 'SingP3RTextScore');
+
+ ThemeSaveBasic(Score, 'Score');
+ ThemeSaveText(Score.TextArtist, 'ScoreTextArtist');
+ ThemeSaveText(Score.TextTitle, 'ScoreTextTitle');
+
+ for I := 1 to 6 do begin
+ ThemeSaveStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
+
+ ThemeSaveText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
+ ThemeSaveText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
+ ThemeSaveText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
+ ThemeSaveText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
+ ThemeSaveText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
+ ThemeSaveText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
+ ThemeSaveText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
+ ThemeSaveText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
+ ThemeSaveText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
+ ThemeSaveText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
+
+ ThemeSaveStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
+ end;
+
+ ThemeSaveBasic(Top5, 'Top5');
+ ThemeSaveText(Top5.TextLevel, 'Top5TextLevel');
+ ThemeSaveText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
+ ThemeSaveStatics(Top5.StaticNumber, 'Top5StaticNumber');
+ ThemeSaveTexts(Top5.TextNumber, 'Top5TextNumber');
+ ThemeSaveTexts(Top5.TextName, 'Top5TextName');
+ ThemeSaveTexts(Top5.TextScore, 'Top5TextScore');
+
+
+ ThemeIni.Free;
+end;
+
+procedure TTheme.ThemeSaveBasic(Theme: TThemeBasic; Name: string);
+begin
+ ThemeIni.WriteInteger(Name, 'Texts', Length(Theme.Text));
+
+ ThemeSaveBackground(Theme.Background, Name + 'Background');
+ ThemeSaveStatics(Theme.Static, Name + 'Static');
+ ThemeSaveTexts(Theme.Text, Name + 'Text');
+end;
+
+procedure TTheme.ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
+begin
+ if ThemeBackground.Tex <> '' then
+ ThemeIni.WriteString(Name, 'Tex', ThemeBackground.Tex)
+ else begin
+ ThemeIni.EraseSection(Name);
+ end;
+end;
+
+procedure TTheme.ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
+begin
+ ThemeIni.WriteInteger(Name, 'X', ThemeStatic.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeStatic.Y);
+ ThemeIni.WriteInteger(Name, 'W', ThemeStatic.W);
+ ThemeIni.WriteInteger(Name, 'H', ThemeStatic.H);
+
+ ThemeIni.WriteString(Name, 'Tex', ThemeStatic.Tex);
+ ThemeIni.WriteString(Name, 'Type', TextureTypeToStr(ThemeStatic.Typ));
+ ThemeIni.WriteString(Name, 'Color', ThemeStatic.Color);
+
+ ThemeIni.WriteFloat(Name, 'TexX1', ThemeStatic.TexX1);
+ ThemeIni.WriteFloat(Name, 'TexY1', ThemeStatic.TexY1);
+ ThemeIni.WriteFloat(Name, 'TexX2', ThemeStatic.TexX2);
+ ThemeIni.WriteFloat(Name, 'TexY2', ThemeStatic.TexY2);
+end;
+
+procedure TTheme.ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
+var
+ S: integer;
+begin
+ for S := 0 to Length(ThemeStatic)-1 do
+ ThemeSaveStatic(ThemeStatic[S], Name + {'Static' +} IntToStr(S+1));
+
+ ThemeIni.EraseSection(Name + {'Static' + }IntToStr(S+1));
+end;
+
+procedure TTheme.ThemeSaveText(ThemeText: TThemeText; Name: string);
+begin
+ ThemeIni.WriteInteger(Name, 'X', ThemeText.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeText.Y);
+
+ ThemeIni.WriteInteger(Name, 'Font', ThemeText.Font);
+ ThemeIni.WriteInteger(Name, 'Size', ThemeText.Size);
+ ThemeIni.WriteInteger(Name, 'Align', ThemeText.Align);
+
+ ThemeIni.WriteString(Name, 'Text', ThemeText.Text);
+ ThemeIni.WriteString(Name, 'Color', ThemeText.Color);
+
+ ThemeIni.WriteBool(Name, 'Reflection', ThemeText.Reflection);
+ ThemeIni.WriteFloat(Name, 'ReflectionSpacing', ThemeText.ReflectionSpacing);
+end;
+
+procedure TTheme.ThemeSaveTexts(ThemeText: AThemeText; Name: string);
+var
+ T: integer;
+begin
+ for T := 0 to Length(ThemeText)-1 do
+ ThemeSaveText(ThemeText[T], Name + {'Text' + }IntToStr(T+1));
+
+ ThemeIni.EraseSection(Name + {'Text' + }IntToStr(T+1));
+end;
+
+procedure TTheme.ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
+var
+ T: integer;
+begin
+ ThemeIni.WriteString(Name, 'Tex', ThemeButton.Tex);
+ ThemeIni.WriteInteger(Name, 'X', ThemeButton.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeButton.Y);
+ ThemeIni.WriteInteger(Name, 'W', ThemeButton.W);
+ ThemeIni.WriteInteger(Name, 'H', ThemeButton.H);
+ ThemeIni.WriteString(Name, 'Type', TextureTypeToStr(ThemeButton.Typ));
+ ThemeIni.WriteInteger(Name, 'Texts', Length(ThemeButton.Text));
+
+ ThemeIni.WriteString(Name, 'Color', ThemeButton.Color);
+
+{ ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
+ ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
+ ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
+ ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
+ ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
+ ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
+ ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);}
+
+{ C := ColorExists(ThemeIni.ReadString(Name, 'Color', ''));
+ if C >= 0 then begin
+ ThemeButton.ColR := Color[C].RGB.R;
+ ThemeButton.ColG := Color[C].RGB.G;
+ ThemeButton.ColB := Color[C].RGB.B;
+ end;
+
+ C := ColorExists(ThemeIni.ReadString(Name, 'DColor', ''));
+ if C >= 0 then begin
+ ThemeButton.DColR := Color[C].RGB.R;
+ ThemeButton.DColG := Color[C].RGB.G;
+ ThemeButton.DColB := Color[C].RGB.B;
+ end;}
+
+ for T := 0 to High(ThemeButton.Text) do
+ ThemeSaveText(ThemeButton.Text[T], Name + 'Text' + IntToStr(T+1));
+end;
+
+procedure TTheme.create_theme_objects();
+begin
+ freeandnil( Loading );
+ Loading := TThemeLoading.Create;
+
+ freeandnil( Main );
+ Main := TThemeMain.Create;
+
+ freeandnil( Name );
+ Name := TThemeName.Create;
+
+ freeandnil( Level );
+ Level := TThemeLevel.Create;
+
+ freeandnil( Song );
+ Song := TThemeSong.Create;
+
+ freeandnil( Sing );
+ Sing := TThemeSing.Create;
+
+ freeandnil( Score );
+ Score := TThemeScore.Create;
+
+ freeandnil( Top5 );
+ Top5 := TThemeTop5.Create;
+
+ freeandnil( Options );
+ Options := TThemeOptions.Create;
+
+ freeandnil( OptionsGame );
+ OptionsGame := TThemeOptionsGame.Create;
+
+ freeandnil( OptionsGraphics );
+ OptionsGraphics := TThemeOptionsGraphics.Create;
+
+ freeandnil( OptionsSound );
+ OptionsSound := TThemeOptionsSound.Create;
+
+ freeandnil( OptionsLyrics );
+ OptionsLyrics := TThemeOptionsLyrics.Create;
+
+ freeandnil( OptionsThemes );
+ OptionsThemes := TThemeOptionsThemes.Create;
+
+ freeandnil( OptionsRecord );
+ OptionsRecord := TThemeOptionsRecord.Create;
+
+ freeandnil( OptionsAdvanced );
+ OptionsAdvanced := TThemeOptionsAdvanced.Create;
+
+
+ freeandnil( ErrorPopup );
+ ErrorPopup := TThemeError.Create;
+
+ freeandnil( CheckPopup );
+ CheckPopup := TThemeCheck.Create;
+
+
+ freeandnil( SongMenu );
+ SongMenu := TThemeSongMenu.Create;
+
+ freeandnil( SongJumpto );
+ SongJumpto := TThemeSongJumpto.Create;
+
+ //Party Screens
+ freeandnil( PartyNewRound );
+ PartyNewRound := TThemePartyNewRound.Create;
+
+ freeandnil( PartyWin );
+ PartyWin := TThemePartyWin.Create;
+
+ freeandnil( PartyScore );
+ PartyScore := TThemePartyScore.Create;
+
+ freeandnil( PartyOptions );
+ PartyOptions := TThemePartyOptions.Create;
+
+ freeandnil( PartyPlayer );
+ PartyPlayer := TThemePartyPlayer.Create;
+
+
+ //Stats Screens:
+ freeandnil( StatMain );
+ StatMain := TThemeStatMain.Create;
+
+ freeandnil( StatDetail );
+ StatDetail := TThemeStatDetail.Create;
+
+ end;
+
+end.
diff --git a/src/Classes/UTime.pas b/src/Classes/UTime.pas
new file mode 100644
index 00000000..f8ae91c4
--- /dev/null
+++ b/src/Classes/UTime.pas
@@ -0,0 +1,185 @@
+unit UTime;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+type
+ TTime = class
+ public
+ constructor Create;
+ function GetTime(): real;
+ end;
+
+ TRelativeTimer = class
+ private
+ AbsoluteTime: int64; // system-clock reference time for calculation of CurrentTime
+ RelativeTimeOffset: real;
+ Paused: boolean;
+ TriggerMode: boolean;
+ public
+ constructor Create(TriggerMode: boolean = false);
+ procedure Pause();
+ procedure Resume();
+ function GetTime(): real;
+ function GetAndResetTime(): real;
+ procedure SetTime(Time: real; Trigger: boolean = true);
+ procedure Reset();
+ end;
+
+procedure CountSkipTimeSet;
+procedure CountSkipTime;
+procedure CountMidTime;
+
+var
+ USTime : TTime;
+ VideoBGTimer: TRelativeTimer;
+
+ TimeNew : int64;
+ TimeOld : int64;
+ TimeSkip : real;
+ TimeMid : real;
+ TimeMidTemp : int64;
+
+implementation
+
+uses
+ sdl,
+ ucommon;
+
+const
+ cSDLCorrectionRatio = 1000;
+
+(*
+BEST Option now ( after discussion with whiteshark ) seems to be to use SDL
+timer functions...
+
+SDL_delay
+SDL_GetTicks
+http://www.gamedev.net/community/forums/topic.asp?topic_id=466145&whichpage=1%EE%8D%B7
+*)
+
+
+procedure CountSkipTimeSet;
+begin
+ TimeNew := SDL_GetTicks();
+end;
+
+procedure CountSkipTime;
+begin
+ TimeOld := TimeNew;
+ TimeNew := SDL_GetTicks();
+ TimeSkip := (TimeNew-TimeOld) / cSDLCorrectionRatio;
+end;
+
+procedure CountMidTime;
+begin
+ TimeMidTemp := SDL_GetTicks();
+ TimeMid := (TimeMidTemp - TimeNew) / cSDLCorrectionRatio;
+end;
+
+{**
+ * TTime
+ **}
+
+constructor TTime.Create;
+begin
+ inherited;
+ CountSkipTimeSet;
+end;
+
+function TTime.GetTime: real;
+begin
+ Result := SDL_GetTicks() / cSDLCorrectionRatio;
+end;
+
+{**
+ * TRelativeTimer
+ **}
+
+(*
+ * Creates a new timer.
+ * If TriggerMode is false (default), the timer
+ * will immediately begin with counting.
+ * If TriggerMode is true, it will wait until Get/SetTime() or Pause() is called
+ * for the first time.
+ *)
+constructor TRelativeTimer.Create(TriggerMode: boolean);
+begin
+ inherited Create();
+ Self.TriggerMode := TriggerMode;
+ Reset();
+ Paused := false;
+end;
+
+procedure TRelativeTimer.Pause();
+begin
+ RelativeTimeOffset := GetTime();
+ Paused := true;
+end;
+
+procedure TRelativeTimer.Resume();
+begin
+ AbsoluteTime := SDL_GetTicks();
+ Paused := false;
+end;
+
+(*
+ * Returns the counter of the timer.
+ * If in TriggerMode it will return 0 and start the counter on the first call.
+ *)
+function TRelativeTimer.GetTime: real;
+begin
+ // initialize absolute time on first call in triggered mode
+ if (TriggerMode and (AbsoluteTime = 0)) then
+ begin
+ AbsoluteTime := SDL_GetTicks();
+ Result := RelativeTimeOffset;
+ Exit;
+ end;
+
+ if Paused then
+ Result := RelativeTimeOffset
+ else
+ Result := RelativeTimeOffset + (SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
+end;
+
+(*
+ * Returns the counter of the timer and resets the counter to 0 afterwards.
+ * Note: In TriggerMode the counter will not be stopped as with Reset().
+ *)
+function TRelativeTimer.GetAndResetTime(): real;
+begin
+ Result := GetTime();
+ SetTime(0);
+end;
+
+(*
+ * Sets the timer to the given time. This will trigger in TriggerMode if
+ * Trigger is set to true. Otherwise the counter's state will not change.
+ *)
+procedure TRelativeTimer.SetTime(Time: real; Trigger: boolean);
+begin
+ RelativeTimeOffset := Time;
+ if ((not TriggerMode) or Trigger) then
+ AbsoluteTime := SDL_GetTicks();
+end;
+
+(*
+ * Resets the counter of the timer to 0.
+ * If in TriggerMode the timer will not start counting until it is triggered again.
+ *)
+procedure TRelativeTimer.Reset();
+begin
+ RelativeTimeOffset := 0;
+ if (TriggerMode) then
+ AbsoluteTime := 0
+ else
+ AbsoluteTime := SDL_GetTicks();
+end;
+
+end.
diff --git a/src/Classes/UVideo.pas b/src/Classes/UVideo.pas
new file mode 100644
index 00000000..0ab1d350
--- /dev/null
+++ b/src/Classes/UVideo.pas
@@ -0,0 +1,828 @@
+{##############################################################################
+ # FFmpeg support for UltraStar deluxe #
+ # #
+ # Created by b1indy #
+ # based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) #
+ # with modifications by Jay Binks #
+ # #
+ # http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg09949.html #
+ # http://www.nabble.com/file/p11795857/mpegpas01.zip #
+ # #
+ ##############################################################################}
+
+unit UVideo;
+
+// uncomment if you want to see the debug stuff
+{.$define DebugDisplay}
+{.$define DebugFrames}
+{.$define VideoBenchmark}
+{.$define Info}
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+// use BGR-format for accelerated colorspace conversion with swscale
+{$IFDEF UseSWScale}
+ {$DEFINE PIXEL_FMT_BGR}
+{$ENDIF}
+
+implementation
+
+uses
+ SDL,
+ textgl,
+ avcodec,
+ avformat,
+ avutil,
+ avio,
+ rational,
+ {$IFDEF UseSWScale}
+ swscale,
+ {$ENDIF}
+ UMediaCore_FFmpeg,
+ math,
+ gl,
+ glext,
+ SysUtils,
+ UCommon,
+ UConfig,
+ ULog,
+ UMusic,
+ UGraphicClasses,
+ UGraphic;
+
+const
+{$IFDEF PIXEL_FMT_BGR}
+ PIXEL_FMT_OPENGL = GL_BGR;
+ PIXEL_FMT_FFMPEG = PIX_FMT_BGR24;
+{$ELSE}
+ PIXEL_FMT_OPENGL = GL_RGB;
+ PIXEL_FMT_FFMPEG = PIX_FMT_RGB24;
+{$ENDIF}
+
+type
+ TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback )
+ private
+ fVideoOpened,
+ fVideoPaused: Boolean;
+
+ VideoStream: PAVStream;
+ VideoStreamIndex : Integer;
+ VideoFormatContext: PAVFormatContext;
+ VideoCodecContext: PAVCodecContext;
+ VideoCodec: PAVCodec;
+
+ AVFrame: PAVFrame;
+ AVFrameRGB: PAVFrame;
+ FrameBuffer: PByte;
+
+ {$IFDEF UseSWScale}
+ SoftwareScaleContext: PSwsContext;
+ {$ENDIF}
+
+ fVideoTex: GLuint;
+ TexWidth, TexHeight: Cardinal;
+
+ VideoAspect: Real;
+ VideoTimeBase, VideoTime: Extended;
+ fLoopTime: Extended;
+
+ EOF: boolean;
+ Loop: boolean;
+
+ Initialized: boolean;
+
+ procedure Reset();
+ function DecodeFrame(var AVPacket: TAVPacket; out pts: double): boolean;
+ procedure SynchronizeVideo(Frame: PAVFrame; var pts: double);
+ public
+ function GetName: String;
+
+ function Init(): boolean;
+ function Finalize: boolean;
+
+ function Open(const aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+ end;
+
+var
+ FFmpegCore: TMediaCore_FFmpeg;
+
+
+// These are called whenever we allocate a frame buffer.
+// We use this to store the global_pts in a frame at the time it is allocated.
+function PtsGetBuffer(CodecCtx: PAVCodecContext; Frame: PAVFrame): integer; cdecl;
+var
+ pts: Pint64;
+ VideoPktPts: Pint64;
+begin
+ Result := avcodec_default_get_buffer(CodecCtx, Frame);
+ VideoPktPts := CodecCtx^.opaque;
+ if (VideoPktPts <> nil) then
+ begin
+ // Note: we must copy the pts instead of passing a pointer, because the packet
+ // (and with it the pts) might change before a frame is returned by av_decode_video.
+ pts := av_malloc(sizeof(int64));
+ pts^ := VideoPktPts^;
+ Frame^.opaque := pts;
+ end;
+end;
+
+procedure PtsReleaseBuffer(CodecCtx: PAVCodecContext; Frame: PAVFrame); cdecl;
+begin
+ if (Frame <> nil) then
+ av_freep(@Frame^.opaque);
+ avcodec_default_release_buffer(CodecCtx, Frame);
+end;
+
+
+{*------------------------------------------------------------------------------
+ * TVideoPlayback_ffmpeg
+ *------------------------------------------------------------------------------}
+
+function TVideoPlayback_FFmpeg.GetName: String;
+begin
+ result := 'FFmpeg_Video';
+end;
+
+function TVideoPlayback_FFmpeg.Init(): boolean;
+begin
+ Result := true;
+
+ if (Initialized) then
+ Exit;
+ Initialized := true;
+
+ FFmpegCore := TMediaCore_FFmpeg.GetInstance();
+
+ Reset();
+ av_register_all();
+ glGenTextures(1, PGLuint(@fVideoTex));
+end;
+
+function TVideoPlayback_FFmpeg.Finalize(): boolean;
+begin
+ Close();
+ glDeleteTextures(1, PGLuint(@fVideoTex));
+ Result := true;
+end;
+
+procedure TVideoPlayback_FFmpeg.Reset();
+begin
+ // close previously opened video
+ Close();
+
+ fVideoOpened := False;
+ fVideoPaused := False;
+ VideoTimeBase := 0;
+ VideoTime := 0;
+ VideoStream := nil;
+ VideoStreamIndex := -1;
+
+ EOF := false;
+
+ // TODO: do we really want this by default?
+ Loop := true;
+ fLoopTime := 0;
+end;
+
+function TVideoPlayback_FFmpeg.Open(const aFileName : string): boolean; // true if succeed
+var
+ errnum: Integer;
+ AudioStreamIndex: integer;
+begin
+ Result := false;
+
+ Reset();
+
+ errnum := av_open_input_file(VideoFormatContext, PChar(aFileName), nil, 0, nil);
+ if (errnum <> 0) then
+ begin
+ Log.LogError('Failed to open file "'+aFileName+'" ('+FFmpegCore.GetErrorString(errnum)+')');
+ Exit;
+ end;
+
+ // update video info
+ if (av_find_stream_info(VideoFormatContext) < 0) then
+ begin
+ Log.LogError('No stream info found', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+ Log.LogInfo('VideoStreamIndex : ' + inttostr(VideoStreamIndex), 'TVideoPlayback_ffmpeg.Open');
+
+ // find video stream
+ FFmpegCore.FindStreamIDs(VideoFormatContext, VideoStreamIndex, AudioStreamIndex);
+ if (VideoStreamIndex < 0) then
+ begin
+ Log.LogError('No video stream found', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+
+ VideoStream := VideoFormatContext^.streams[VideoStreamIndex];
+ VideoCodecContext := VideoStream^.codec;
+
+ VideoCodec := avcodec_find_decoder(VideoCodecContext^.codec_id);
+ if (VideoCodec = nil) then
+ begin
+ Log.LogError('No matching codec found', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+
+ // set debug options
+ VideoCodecContext^.debug_mv := 0;
+ VideoCodecContext^.debug := 0;
+
+ // detect bug-workarounds automatically
+ VideoCodecContext^.workaround_bugs := FF_BUG_AUTODETECT;
+ // error resilience strategy (careful/compliant/agressive/very_aggressive)
+ //VideoCodecContext^.error_resilience := FF_ER_CAREFUL; //FF_ER_COMPLIANT;
+ // allow non spec compliant speedup tricks.
+ //VideoCodecContext^.flags2 := VideoCodecContext^.flags2 or CODEC_FLAG2_FAST;
+
+ // Note: avcodec_open() and avcodec_close() are not thread-safe and will
+ // fail if called concurrently by different threads.
+ FFmpegCore.LockAVCodec();
+ try
+ errnum := avcodec_open(VideoCodecContext, VideoCodec);
+ finally
+ FFmpegCore.UnlockAVCodec();
+ end;
+ if (errnum < 0) then
+ begin
+ Log.LogError('No matching codec found', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+
+ // register custom callbacks for pts-determination
+ VideoCodecContext^.get_buffer := PtsGetBuffer;
+ VideoCodecContext^.release_buffer := PtsReleaseBuffer;
+
+ {$ifdef DebugDisplay}
+ DebugWriteln('Found a matching Codec: '+ VideoCodecContext^.Codec.Name + sLineBreak +
+ sLineBreak +
+ ' Width = '+inttostr(VideoCodecContext^.width) +
+ ', Height='+inttostr(VideoCodecContext^.height) + sLineBreak +
+ ' Aspect : '+inttostr(VideoCodecContext^.sample_aspect_ratio.num) + '/' +
+ inttostr(VideoCodecContext^.sample_aspect_ratio.den) + sLineBreak +
+ ' Framerate : '+inttostr(VideoCodecContext^.time_base.num) + '/' +
+ inttostr(VideoCodecContext^.time_base.den));
+ {$endif}
+
+ // allocate space for decoded frame and rgb frame
+ AVFrame := avcodec_alloc_frame();
+ AVFrameRGB := avcodec_alloc_frame();
+ FrameBuffer := av_malloc(avpicture_get_size(PIXEL_FMT_FFMPEG,
+ VideoCodecContext^.width, VideoCodecContext^.height));
+
+ if ((AVFrame = nil) or (AVFrameRGB = nil) or (FrameBuffer = nil)) then
+ begin
+ Log.LogError('Failed to allocate buffers', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+
+ // TODO: pad data for OpenGL to GL_UNPACK_ALIGNMENT
+ // (otherwise video will be distorted if width/height is not a multiple of the alignment)
+ errnum := avpicture_fill(PAVPicture(AVFrameRGB), FrameBuffer, PIXEL_FMT_FFMPEG,
+ VideoCodecContext^.width, VideoCodecContext^.height);
+ if (errnum < 0) then
+ begin
+ Log.LogError('avpicture_fill failed: ' + FFmpegCore.GetErrorString(errnum), 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+
+ // calculate some information for video display
+ VideoAspect := av_q2d(VideoCodecContext^.sample_aspect_ratio);
+ if (VideoAspect = 0) then
+ VideoAspect := VideoCodecContext^.width /
+ VideoCodecContext^.height
+ else
+ VideoAspect := VideoAspect * VideoCodecContext^.width /
+ VideoCodecContext^.height;
+
+ VideoTimeBase := 1/av_q2d(VideoStream^.r_frame_rate);
+
+ // hack to get reasonable timebase (for divx and others)
+ if (VideoTimeBase < 0.02) then // 0.02 <-> 50 fps
+ begin
+ VideoTimeBase := av_q2d(VideoStream^.r_frame_rate);
+ while (VideoTimeBase > 50) do
+ VideoTimeBase := VideoTimeBase/10;
+ VideoTimeBase := 1/VideoTimeBase;
+ end;
+
+ Log.LogInfo('VideoTimeBase: ' + floattostr(VideoTimeBase), 'TVideoPlayback_ffmpeg.Open');
+ Log.LogInfo('Framerate: '+inttostr(floor(1/VideoTimeBase))+'fps', 'TVideoPlayback_ffmpeg.Open');
+
+ {$IFDEF UseSWScale}
+ // if available get a SWScale-context -> faster than the deprecated img_convert().
+ // SWScale has accelerated support for PIX_FMT_RGB32/PIX_FMT_BGR24/PIX_FMT_BGR565/PIX_FMT_BGR555.
+ // Note: PIX_FMT_RGB32 is a BGR- and not an RGB-format (maybe a bug)!!!
+ // The BGR565-formats (GL_UNSIGNED_SHORT_5_6_5) is way too slow because of its
+ // bad OpenGL support. The BGR formats have MMX(2) implementations but no speed-up
+ // could be observed in comparison to the RGB versions.
+ SoftwareScaleContext := sws_getContext(
+ VideoCodecContext^.width, VideoCodecContext^.height,
+ integer(VideoCodecContext^.pix_fmt),
+ VideoCodecContext^.width, VideoCodecContext^.height,
+ integer(PIXEL_FMT_FFMPEG),
+ SWS_FAST_BILINEAR, nil, nil, nil);
+ if (SoftwareScaleContext = nil) then
+ begin
+ Log.LogError('Failed to get swscale context', 'TVideoPlayback_ffmpeg.Open');
+ Close();
+ Exit;
+ end;
+ {$ENDIF}
+
+ TexWidth := Round(Power(2, Ceil(Log2(VideoCodecContext^.width))));
+ TexHeight := Round(Power(2, Ceil(Log2(VideoCodecContext^.height))));
+
+ // we retrieve a texture just once with glTexImage2D and update it with glTexSubImage2D later.
+ // Benefits: glTexSubImage2D is faster and supports non-power-of-two widths/height.
+ glBindTexture(GL_TEXTURE_2D, fVideoTex);
+ glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, TexWidth, TexHeight, 0,
+ PIXEL_FMT_OPENGL, GL_UNSIGNED_BYTE, nil);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+
+ fVideoOpened := True;
+
+ Result := true;
+end;
+
+procedure TVideoPlayback_FFmpeg.Close;
+begin
+ if (FrameBuffer <> nil) then
+ av_free(FrameBuffer);
+ if (AVFrameRGB <> nil) then
+ av_free(AVFrameRGB);
+ if (AVFrame <> nil) then
+ av_free(AVFrame);
+
+ AVFrame := nil;
+ AVFrameRGB := nil;
+ FrameBuffer := nil;
+
+ if (VideoCodecContext <> nil) then
+ begin
+ // avcodec_close() is not thread-safe
+ FFmpegCore.LockAVCodec();
+ try
+ avcodec_close(VideoCodecContext);
+ finally
+ FFmpegCore.UnlockAVCodec();
+ end;
+ end;
+
+ if (VideoFormatContext <> nil) then
+ av_close_input_file(VideoFormatContext);
+
+ VideoCodecContext := nil;
+ VideoFormatContext := nil;
+
+ fVideoOpened := False;
+end;
+
+procedure TVideoPlayback_FFmpeg.SynchronizeVideo(Frame: PAVFrame; var pts: double);
+var
+ FrameDelay: double;
+begin
+ if (pts <> 0) then
+ begin
+ // if we have pts, set video clock to it
+ VideoTime := pts;
+ end else
+ begin
+ // if we aren't given a pts, set it to the clock
+ pts := VideoTime;
+ end;
+ // update the video clock
+ FrameDelay := av_q2d(VideoCodecContext^.time_base);
+ // if we are repeating a frame, adjust clock accordingly
+ FrameDelay := FrameDelay + Frame^.repeat_pict * (FrameDelay * 0.5);
+ VideoTime := VideoTime + FrameDelay;
+end;
+
+function TVideoPlayback_FFmpeg.DecodeFrame(var AVPacket: TAVPacket; out pts: double): boolean;
+var
+ FrameFinished: Integer;
+ VideoPktPts: int64;
+ pbIOCtx: PByteIOContext;
+ errnum: integer;
+begin
+ Result := false;
+ FrameFinished := 0;
+
+ if EOF then
+ Exit;
+
+ // read packets until we have a finished frame (or there are no more packets)
+ while (FrameFinished = 0) do
+ begin
+ errnum := av_read_frame(VideoFormatContext, AVPacket);
+ if (errnum < 0) then
+ begin
+ // failed to read a frame, check reason
+
+ {$IF (LIBAVFORMAT_VERSION_MAJOR >= 52)}
+ pbIOCtx := VideoFormatContext^.pb;
+ {$ELSE}
+ pbIOCtx := @VideoFormatContext^.pb;
+ {$IFEND}
+
+ // check for end-of-file (eof is not an error)
+ if (url_feof(pbIOCtx) <> 0) then
+ begin
+ EOF := true;
+ Exit;
+ end;
+
+ // check for errors
+ if (url_ferror(pbIOCtx) <> 0) then
+ Exit;
+
+ // url_feof() does not detect an EOF for some mov-files (e.g. deluxe.mov)
+ // so we have to do it this way.
+ if ((VideoFormatContext^.file_size <> 0) and
+ (pbIOCtx^.pos >= VideoFormatContext^.file_size)) then
+ begin
+ EOF := true;
+ Exit;
+ end;
+
+ // no error -> wait for user input
+ SDL_Delay(100);
+ continue;
+ end;
+
+ // if we got a packet from the video stream, then decode it
+ if (AVPacket.stream_index = VideoStreamIndex) then
+ begin
+ // save pts to be stored in pFrame in first call of PtsGetBuffer()
+ VideoPktPts := AVPacket.pts;
+ VideoCodecContext^.opaque := @VideoPktPts;
+
+ // decode packet
+ avcodec_decode_video(VideoCodecContext, AVFrame,
+ frameFinished, AVPacket.data, AVPacket.size);
+
+ // reset opaque data
+ VideoCodecContext^.opaque := nil;
+
+ // update pts
+ if (AVPacket.dts <> AV_NOPTS_VALUE) then
+ begin
+ pts := AVPacket.dts;
+ end
+ else if ((AVFrame^.opaque <> nil) and
+ (Pint64(AVFrame^.opaque)^ <> AV_NOPTS_VALUE)) then
+ begin
+ pts := Pint64(AVFrame^.opaque)^;
+ end
+ else
+ begin
+ pts := 0;
+ end;
+ pts := pts * av_q2d(VideoStream^.time_base);
+
+ // synchronize on each complete frame
+ if (frameFinished <> 0) then
+ SynchronizeVideo(AVFrame, pts);
+ end;
+
+ // free the packet from av_read_frame
+ av_free_packet( @AVPacket );
+ end;
+
+ Result := true;
+end;
+
+procedure TVideoPlayback_FFmpeg.GetFrame(Time: Extended);
+var
+ AVPacket: TAVPacket;
+ errnum: Integer;
+ myTime: Extended;
+ TimeDifference: Extended;
+ DropFrameCount: Integer;
+ pts: double;
+ i: Integer;
+const
+ FRAME_DROPCOUNT = 3;
+begin
+ if not fVideoOpened then
+ Exit;
+
+ if fVideoPaused then
+ Exit;
+
+ // current time, relative to last loop (if any)
+ myTime := Time - fLoopTime;
+ // time since the last frame was returned
+ TimeDifference := myTime - VideoTime;
+
+ {$IFDEF DebugDisplay}
+ DebugWriteln('Time: '+inttostr(floor(Time*1000)) + sLineBreak +
+ 'VideoTime: '+inttostr(floor(VideoTime*1000)) + sLineBreak +
+ 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
+ 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
+ {$endif}
+
+ // check if a new frame is needed
+ if (VideoTime <> 0) and (TimeDifference < VideoTimeBase) then
+ begin
+ {$ifdef DebugFrames}
+ // frame delay debug display
+ GoldenRec.Spawn(200,15,1,16,0,-1,ColoredStar,$00ff00);
+ {$endif}
+
+ {$IFDEF DebugDisplay}
+ DebugWriteln('not getting new frame' + sLineBreak +
+ 'Time: '+inttostr(floor(Time*1000)) + sLineBreak +
+ 'VideoTime: '+inttostr(floor(VideoTime*1000)) + sLineBreak +
+ 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
+ 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
+ {$endif}
+
+ // we do not need a new frame now
+ Exit;
+ end;
+
+ // update video-time to the next frame
+ VideoTime := VideoTime + VideoTimeBase;
+ TimeDifference := myTime - VideoTime;
+
+ // check if we have to skip frames
+ if (TimeDifference >= FRAME_DROPCOUNT*VideoTimeBase) then
+ begin
+ {$IFDEF DebugFrames}
+ //frame drop debug display
+ GoldenRec.Spawn(200,55,1,16,0,-1,ColoredStar,$ff0000);
+ {$ENDIF}
+ {$IFDEF DebugDisplay}
+ DebugWriteln('skipping frames' + sLineBreak +
+ 'TimeBase: '+inttostr(floor(VideoTimeBase*1000)) + sLineBreak +
+ 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
+ {$endif}
+
+ // update video-time
+ DropFrameCount := Trunc(TimeDifference / VideoTimeBase);
+ VideoTime := VideoTime + DropFrameCount*VideoTimeBase;
+
+ // skip half of the frames, this is much smoother than to skip all at once
+ for i := 1 to DropFrameCount (*div 2*) do
+ DecodeFrame(AVPacket, pts);
+ end;
+
+ {$IFDEF VideoBenchmark}
+ Log.BenchmarkStart(15);
+ {$ENDIF}
+
+ if (not DecodeFrame(AVPacket, pts)) then
+ begin
+ if Loop then
+ begin
+ // Record the time we looped. This is used to keep the loops in time. otherwise they speed
+ SetPosition(0);
+ fLoopTime := Time;
+ end;
+ Exit;
+ end;
+
+ // TODO: support for pan&scan
+ //if (AVFrame.pan_scan <> nil) then
+ //begin
+ // Writeln(Format('PanScan: %d/%d', [AVFrame.pan_scan.width, AVFrame.pan_scan.height]));
+ //end;
+
+ // otherwise we convert the pixeldata from YUV to RGB
+ {$IFDEF UseSWScale}
+ errnum := sws_scale(SoftwareScaleContext, @(AVFrame.data), @(AVFrame.linesize),
+ 0, VideoCodecContext^.Height,
+ @(AVFrameRGB.data), @(AVFrameRGB.linesize));
+ {$ELSE}
+ errnum := img_convert(PAVPicture(AVFrameRGB), PIXEL_FMT_FFMPEG,
+ PAVPicture(AVFrame), VideoCodecContext^.pix_fmt,
+ VideoCodecContext^.width, VideoCodecContext^.height);
+ {$ENDIF}
+
+ if (errnum < 0) then
+ begin
+ Log.LogError('Image conversion failed', 'TVideoPlayback_ffmpeg.GetFrame');
+ Exit;
+ end;
+
+ {$IFDEF VideoBenchmark}
+ Log.BenchmarkEnd(15);
+ Log.BenchmarkStart(16);
+ {$ENDIF}
+
+ // TODO: data is not padded, so we will need to tell OpenGL.
+ // Or should we add padding with avpicture_fill? (check which one is faster)
+ //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glBindTexture(GL_TEXTURE_2D, fVideoTex);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ VideoCodecContext^.width, VideoCodecContext^.height,
+ PIXEL_FMT_OPENGL, GL_UNSIGNED_BYTE, AVFrameRGB^.data[0]);
+
+ {$ifdef DebugFrames}
+ //frame decode debug display
+ GoldenRec.Spawn(200, 35, 1, 16, 0, -1, ColoredStar, $ffff00);
+ {$endif}
+
+ {$IFDEF VideoBenchmark}
+ Log.BenchmarkEnd(16);
+ Log.LogBenchmark('FFmpeg', 15);
+ Log.LogBenchmark('Texture', 16);
+ {$ENDIF}
+end;
+
+procedure TVideoPlayback_FFmpeg.DrawGL(Screen: integer);
+var
+ TexVideoRightPos, TexVideoLowerPos: Single;
+ ScreenLeftPos, ScreenRightPos: Single;
+ ScreenUpperPos, ScreenLowerPos: Single;
+ ScaledVideoWidth, ScaledVideoHeight: Single;
+ ScreenMidPosX, ScreenMidPosY: Single;
+ ScreenAspect: Single;
+begin
+ // have a nice black background to draw on (even if there were errors opening the vid)
+ if (Screen = 1) then
+ begin
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+
+ // exit if there's nothing to draw
+ if (not fVideoOpened) then
+ Exit;
+
+ {$IFDEF VideoBenchmark}
+ Log.BenchmarkStart(15);
+ {$ENDIF}
+
+ // TODO: add a SetAspectCorrectionMode() function so we can switch
+ // aspect correction. The screens video backgrounds look very ugly with aspect
+ // correction because of the white bars at the top and bottom.
+
+ ScreenAspect := ScreenW / ScreenH;
+ ScaledVideoWidth := RenderW;
+ ScaledVideoHeight := RenderH * ScreenAspect/VideoAspect;
+
+ // Note: Scaling the width does not look good because the video might contain
+ // black borders at the top already
+ //ScaledVideoHeight := RenderH;
+ //ScaledVideoWidth := RenderW * VideoAspect/ScreenAspect;
+
+ // center the video
+ ScreenMidPosX := RenderW/2;
+ ScreenMidPosY := RenderH/2;
+ ScreenLeftPos := ScreenMidPosX - ScaledVideoWidth/2;
+ ScreenRightPos := ScreenMidPosX + ScaledVideoWidth/2;
+ ScreenUpperPos := ScreenMidPosY - ScaledVideoHeight/2;
+ ScreenLowerPos := ScreenMidPosY + ScaledVideoHeight/2;
+ // the video-texture contains empty borders because its width and height must be
+ // a power of 2. So we have to determine the texture coords of the video.
+ TexVideoRightPos := VideoCodecContext^.width / TexWidth;
+ TexVideoLowerPos := VideoCodecContext^.height / TexHeight;
+
+ // we could use blending for brightness control, but do we need this?
+ glDisable(GL_BLEND);
+
+ // TODO: disable other stuff like lightning, etc.
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, fVideoTex);
+ glColor3f(1, 1, 1);
+ glBegin(GL_QUADS);
+ // upper-left coord
+ glTexCoord2f(0, 0);
+ glVertex2f(ScreenLeftPos, ScreenUpperPos);
+ // lower-left coord
+ glTexCoord2f(0, TexVideoLowerPos);
+ glVertex2f(ScreenLeftPos, ScreenLowerPos);
+ // lower-right coord
+ glTexCoord2f(TexVideoRightPos, TexVideoLowerPos);
+ glVertex2f(ScreenRightPos, ScreenLowerPos);
+ // upper-right coord
+ glTexCoord2f(TexVideoRightPos, 0);
+ glVertex2f(ScreenRightPos, ScreenUpperPos);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+
+ {$IFDEF VideoBenchmark}
+ Log.BenchmarkEnd(15);
+ Log.LogBenchmark('DrawGL', 15);
+ {$ENDIF}
+
+ {$IFDEF Info}
+ if (fVideoSkipTime+VideoTime+VideoTimeBase < 0) then
+ begin
+ glColor4f(0.7, 1, 0.3, 1);
+ SetFontStyle (1);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (300, 0);
+ glPrint('Delay due to negative VideoGap');
+ glColor4f(1, 1, 1, 1);
+ end;
+ {$ENDIF}
+
+ {$IFDEF DebugFrames}
+ glColor4f(0, 0, 0, 0.2);
+ glbegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(0, 70);
+ glVertex2f(250, 70);
+ glVertex2f(250, 0);
+ glEnd;
+
+ glColor4f(1, 1, 1, 1);
+ SetFontStyle (1);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (5, 0);
+ glPrint('delaying frame');
+ SetFontPos (5, 20);
+ glPrint('fetching frame');
+ SetFontPos (5, 40);
+ glPrint('dropping frame');
+ {$ENDIF}
+end;
+
+procedure TVideoPlayback_FFmpeg.Play;
+begin
+end;
+
+procedure TVideoPlayback_FFmpeg.Pause;
+begin
+ fVideoPaused := not fVideoPaused;
+end;
+
+procedure TVideoPlayback_FFmpeg.Stop;
+begin
+end;
+
+procedure TVideoPlayback_FFmpeg.SetPosition(Time: real);
+var
+ SeekFlags: integer;
+begin
+ if not fVideoOpened then
+ Exit;
+
+ if (Time < 0) then
+ Time := 0;
+
+ // TODO: handle loop-times
+ //Time := Time mod VideoDuration;
+
+ // backward seeking might fail without AVSEEK_FLAG_BACKWARD
+ SeekFlags := AVSEEK_FLAG_ANY;
+ if (Time < VideoTime) then
+ SeekFlags := SeekFlags or AVSEEK_FLAG_BACKWARD;
+
+ VideoTime := Time;
+ EOF := false;
+
+ if (av_seek_frame(VideoFormatContext, VideoStreamIndex, Floor(Time/VideoTimeBase), SeekFlags) < 0) then
+ begin
+ Log.LogError('av_seek_frame() failed', 'TVideoPlayback_ffmpeg.SetPosition');
+ Exit;
+ end;
+
+ avcodec_flush_buffers(VideoCodecContext);
+end;
+
+function TVideoPlayback_FFmpeg.GetPosition: real;
+begin
+ // TODO: return video-position in seconds
+ Result := VideoTime;
+end;
+
+initialization
+ MediaManager.Add(TVideoPlayback_FFmpeg.Create);
+
+end.
diff --git a/src/Classes/UVisualizer.pas b/src/Classes/UVisualizer.pas
new file mode 100644
index 00000000..e2125201
--- /dev/null
+++ b/src/Classes/UVisualizer.pas
@@ -0,0 +1,442 @@
+unit UVisualizer;
+
+(* TODO:
+ * - fix video/visualizer switching
+ * - use GL_EXT_framebuffer_object for rendering to a separate framebuffer,
+ * this will prevent plugins from messing up our render-context
+ * (-> no stack corruption anymore, no need for Save/RestoreOpenGLState()).
+ * - create a generic (C-compatible) interface for visualization plugins
+ * - create a visualization plugin manager
+ * - write a plugin for projectM in C/C++ (so we need no wrapper anymore)
+ *)
+
+{* Note:
+ * It would be easier to create a seperate Render-Context (RC) for projectM
+ * and switch to it when necessary. This can be achieved by pbuffers
+ * (slow and platform specific) or the OpenGL FramebufferObject (FBO) extension
+ * (fast and plattform-independent but not supported by older graphic-cards/drivers).
+ *
+ * See http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
+ *
+ * To support as many cards as possible we will stick to the current dirty
+ * solution for now even if it is a pain to save/restore projectM's state due
+ * to bugs etc.
+ *
+ * This also restricts us to projectM. As other plug-ins might have different
+ * needs and bugs concerning the OpenGL state, USDX's state would probably be
+ * corrupted after the plug-in finshed drawing.
+ *}
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SDL,
+ UGraphicClasses,
+ textgl,
+ math,
+ gl,
+ SysUtils,
+ UIni,
+ projectM,
+ UMusic;
+
+implementation
+
+uses
+ UGraphic,
+ UMain,
+ UConfig,
+ ULog;
+
+{$IF PROJECTM_VERSION < 1000000} // < 1.0
+// Initialization data used on projectM 0.9x creation.
+// Since projectM 1.0 this data is passed via the config-file.
+const
+ meshX = 32;
+ meshY = 24;
+ fps = 30;
+ textureSize = 512;
+{$IFEND}
+
+type
+ TVideoPlayback_ProjectM = class( TInterfacedObject, IVideoPlayback, IVideoVisualization )
+ private
+ pm: TProjectM;
+ ProjectMPath : string;
+ Initialized: boolean;
+
+ VisualizerStarted: boolean;
+ VisualizerPaused: boolean;
+
+ VisualTex: GLuint;
+ PCMData: TPCMData;
+ RndPCMcount: integer;
+
+ projMatrix: array[0..3, 0..3] of GLdouble;
+ texMatrix: array[0..3, 0..3] of GLdouble;
+
+ procedure VisualizerStart;
+ procedure VisualizerStop;
+
+ procedure VisualizerTogglePause;
+
+ function GetRandomPCMData(var data: TPCMData): Cardinal;
+
+ procedure SaveOpenGLState();
+ procedure RestoreOpenGLState();
+
+ public
+ function GetName: String;
+
+ function Init(): boolean;
+ function Finalize(): boolean;
+
+ function Open(const aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+ end;
+
+
+function TVideoPlayback_ProjectM.GetName: String;
+begin
+ Result := 'ProjectM';
+end;
+
+function TVideoPlayback_ProjectM.Init(): boolean;
+begin
+ Result := true;
+
+ if (Initialized) then
+ Exit;
+ Initialized := true;
+
+ RndPCMcount := 0;
+
+ ProjectMPath := ProjectM_DataDir + PathDelim;
+
+ VisualizerStarted := False;
+ VisualizerPaused := False;
+
+ {$IFDEF UseTexture}
+ glGenTextures(1, PglUint(@VisualTex));
+ glBindTexture(GL_TEXTURE_2D, VisualTex);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ {$ENDIF}
+end;
+
+function TVideoPlayback_ProjectM.Finalize(): boolean;
+begin
+ VisualizerStop();
+ {$IFDEF UseTexture}
+ glDeleteTextures(1, PglUint(@VisualTex));
+ {$ENDIF}
+ Result := true;
+end;
+
+function TVideoPlayback_ProjectM.Open(const aFileName : string): boolean; // true if succeed
+begin
+ Result := false;
+end;
+
+procedure TVideoPlayback_ProjectM.Close;
+begin
+ VisualizerStop();
+end;
+
+procedure TVideoPlayback_ProjectM.Play;
+begin
+ VisualizerStart();
+end;
+
+procedure TVideoPlayback_ProjectM.Pause;
+begin
+ VisualizerTogglePause();
+end;
+
+procedure TVideoPlayback_ProjectM.Stop;
+begin
+ VisualizerStop();
+end;
+
+procedure TVideoPlayback_ProjectM.SetPosition(Time: real);
+begin
+ if assigned(pm) then
+ pm.RandomPreset();
+end;
+
+function TVideoPlayback_ProjectM.GetPosition: real;
+begin
+ Result := 0;
+end;
+
+{**
+ * Saves the current OpenGL state.
+ * This is necessary to prevent projectM from corrupting USDX's current
+ * OpenGL state.
+ *
+ * The following steps are performed:
+ * - All attributes are pushed to the attribute-stack
+ * - Projection-/Texture-matrices are saved
+ * - Modelview-matrix is pushed to the Modelview-stack
+ * - the OpenGL error-state (glGetError) is cleared
+ *}
+procedure TVideoPlayback_ProjectM.SaveOpenGLState();
+begin
+ // save all OpenGL state-machine attributes
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+ // Note: we do not use glPushMatrix() for the GL_PROJECTION and GL_TEXTURE stacks.
+ // OpenGL specifies the depth of those stacks to be at least 2 but projectM
+ // already uses 2 stack-entries so overflows might be possible on older hardware.
+ // In contrast to this the GL_MODELVIEW stack-size is at least 32, so we can
+ // use glPushMatrix() for this stack.
+
+ // save projection-matrix
+ glMatrixMode(GL_PROJECTION);
+ glGetDoublev(GL_PROJECTION_MATRIX, @projMatrix);
+ {$IF PROJECTM_VERSION = 1000000} // 1.0, 1.01
+ // bugfix: projection-matrix is popped without being pushed first
+ glPushMatrix();
+ {$IFEND}
+
+ // save texture-matrix
+ glMatrixMode(GL_TEXTURE);
+ glGetDoublev(GL_TEXTURE_MATRIX, @texMatrix);
+
+ // save modelview-matrix
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ {$IF PROJECTM_VERSION = 1000000} // 1.0, 1.01
+ // bugfix: modelview-matrix is popped without being pushed first
+ glPushMatrix();
+ {$IFEND}
+
+ // reset OpenGL error-state
+ glGetError();
+end;
+
+{**
+ * Restores the OpenGL state saved by SaveOpenGLState()
+ * and resets the error-state.
+ *}
+procedure TVideoPlayback_ProjectM.RestoreOpenGLState();
+begin
+ // reset OpenGL error-state
+ glGetError();
+
+ // restore projection-matrix
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixd(@projMatrix);
+
+ // restore texture-matrix
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixd(@texMatrix);
+
+ // restore modelview-matrix
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ // restore all OpenGL state-machine attributes
+ glPopAttrib();
+end;
+
+procedure TVideoPlayback_ProjectM.VisualizerStart;
+begin
+ if VisualizerStarted then
+ Exit;
+
+ // the OpenGL state must be saved before
+ SaveOpenGLState();
+ try
+
+ try
+ {$IF PROJECTM_VERSION >= 1000000} // >= 1.0
+ pm := TProjectM.Create(ProjectMPath + 'config.inp');
+ {$ELSE}
+ pm := TProjectM.Create(
+ meshX, meshY, fps, textureSize, ScreenW, ScreenH,
+ ProjectMPath + 'presets', ProjectMPath + 'fonts');
+ {$IFEND}
+ except on E: Exception do
+ begin
+ // Create() might fail if the config-file is not found
+ Log.LogError('TProjectM.Create: ' + E.Message, 'TVideoPlayback_ProjectM.VisualizerStart');
+ Exit;
+ end;
+ end;
+
+ // initialize OpenGL
+ pm.ResetGL(ScreenW, ScreenH);
+ // skip projectM default-preset
+ pm.RandomPreset();
+ // projectM >= 1.0 uses the OpenGL FramebufferObject (FBO) extension.
+ // Unfortunately it does NOT reset the framebuffer-context after
+ // TProjectM.Create. Either glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) for
+ // a manual reset or TProjectM.RenderFrame() must be called.
+ // We use the latter so we do not need to load the FBO extension in USDX.
+ pm.RenderFrame();
+
+ VisualizerStarted := True;
+ finally
+ RestoreOpenGLState();
+ end;
+end;
+
+procedure TVideoPlayback_ProjectM.VisualizerStop;
+begin
+ if VisualizerStarted then
+ begin
+ VisualizerStarted := False;
+ FreeAndNil(pm);
+ end;
+end;
+
+procedure TVideoPlayback_ProjectM.VisualizerTogglePause;
+begin
+ VisualizerPaused := not VisualizerPaused;
+end;
+
+procedure TVideoPlayback_ProjectM.GetFrame(Time: Extended);
+var
+ nSamples: cardinal;
+ stackDepth: Integer;
+begin
+ if not VisualizerStarted then
+ Exit;
+
+ if VisualizerPaused then
+ Exit;
+
+ // get audio data
+ nSamples := AudioPlayback.GetPCMData(PcmData);
+
+ // generate some data if non is available
+ if (nSamples = 0) then
+ nSamples := GetRandomPCMData(PcmData);
+
+ // send audio-data to projectM
+ if (nSamples > 0) then
+ pm.AddPCM16Data(PSmallInt(@PcmData), nSamples);
+
+ // store OpenGL state (might be messed up otherwise)
+ SaveOpenGLState();
+ try
+ // setup projectM's OpenGL state
+ pm.ResetGL(ScreenW, ScreenH);
+
+ // let projectM render a frame
+ pm.RenderFrame();
+
+ {$IFDEF UseTexture}
+ glBindTexture(GL_TEXTURE_2D, VisualTex);
+ glFlush();
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, VisualWidth, VisualHeight, 0);
+ {$ENDIF}
+ finally
+ // restore USDX OpenGL state
+ RestoreOpenGLState();
+ end;
+
+ // discard projectM's depth buffer information (avoid overlay)
+ glClear(GL_DEPTH_BUFFER_BIT);
+end;
+
+{**
+ * Draws the current frame to screen.
+ * TODO: this is not used yet. Data is directly drawn on GetFrame().
+ *}
+procedure TVideoPlayback_ProjectM.DrawGL(Screen: integer);
+begin
+ {$IFDEF UseTexture}
+ // have a nice black background to draw on
+ if (Screen = 1) then
+ begin
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+
+ // exit if there's nothing to draw
+ if not VisualizerStarted then
+ Exit;
+
+ // setup display
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ gluOrtho2D(0, 1, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glBindTexture(GL_TEXTURE_2D, VisualTex);
+ glColor4f(1, 1, 1, 1);
+
+ // draw projectM frame
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(0, 0);
+ glTexCoord2f(1, 0); glVertex2f(1, 0);
+ glTexCoord2f(1, 1); glVertex2f(1, 1);
+ glTexCoord2f(0, 1); glVertex2f(0, 1);
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // restore state
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ {$ENDIF}
+end;
+
+{**
+ * Produces random "sound"-data in case no audio-data is available.
+ * Otherwise the visualization will look rather boring.
+ *}
+function TVideoPlayback_ProjectM.GetRandomPCMData(var data: TPCMData): Cardinal;
+var
+ i: integer;
+begin
+ // Produce some fake PCM data
+ if (RndPCMcount mod 500 = 0) then
+ begin
+ FillChar(data, SizeOf(TPCMData), 0);
+ end
+ else
+ begin
+ for i := 0 to 511 do
+ begin
+ data[i][0] := Random(High(Word)+1);
+ data[i][1] := Random(High(Word)+1);
+ end;
+ end;
+ Inc(RndPCMcount);
+ Result := 512;
+end;
+
+
+initialization
+ MediaManager.Add(TVideoPlayback_ProjectM.Create);
+
+end.
diff --git a/src/Classes/UXMLSong.pas b/src/Classes/UXMLSong.pas
new file mode 100644
index 00000000..1a1fe6bc
--- /dev/null
+++ b/src/Classes/UXMLSong.pas
@@ -0,0 +1,573 @@
+unit UXMLSong;
+
+interface
+uses Classes;
+
+type
+ TNote = record
+ Start: Cardinal;
+ Duration: Cardinal;
+ Tone: Integer;
+ NoteTyp: Byte;
+ Lyric: String;
+ end;
+ ANote = Array of TNote;
+
+ TSentence = record
+ Singer: Byte;
+ Duration: Cardinal;
+ Notes: ANote;
+ end;
+ ASentence = Array of TSentence;
+
+ TSongInfo = Record
+ ID: Cardinal;
+ DualChannel: Boolean;
+ Header: Record
+ Artist: String;
+ Title: String;
+ Gap: Cardinal;
+ BPM: Real;
+ Resolution: Byte;
+ Edition: String;
+ Genre: String;
+ Year: String;
+ Language: String;
+ end;
+ CountSentences: Cardinal;
+ Sentences: ASentence;
+ end;
+
+ TParser = class
+ private
+ SSFile: TStringList;
+
+ ParserState: Byte;
+ CurPosinSong: Cardinal; //Cur Beat Pos in the Song
+ CurDuettSinger: Byte; //Who sings this Part?
+ BindLyrics: Boolean; //Should the Lyrics be bind to the last Word (no Space)
+ FirstNote: Boolean; //Is this the First Note found? For Gap calculating
+
+ Function ParseLine(Line: String): Boolean;
+ public
+ SongInfo: TSongInfo;
+ ErrorMessage: String;
+ Edition: String;
+ SingstarVersion: String;
+
+ Settings: Record
+ DashReplacement: Char;
+ end;
+
+ Constructor Create;
+
+ Function ParseConfigforEdition(const Filename: String): String;
+
+ Function ParseSongHeader(const Filename: String): Boolean; //Parse Song Header only
+ Function ParseSong (const Filename: String): Boolean; //Parse whole Song
+ end;
+
+const
+ PS_None = 0;
+ PS_Melody = 1;
+ PS_Sentence = 2;
+
+ NT_Normal = 1;
+ NT_Freestyle = 0;
+ NT_Golden = 2;
+
+ DS_Player1 = 1;
+ DS_Player2 = 2;
+ DS_Both = 3;
+
+implementation
+uses SysUtils, StrUtils;
+
+Constructor TParser.Create;
+begin
+ inherited Create;
+ ErrorMessage := '';
+
+ DecimalSeparator := '.';
+end;
+
+Function TParser.ParseSong (const Filename: String): Boolean;
+var I: Integer;
+begin
+ Result := False;
+ if FileExists(Filename) then
+ begin
+ SSFile := TStringList.Create;
+
+ try
+ ErrorMessage := 'Can''t open melody.xml file';
+ SSFile.LoadFromFile(Filename);
+ ErrorMessage := '';
+ Result := True;
+ I := 0;
+
+ SongInfo.CountSentences := 0;
+ CurDuettSinger := DS_Both; //Both is Singstar Standard
+ CurPosinSong := 0; //Start at Pos 0
+ BindLyrics := True; //Dont start with Space
+ FirstNote := True; //First Note found should be the First Note ;)
+
+ SongInfo.Header.Language := '';
+ SongInfo.Header.Edition := Edition;
+ SongInfo.DualChannel := False;
+
+ ParserState := PS_None;
+
+ SetLength(SongInfo.Sentences, 0);
+
+ While Result And (I < SSFile.Count) do
+ begin
+ Result := ParseLine(SSFile.Strings[I]);
+
+ Inc(I);
+ end;
+
+ finally
+ SSFile.Free;
+ end;
+ end;
+end;
+
+Function TParser.ParseSongHeader (const Filename: String): Boolean;
+var I: Integer;
+begin
+ Result := False;
+ if FileExists(Filename) then
+ begin
+ SSFile := TStringList.Create;
+ SSFile.Clear;
+
+ try
+ SSFile.LoadFromFile(Filename);
+
+ If (SSFile.Count > 0) then
+ begin
+ Result := True;
+ I := 0;
+
+ SongInfo.CountSentences := 0;
+ CurDuettSinger := DS_Both; //Both is Singstar Standard
+ CurPosinSong := 0; //Start at Pos 0
+ BindLyrics := True; //Dont start with Space
+ FirstNote := True; //First Note found should be the First Note ;)
+
+ SongInfo.ID := 0;
+ SongInfo.Header.Language := '';
+ SongInfo.Header.Edition := Edition;
+ SongInfo.DualChannel := False;
+ ParserState := PS_None;
+
+ While (SongInfo.ID < 4) AND Result And (I < SSFile.Count) do
+ begin
+ Result := ParseLine(SSFile.Strings[I]);
+
+ Inc(I);
+ end;
+ end
+ else
+ ErrorMessage := 'Can''t open melody.xml file';
+
+ finally
+ SSFile.Free;
+ end;
+ end
+ else
+ ErrorMessage := 'Can''t find melody.xml file';
+end;
+
+Function TParser.ParseLine(Line: String): Boolean;
+var
+ Tag: String;
+ Values: String;
+ AValues: Array of Record
+ Name: String;
+ Value: String;
+ end;
+ I, J, K: Integer;
+ Duration, Tone: Integer;
+ Lyric: String;
+ NoteType: Byte;
+
+ Procedure MakeValuesArray;
+ var Len, Pos, State, StateChange: Integer;
+ begin
+ Len := -1;
+ SetLength(AValues, Len + 1);
+
+ Pos := 1;
+ State := 0;
+ While (Pos <= Length(Values)) AND (Pos <> 0) do
+ begin
+ Case State of
+
+ 0: begin //Search for ValueName
+ If (Values[Pos] <> ' ') AND (Values[Pos] <> '=') then
+ begin
+ //Found Something
+ State := 1; //State search for '='
+ StateChange := Pos; //Save Pos of Change
+ Pos := PosEx('=', Values, Pos + 1);
+ end
+ else Inc(Pos); //When nothing found then go to next char
+ end;
+
+ 1: begin //Search for Equal Mark
+ //Add New Value
+ Inc(Len);
+ SetLength(AValues, Len + 1);
+
+ AValues[Len].Name := UpperCase(Copy(Values, StateChange, Pos - StateChange));
+
+
+ State := 2; //Now Search for starting '"'
+ StateChange := Pos; //Save Pos of Change
+ Pos := PosEx('"', Values, Pos + 1);
+ end;
+
+ 2: begin //Search for starting '"' or ' ' <- End if there was no "
+ If (Values[Pos] = '"') then
+ begin //Found starting '"'
+ State := 3; //Now Search for ending '"'
+ StateChange := Pos; //Save Pos of Change
+ Pos := PosEx('"', Values, Pos + 1);
+ end
+ else If (Values[Pos] = ' ') then //Found ending Space
+ begin
+ //Save Value to Array
+ AValues[Len].Value := Copy(Values, StateChange + 1, Pos - StateChange - 1);
+
+ //Search for next Valuename
+ State := 0;
+ StateChange := Pos;
+ Inc(Pos);
+ end;
+ end;
+
+ 3: begin //Search for ending '"'
+ //Save Value to Array
+ AValues[Len].Value := Copy(Values, StateChange + 1, Pos - StateChange - 1);
+
+ //Search for next Valuename
+ State := 0;
+ StateChange := Pos;
+ Inc(Pos);
+ end;
+ end;
+
+ If (State >= 2) then
+ begin //Save Last Value
+ AValues[Len].Value := Copy(Values, StateChange + 1, Length(Values) - StateChange);
+ end;
+ end;
+ end;
+begin
+ Result := True;
+
+ Line := Trim(Line);
+ If (Length(Line) > 0) then
+ begin
+ I := Pos('<', Line);
+ J := PosEx(' ', Line, I+1);
+ K := PosEx('>', Line, I+1);
+
+ If (J = 0) then J := K
+ Else If (K < J) AND (K <> 0) then J := K; //Use nearest Tagname End indicator
+ Tag := UpperCase(copy(Line, I + 1, J - I - 1));
+ Values := copy(Line, J + 1, K - J - 1);
+
+ Case ParserState of
+ PS_None: begin//Search for Melody Tag
+ If (Tag = 'MELODY') then
+ begin
+ Inc(SongInfo.ID); //Inc SongID when header Information is added
+ MakeValuesArray;
+ For I := 0 to High(AValues) do
+ begin
+ If (AValues[I].Name = 'TEMPO') then
+ begin
+ SongInfo.Header.BPM := StrtoFloatDef(AValues[I].Value, 0);
+ If (SongInfo.Header.BPM <= 0) then
+ begin
+ Result := False;
+ ErrorMessage := 'Can''t read BPM from Song';
+ end;
+ end
+
+ Else If (AValues[I].Name = 'RESOLUTION') then
+ begin
+ AValues[I].Value := Uppercase(AValues[I].Value);
+ //Ultrastar Resolution is "how often a Beat is split / 4"
+ If (AValues[I].Value = 'HEMIDEMISEMIQUAVER') then
+ SongInfo.Header.Resolution := 64 div 4
+ Else If (AValues[I].Value = 'DEMISEMIQUAVER') then
+ SongInfo.Header.Resolution := 32 div 4
+ Else If (AValues[I].Value = 'SEMIQUAVER') then
+ SongInfo.Header.Resolution := 16 div 4
+ Else If (AValues[I].Value = 'QUAVER') then
+ SongInfo.Header.Resolution := 8 div 4
+ Else If (AValues[I].Value = 'CROTCHET') then
+ SongInfo.Header.Resolution := 4 div 4
+ Else
+ begin //Can't understand teh Resolution :/
+ Result := False;
+ ErrorMessage := 'Can''t read Resolution from Song';
+ end;
+ end
+
+ Else If (AValues[I].Name = 'GENRE') then
+ begin
+ SongInfo.Header.Genre := AValues[I].Value;
+ end
+
+ Else If (AValues[I].Name = 'YEAR') then
+ begin
+ SongInfo.Header.Year := AValues[I].Value;
+ end
+
+ Else If (AValues[I].Name = 'VERSION') then
+ begin
+ SingstarVersion := AValues[I].Value;
+ end;
+ end;
+
+ ParserState := PS_Melody; //In Melody Tag
+ end;
+ end;
+
+
+ PS_Melody: begin //Search for Sentence, Artist/Title Info or eo Melody
+ If (Tag = 'SENTENCE') then
+ begin
+ ParserState := PS_Sentence; //Parse in a Sentence Tag now
+
+ //Increase SentenceCount
+ Inc(SongInfo.CountSentences);
+
+ BindLyrics := True; //Don't let Txts Begin w/ Space
+
+ //Search for Duett Singer Info
+ MakeValuesArray;
+ For I := 0 to High(AValues) do
+ If (AValues[I].Name = 'SINGER') then
+ begin
+ AValues[I].Value := Uppercase(AValues[I].Value);
+ If (AValues[I].Value = 'SOLO 1') then
+ CurDuettSinger := DS_Player1
+ Else If (AValues[I].Value = 'SOLO 2') then
+ CurDuettSinger := DS_Player2
+ Else
+ CurDuettSinger := DS_Both; //In case of "Group" or anything that is not identified use Both
+ end;
+ end
+
+ Else If (Tag = '!--') then
+ begin //Comment, this may be Artist or Title Info
+ I := Pos(':', Values); //Search for Delimiter
+
+ If (I <> 0) then //If Found check for Title or Artist
+ begin
+ //Copy Title or Artist Tag to Tag String
+ Tag := Uppercase(Trim(Copy(Values, 1, I - 1)));
+
+ If (Tag = 'ARTIST') then
+ begin
+ SongInfo.Header.Artist := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
+ Inc(SongInfo.ID); //Inc SongID when header Information is added
+ end
+ Else If (Tag = 'TITLE') then
+ begin
+ SongInfo.Header.Title := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
+ Inc(SongInfo.ID); //Inc SongID when header Information is added
+ end;
+ end;
+ end
+
+ //Parsing for weird "Die toten Hosen" Tags
+ Else If (Tag = '!--ARTIST:') OR (Tag = '!--ARTIST') then
+ begin //Comment, with Artist Info
+ I := Pos(':', Values); //Search for Delimiter
+
+ Inc(SongInfo.ID); //Inc SongID when header Information is added
+
+ SongInfo.Header.Artist := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
+ end
+
+ Else If (Tag = '!--TITLE:') OR (Tag = '!--TITLE') then
+ begin //Comment, with Artist Info
+ I := Pos(':', Values); //Search for Delimiter
+
+ Inc(SongInfo.ID); //Inc SongID when header Information is added
+
+ SongInfo.Header.Title := Trim(Copy(Values, I + 1, Length(Values) - I - 2));
+ end
+
+ Else If (Tag = '/MELODY') then
+ begin
+ ParserState := PS_None;
+ Exit; //Stop Parsing, Melody iTag ended
+ end
+ end;
+
+
+ PS_Sentence: begin //Search for Notes or eo Sentence
+ If (Tag = 'NOTE') then
+ begin //Found Note
+ //Get Values
+ MakeValuesArray;
+
+ NoteType := NT_Normal;
+ For I := 0 to High(AValues) do
+ begin
+ If (AValues[I].Name = 'DURATION') then
+ begin
+ Duration := StrtoIntDef(AValues[I].Value, -1);
+ If (Duration < 0) then
+ begin
+ Result := False;
+ ErrorMessage := 'Can''t read duration from Note in Line: "' + Line + '"';
+ Exit;
+ end;
+ end
+ Else If (AValues[I].Name = 'MIDINOTE') then
+ begin
+ Tone := StrtoIntDef(AValues[I].Value, 0);
+ end
+ Else If (AValues[I].Name = 'BONUS') AND (Uppercase(AValues[I].Value) = 'YES') then
+ begin
+ NoteType := NT_Golden;
+ end
+ Else If (AValues[I].Name = 'FREESTYLE') AND (Uppercase(AValues[I].Value) = 'YES') then
+ begin
+ NoteType := NT_Freestyle;
+ end
+ Else If (AValues[I].Name = 'LYRIC') then
+ begin
+ Lyric := AValues[I].Value;
+
+ If (Length(Lyric) > 0) then
+ begin
+ If (Lyric = '-') then
+ Lyric[1] := Settings.DashReplacement;
+
+ If (not BindLyrics) then
+ Lyric := ' ' + Lyric;
+
+
+ If (Length(Lyric) > 2) AND (Lyric[Length(Lyric)-1] = ' ') AND (Lyric[Length(Lyric)] = '-') then
+ begin //Between this and the next Lyric should be no space
+ BindLyrics := True;
+ SetLength(Lyric, Length(Lyric) - 2);
+ end
+ else
+ BindLyrics := False; //There should be a Space
+ end;
+ end;
+ end;
+
+ //Add Note
+ I := SongInfo.CountSentences - 1;
+
+ If (Length(Lyric) > 0) then
+ begin //Real note, no rest
+ //First Note of Sentence
+ If (Length(SongInfo.Sentences) < SongInfo.CountSentences) then
+ begin
+ SetLength(SongInfo.Sentences, SongInfo.CountSentences);
+ SetLength(SongInfo.Sentences[I].Notes, 0);
+ end;
+
+ //First Note of Song -> Generate Gap
+ If (FirstNote) then
+ begin
+ //Calculate Gap
+ If (SongInfo.Header.Resolution <> 0) AND (SongInfo.Header.BPM <> 0) then
+ SongInfo.Header.Gap := Round(CurPosinSong / (SongInfo.Header.BPM*SongInfo.Header.Resolution) * 60000)
+ Else
+ begin
+ Result := False;
+ ErrorMessage := 'Can''t calculate Gap, no Resolution or BPM present.';
+ Exit;
+ end;
+
+ CurPosinSong := 0; //Start at 0, because Gap goes until here
+ Inc(SongInfo.ID); //Add Header Value therefore Inc
+ FirstNote := False;
+ end;
+
+ J := Length(SongInfo.Sentences[I].Notes);
+ SetLength(SongInfo.Sentences[I].Notes, J + 1);
+ SongInfo.Sentences[I].Notes[J].Start := CurPosinSong;
+ SongInfo.Sentences[I].Notes[J].Duration := Duration;
+ SongInfo.Sentences[I].Notes[J].Tone := Tone;
+ SongInfo.Sentences[I].Notes[J].NoteTyp := NoteType;
+ SongInfo.Sentences[I].Notes[J].Lyric := Lyric;
+
+ //Inc Pos in Song
+ Inc(CurPosInSong, Duration);
+ end
+ else
+ begin
+ //just change pos in Song
+ Inc(CurPosInSong, Duration);
+ end;
+
+
+ end
+ Else If (Tag = '/SENTENCE') then
+ begin //End of Sentence Tag
+ ParserState := PS_Melody;
+
+ //Delete Sentence if no Note is Added
+ If (Length(SongInfo.Sentences) <> SongInfo.CountSentences) then
+ begin
+ SongInfo.CountSentences := Length(SongInfo.Sentences);
+ end;
+ end;
+ end;
+ end;
+
+ end
+ else //Empty Line -> parsed succesful ;)
+ Result := true;
+end;
+
+Function TParser.ParseConfigforEdition(const Filename: String): String;
+var
+ txt: TStringlist;
+ I: Integer;
+ J, K: Integer;
+ S: String;
+begin
+ Result := '';
+ txt := TStringlist.Create;
+ try
+ txt.LoadFromFile(Filename);
+
+ For I := 0 to txt.Count-1 do
+ begin
+ S := Trim(txt.Strings[I]);
+ J := Pos('', S);
+
+ If (J <> 0) then
+ begin
+ Inc(J, 14);
+ K := Pos('', S);
+ If (K nil then write array of TUS_PluginInfo to address at lparam) else (Get PluginInfo of Plugin with Index(wParam) to Address at lParam)
+ function GetPluginState(wParam: TwParam; lParam: TlParam): integer; //If wParam = -1 then (If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TUS_PluginInfo to address at lparam) else (Return PluginInfo of Plugin with Index(wParam))
+
+ end;
+
+ {*********************
+ TtehPlugins
+ Class Represents the Plugins in Module Chain.
+ It Calls the Plugins Procs and Funcs
+ *********************}
+ TtehPlugins = class (TCoreModule)
+ private
+ PluginLoader: PPluginLoader;
+ public
+ //TCoreModule methods to inherit
+ constructor Create; override;
+
+ procedure Info(const pInfo: PModuleInfo); override;
+ function Load: Boolean; override;
+ function Init: Boolean; override;
+ procedure DeInit; override;
+ end;
+
+const
+ {$IFDEF MSWINDOWS}
+ PluginFileExtension = '.dll';
+ {$ENDIF}
+ {$IFDEF LINUX}
+ PluginFileExtension = '.so';
+ {$ENDIF}
+ {$IFDEF DARWIN}
+ PluginFileExtension = '.dylib';
+ {$ENDIF}
+
+implementation
+
+uses
+ UCore,
+ UPluginInterface,
+{$IFDEF MSWINDOWS}
+ windows,
+{$ELSE}
+ dynlibs,
+{$ENDIF}
+ UMain,
+ SysUtils;
+
+{*********************
+ TPluginLoader
+ Implentation
+*********************}
+
+//-------------
+// function that gives some Infos about the Module to the Core
+//-------------
+procedure TPluginLoader.Info(const pInfo: PModuleInfo);
+begin
+ pInfo^.Name := 'TPluginLoader';
+ pInfo^.Version := MakeVersion(1,0,0,chr(0));
+ pInfo^.Description := 'Searches for Plugins, loads and unloads them';
+end;
+
+//-------------
+// Just the Constructor
+//-------------
+constructor TPluginLoader.Create;
+begin
+ inherited;
+
+ //Init PluginInterface
+ //Using Methods from UPluginInterface
+ PluginInterface.CreateHookableEvent := CreateHookableEvent;
+ PluginInterface.DestroyHookableEvent := DestroyHookableEvent;
+ PluginInterface.NotivyEventHooks := NotivyEventHooks;
+ PluginInterface.HookEvent := HookEvent;
+ PluginInterface.UnHookEvent := UnHookEvent;
+ PluginInterface.EventExists := EventExists;
+
+ PluginInterface.CreateService := @CreateService;
+ PluginInterface.DestroyService := DestroyService;
+ PluginInterface.CallService := CallService;
+ PluginInterface.ServiceExists := ServiceExists;
+
+ //UnSet Private Var
+ LoadingProcessFinished := False;
+end;
+
+//-------------
+//Is Called on Loading.
+//In this Method only Events and Services should be created
+//to offer them to other Modules or Plugins during the Init process
+//If False is Returned this will cause a Forced Exit
+//-------------
+function TPluginLoader.Load: Boolean;
+begin
+ Result := True;
+
+ try
+ //Start Searching for Plugins
+ BrowseDir(PluginPath);
+ except
+ Result := False;
+ Core.ReportError(integer(PChar('Error Browsing and Loading.')), PChar('TPluginLoader'));
+ end;
+end;
+
+//-------------
+//Is Called on Init Process
+//In this Method you can Hook some Events and Create + Init
+//your Classes, Variables etc.
+//If False is Returned this will cause a Forced Exit
+//-------------
+function TPluginLoader.Init: Boolean;
+begin
+ //Just set Prvate Var to true.
+ LoadingProcessFinished := True;
+ Result := True;
+end;
+
+//-------------
+//Is Called if this Module has been Inited and there is a Exit.
+//Deinit is in backwards Initing Order
+//-------------
+procedure TPluginLoader.DeInit;
+var
+ I: integer;
+begin
+ //Force DeInit
+ //If some Plugins aren't DeInited for some Reason o0
+ for I := 0 to High(Plugins) do
+ begin
+ if (Plugins[I].State < 4) then
+ FreePlugin(I);
+ end;
+
+ //Nothing to do here. Core will remove the Hooks
+end;
+
+//-------------
+//Is Called if this Module will be unloaded and has been created
+//Should be used to Free Memory
+//-------------
+Destructor TPluginLoader.Destroy;
+begin
+ //Just save some Memory if it wasn't done now..
+ SetLength(Plugins, 0);
+ inherited;
+end;
+
+//--------------
+// Browses the Path at _Path_ for Plugins
+//--------------
+procedure TPluginLoader.BrowseDir(Path: String);
+var
+ SR: TSearchRec;
+begin
+ //Search for other Dirs to Browse
+ if FindFirst(Path + '*', faDirectory, SR) = 0 then begin
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ BrowseDir(Path + Sr.Name + PathDelim);
+ until FindNext(SR) <> 0;
+ end;
+ FindClose(SR);
+
+ //Search for Plugins at Path
+ if FindFirst(Path + '*' + PluginFileExtension, 0, SR) = 0 then
+ begin
+ repeat
+ AddPlugin(Path + SR.Name);
+ until FindNext(SR) <> 0;
+ end;
+ FindClose(SR);
+end;
+
+//--------------
+// If Plugin Exists: Index of Plugin, else -1
+//--------------
+function TPluginLoader.PluginExists(Name: String): integer;
+var
+ I: integer;
+begin
+ Result := -1;
+
+ if (Length(Name) <= 32 { =>Length(TUS_PluginInfo.Name)}) then
+ begin
+ for I := 0 to High(Plugins) do
+ if (Plugins[I].Info.Name = Name) then
+ begin //Found the Plugin
+ Result := I;
+ Break;
+ end;
+ end;
+end;
+
+//--------------
+// Adds Plugin to the Array
+//--------------
+procedure TPluginLoader.AddPlugin(Filename: String);
+var
+ hLib: THandle;
+ PInfo: Proc_PluginInfo;
+ Info: TUS_PluginInfo;
+ PluginID: integer;
+begin
+ if (FileExists(Filename)) then
+ begin //Load Libary
+ hLib := LoadLibrary(PChar(Filename));
+ if (hLib <> 0) then
+ begin //Try to get Address of the Info Proc
+ PInfo := GetProcAddress (hLib, PChar('USPlugin_Info'));
+ if (@PInfo <> nil) then
+ begin
+ Info.cbSize := SizeOf(TUS_PluginInfo);
+
+ try //Call Info Proc
+ PInfo(@Info);
+ except
+ Info.Name := '';
+ Core.ReportError(integer(PChar('Error getting Plugin Info: ' + Filename)), PChar('TPluginLoader'));
+ end;
+
+ //Is Name set ?
+ if (Trim(Info.Name) <> '') then
+ begin
+ PluginID := PluginExists(Info.Name);
+
+ if (PluginID > 0) and (Plugins[PluginID].State >=4) then
+ PluginID := -1;
+
+ if (PluginID = -1) then
+ begin
+ //Add new item to array
+ PluginID := Length(Plugins);
+ SetLength(Plugins, PluginID + 1);
+
+ //Fill with Info:
+ Plugins[PluginID].Info := Info;
+ Plugins[PluginID].State := 0;
+ Plugins[PluginID].Path := Filename;
+ Plugins[PluginID].NeedsDeInit := False;
+ Plugins[PluginID].hLib := hLib;
+
+ //Try to get Procs
+ Plugins[PluginID].Procs.Load := GetProcAddress (hLib, PChar('USPlugin_Load'));
+ Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
+ Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
+
+ if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
+ begin
+ Plugins[PluginID].State := 255;
+ FreeLibrary(hLib);
+ Core.ReportError(integer(PChar('Can''t get Plugin Procs from Libary: "' + Info.Name + '" ' + Filename)), PChar('TPluginLoader'));
+ end;
+
+ //Emulate loading process if this Plugin is loaded to late
+ if (LoadingProcessFinished) then
+ begin
+ CallLoad(PluginID);
+ CallInit(PluginID);
+ end;
+ end
+ else if (LoadingProcessFinished = False) then
+ begin
+ if (Plugins[PluginID].Info.Version < Info.Version) then
+ begin //Found newer Version of this Plugin
+ Core.ReportDebug(integer(PChar('Found a newer Version of Plugin: ' + String(Info.Name))), PChar('TPluginLoader'));
+
+ //Unload Old Plugin
+ UnloadPlugin(PluginID, nil);
+
+ //Fill with new Info
+ Plugins[PluginID].Info := Info;
+ Plugins[PluginID].State := 0;
+ Plugins[PluginID].Path := Filename;
+ Plugins[PluginID].NeedsDeInit := False;
+ Plugins[PluginID].hLib := hLib;
+
+ //Try to get Procs
+ Plugins[PluginID].Procs.Load := GetProcAddress (hLib, PChar('USPlugin_Load'));
+ Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
+ Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
+
+ if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
+ begin
+ FreeLibrary(hLib);
+ Plugins[PluginID].State := 255;
+ Core.ReportError(integer(PChar('Can''t get Plugin Procs from Libary: "' + Info.Name + '" ' + Filename)), PChar('TPluginLoader'));
+ end;
+ end
+ else
+ begin //Newer Version already loaded
+ FreeLibrary(hLib);
+ end;
+ end
+ else
+ begin
+ FreeLibrary(hLib);
+ Core.ReportError(integer(PChar('Plugin with this Name already exists: ' + String(Info.Name))), PChar('TPluginLoader'));
+ end;
+ end
+ else
+ begin
+ FreeLibrary(hLib);
+ Core.ReportError(integer(PChar('No name reported: ' + Filename)), PChar('TPluginLoader'));
+ end;
+ end
+ else
+ begin
+ FreeLibrary(hLib);
+ Core.ReportError(integer(PChar('Can''t find Info procedure: ' + Filename)), PChar('TPluginLoader'));
+ end;
+ end
+ else
+ Core.ReportError(integer(PChar('Can''t load Plugin Libary: ' + Filename)), PChar('TPluginLoader'));
+ end;
+end;
+
+//--------------
+// Calls Load Func of Plugin with the given Index
+//--------------
+function TPluginLoader.CallLoad(Index: Cardinal): integer;
+begin
+ Result := -2;
+ if(Index < Length(Plugins)) then
+ begin
+ if (@Plugins[Index].Procs.Load <> nil) and (Plugins[Index].State = 0) then
+ begin
+ try
+ Result := Plugins[Index].Procs.Load(@PluginInterface);
+ except
+ Result := -3;
+ End;
+
+ if (Result = 0) then
+ Plugins[Index].State := 1
+ else
+ begin
+ FreePlugin(Index);
+ Plugins[Index].State := 255;
+ Core.ReportError(integer(PChar('Error calling Load function from Plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
+ end;
+ end;
+ end;
+end;
+
+//--------------
+// Calls Init Func of Plugin with the given Index
+//--------------
+function TPluginLoader.CallInit(Index: Cardinal): integer;
+begin
+ Result := -2;
+ if(Index < Length(Plugins)) then
+ begin
+ if (@Plugins[Index].Procs.Init <> nil) and (Plugins[Index].State = 1) then
+ begin
+ try
+ Result := Plugins[Index].Procs.Init(@PluginInterface);
+ except
+ Result := -3;
+ End;
+
+ if (Result = 0) then
+ begin
+ Plugins[Index].State := 2;
+ Plugins[Index].NeedsDeInit := True;
+ end
+ else
+ begin
+ FreePlugin(Index);
+ Plugins[Index].State := 255;
+ Core.ReportError(integer(PChar('Error calling Init function from Plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
+ end;
+ end;
+ end;
+end;
+
+//--------------
+// Calls DeInit Proc of Plugin with the given Index
+//--------------
+procedure TPluginLoader.CallDeInit(Index: Cardinal);
+begin
+ if(Index < Length(Plugins)) then
+ begin
+ if (Plugins[Index].State < 4) then
+ begin
+ if (@Plugins[Index].Procs.DeInit <> nil) and (Plugins[Index].NeedsDeInit) then
+ try
+ Plugins[Index].Procs.DeInit(@PluginInterface);
+ except
+
+ End;
+
+ //Don't forget to remove Services and Subscriptions by this Plugin
+ Core.Hooks.DelbyOwner(-1 - Index);
+
+ FreePlugin(Index);
+ end;
+ end;
+end;
+
+//--------------
+// Frees all Plugin Sources (Procs and Handles) - Helper for Deiniting Functions
+//--------------
+procedure TPluginLoader.FreePlugin(Index: Cardinal);
+begin
+ Plugins[Index].State := 4;
+ Plugins[Index].Procs.Load := nil;
+ Plugins[Index].Procs.Init := nil;
+ Plugins[Index].Procs.DeInit := nil;
+
+ if (Plugins[Index].hLib <> 0) then
+ FreeLibrary(Plugins[Index].hLib);
+end;
+
+
+
+//--------------
+// wParam PChar(PluginName/PluginPath) | wParam (if lParam = nil) ID of the Plugin
+//--------------
+function TPluginLoader.LoadPlugin(wParam: TwParam; lParam: TlParam): integer;
+var
+ Index: integer;
+ sFile: String;
+begin
+ Result := -1;
+ sFile := '';
+ //lParam is ID
+ if (lParam = nil) then
+ begin
+ Index := wParam;
+ end
+ else
+ begin //lParam is PChar
+ try
+ sFile := String(PChar(lParam));
+ Index := PluginExists(sFile);
+ if (Index < 0) And FileExists(sFile) then
+ begin //Is Filename
+ AddPlugin(sFile);
+ Result := Plugins[High(Plugins)].State;
+ end;
+ except
+ Index := -2;
+ end;
+ end;
+
+
+ if (Index >= 0) and (Index < Length(Plugins)) then
+ begin
+ AddPlugin(Plugins[Index].Path);
+ Result := Plugins[Index].State;
+ end;
+end;
+
+//--------------
+// wParam PChar(PluginName/PluginPath) | wParam (if lParam = nil) ID of the Plugin
+//--------------
+function TPluginLoader.UnloadPlugin(wParam: TwParam; lParam: TlParam): integer;
+var
+ Index: integer;
+ sName: String;
+begin
+ Result := -1;
+ //lParam is ID
+ if (lParam = nil) then
+ begin
+ Index := wParam;
+ end
+ else
+ begin //wParam is PChar
+ try
+ sName := String(PChar(lParam));
+ Index := PluginExists(sName);
+ except
+ Index := -2;
+ end;
+ end;
+
+
+ if (Index >= 0) and (Index < Length(Plugins)) then
+ CallDeInit(Index)
+end;
+
+//--------------
+// if wParam = -1 then (if lParam = nil then get length of Moduleinfo Array. if lparam <> nil then write array of TUS_PluginInfo to address at lparam) else (Get PluginInfo of Plugin with Index(wParam) to Address at lParam)
+//--------------
+function TPluginLoader.GetPluginInfo(wParam: TwParam; lParam: TlParam): integer;
+var I: integer;
+begin
+ Result := 0;
+ if (wParam > 0) then
+ begin //Get Info of 1 Plugin
+ if (lParam <> nil) and (wParam < Length(Plugins)) then
+ begin
+ try
+ Result := 1;
+ PUS_PluginInfo(lParam)^ := Plugins[wParam].Info;
+ except
+
+ End;
+ end;
+ end
+ else if (lParam = nil) then
+ begin //Get Length of Plugin (Info) Array
+ Result := Length(Plugins);
+ end
+ else //Write PluginInfo Array to Address in lParam
+ begin
+ try
+ for I := 0 to high(Plugins) do
+ PAUS_PluginInfo(lParam)^[I] := Plugins[I].Info;
+ Result := Length(Plugins);
+ except
+ Core.ReportError(integer(PChar('Could not write PluginInfo Array')), PChar('TPluginLoader'));
+ End;
+ end;
+
+end;
+
+//--------------
+// if wParam = -1 then (if lParam = nil then get length of Plugin State Array. if lparam <> nil then write array of Byte to address at lparam) else (Return State of Plugin with Index(wParam))
+//--------------
+function TPluginLoader.GetPluginState(wParam: TwParam; lParam: TlParam): integer;
+var I: integer;
+begin
+ Result := -1;
+ if (wParam > 0) then
+ begin //Get State of 1 Plugin
+ if (wParam < Length(Plugins)) then
+ begin
+ Result := Plugins[wParam].State;
+ end;
+ end
+ else if (lParam = nil) then
+ begin //Get Length of Plugin (Info) Array
+ Result := Length(Plugins);
+ end
+ else //Write PluginInfo Array to Address in lParam
+ begin
+ try
+ for I := 0 to high(Plugins) do
+ Byte(Pointer(integer(lParam) + I)^) := Plugins[I].State;
+ Result := Length(Plugins);
+ except
+ Core.ReportError(integer(PChar('Could not write PluginState Array')), PChar('TPluginLoader'));
+ End;
+ end;
+end;
+
+
+{*********************
+ TtehPlugins
+ Implentation
+*********************}
+
+//-------------
+// function that gives some Infos about the Module to the Core
+//-------------
+procedure TtehPlugins.Info(const pInfo: PModuleInfo);
+begin
+ pInfo^.Name := 'TtehPlugins';
+ pInfo^.Version := MakeVersion(1,0,0,chr(0));
+ pInfo^.Description := 'Module executing the Plugins!';
+end;
+
+//-------------
+// Just the Constructor
+//-------------
+constructor TtehPlugins.Create;
+begin
+ inherited;
+ PluginLoader := nil;
+end;
+
+//-------------
+//Is Called on Loading.
+//In this Method only Events and Services should be created
+//to offer them to other Modules or Plugins during the Init process
+//If False is Returned this will cause a Forced Exit
+//-------------
+function TtehPlugins.Load: Boolean;
+var
+ i: integer; //Counter
+ CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
+begin
+ //Get Pointer to PluginLoader
+ PluginLoader := PPluginLoader(Core.GetModulebyName('TPluginLoader'));
+ if (PluginLoader = nil) then
+ begin
+ Result := false;
+ Core.ReportError(integer(PChar('Could not get Pointer to PluginLoader')), PChar('TtehPlugins'));
+ end
+ else
+ begin
+ Result := true;
+
+ //Backup CurExecuted
+ CurExecutedBackup := Core.CurExecuted;
+
+ //Start Loading the Plugins
+ for i := 0 to High(PluginLoader.Plugins) do
+ begin
+ Core.CurExecuted := -1 - i;
+
+ try
+ //Unload Plugin if not correctly Executed
+ if (PluginLoader.CallLoad(i) <> 0) then
+ begin
+ PluginLoader.CallDeInit(i);
+ PluginLoader.Plugins[i].State := 254; //Plugin asks for unload
+ Core.ReportDebug(integer(PChar('Plugin Selfabort during loading process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ end
+ else
+ begin
+ Core.ReportDebug(integer(PChar('Plugin loaded succesful: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ end;
+ except
+ //Plugin could not be loaded.
+ // => Show Error Message, then ShutDown Plugin
+ on E: Exception do
+ begin
+ PluginLoader.CallDeInit(i);
+ PluginLoader.Plugins[i].State := 255; //Plugin causes Error
+ Core.ReportError(integer(PChar('Plugin causes Error during loading process: ' + PluginLoader.Plugins[i].Info.Name + ', ErrorMsg: "' + E.Message + '"')), PChar('TtehPlugins'));
+ end;
+ end;
+ end;
+
+ //Reset CurExecuted
+ Core.CurExecuted := CurExecutedBackup;
+ end;
+end;
+
+//-------------
+//Is Called on Init Process
+//In this Method you can Hook some Events and Create + Init
+//your Classes, Variables etc.
+//If False is Returned this will cause a Forced Exit
+//-------------
+function TtehPlugins.Init: Boolean;
+var
+ i: integer; //Counter
+ CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
+begin
+ Result := true;
+
+ //Backup CurExecuted
+ CurExecutedBackup := Core.CurExecuted;
+
+ //Start Loading the Plugins
+ for i := 0 to High(PluginLoader.Plugins) do
+ try
+ Core.CurExecuted := -1 - i;
+
+ //Unload Plugin if not correctly Executed
+ if (PluginLoader.CallInit(i) <> 0) then
+ begin
+ PluginLoader.CallDeInit(i);
+ PluginLoader.Plugins[i].State := 254; //Plugin asks for unload
+ Core.ReportDebug(integer(PChar('Plugin Selfabort during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ end
+ else
+ Core.ReportDebug(integer(PChar('Plugin inited succesful: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ except
+ //Plugin could not be loaded.
+ // => Show Error Message, then ShutDown Plugin
+ PluginLoader.CallDeInit(i);
+ PluginLoader.Plugins[i].State := 255; //Plugin causes Error
+ Core.ReportError(integer(PChar('Plugin causes Error during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ end;
+
+ //Reset CurExecuted
+ Core.CurExecuted := CurExecutedBackup;
+end;
+
+//-------------
+//Is Called if this Module has been Inited and there is a Exit.
+//Deinit is in backwards Initing Order
+//-------------
+procedure TtehPlugins.DeInit;
+var
+ i: integer; //Counter
+ CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
+begin
+ //Backup CurExecuted
+ CurExecutedBackup := Core.CurExecuted;
+
+ //Start Loop
+
+ for i := 0 to High(PluginLoader.Plugins) do
+ begin
+ try
+ //DeInit Plugin
+ PluginLoader.CallDeInit(i);
+ except
+ end;
+ end;
+
+ //Reset CurExecuted
+ Core.CurExecuted := CurExecutedBackup;
+end;
+
+end.
diff --git a/src/MacOSX/English.lproj/InfoPlist.strings b/src/MacOSX/English.lproj/InfoPlist.strings
new file mode 100755
index 00000000..ce30d99a
Binary files /dev/null and b/src/MacOSX/English.lproj/InfoPlist.strings differ
diff --git a/src/MacOSX/English.lproj/SDLMain.nib/classes.nib b/src/MacOSX/English.lproj/SDLMain.nib/classes.nib
new file mode 100644
index 00000000..799eaadd
--- /dev/null
+++ b/src/MacOSX/English.lproj/SDLMain.nib/classes.nib
@@ -0,0 +1,19 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {
+ help = id;
+ newGame = id;
+ openGame = id;
+ prefsMenu = id;
+ saveGame = id;
+ saveGameAs = id;
+ };
+ CLASS = SDLMain;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ }
+ );
+ IBVersion = 1;
+}
\ No newline at end of file
diff --git a/src/MacOSX/English.lproj/SDLMain.nib/info.nib b/src/MacOSX/English.lproj/SDLMain.nib/info.nib
new file mode 100644
index 00000000..1d6fb7e0
--- /dev/null
+++ b/src/MacOSX/English.lproj/SDLMain.nib/info.nib
@@ -0,0 +1,21 @@
+
+
+
+
+ IBDocumentLocation
+ 62 117 356 240 0 0 1152 848
+ IBEditorPositions
+
+ 29
+ 62 362 195 44 0 0 1152 848
+
+ IBFramework Version
+ 291.0
+ IBOpenObjects
+
+ 29
+
+ IBSystem Version
+ 6L60
+
+
diff --git a/src/MacOSX/English.lproj/SDLMain.nib/objects.nib b/src/MacOSX/English.lproj/SDLMain.nib/objects.nib
new file mode 100644
index 00000000..63780152
Binary files /dev/null and b/src/MacOSX/English.lproj/SDLMain.nib/objects.nib differ
diff --git a/src/MacOSX/Info.plist b/src/MacOSX/Info.plist
new file mode 100644
index 00000000..a62966cf
--- /dev/null
+++ b/src/MacOSX/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleDisplayName
+ UltraStarDeluxe
+ CFBundleExecutable
+ ultrastardx
+ CFBundleGetInfoString
+ UltraStarDeluxe, a SingStar clone
+ CFBundleIconFile
+ ustar-icon_v01.icns
+ CFBundleIdentifier
+ org.ultrastardeluxe.ultrastardeluxe
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ UltraStarDeluxe
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ USDX
+ CFBundleVersion
+ 1.0
+ LSExecutableArchitectures
+ i386
+ NSAppleScriptEnabled
+
+ NSHumanReadableCopyright
+ LGPL
+ NSMainNibFile
+ SDLMain
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1 b/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
new file mode 100644
index 00000000..578575c4
--- /dev/null
+++ b/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
@@ -0,0 +1,1408 @@
+
+
+
+
+ ActivePerspectiveName
+ Project
+ AllowedModules
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXSmartGroupTreeModule
+ Name
+ Groups and Files Outline View
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXNavigatorGroup
+ Name
+ Editor
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCTaskListModule
+ Name
+ Task List
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCDetailModule
+ Name
+ File and Smart Group Detail Viewer
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXBuildResultsModule
+ Name
+ Detailed Build Results Viewer
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXProjectFindModule
+ Name
+ Project Batch Find Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXRunSessionModule
+ Name
+ Run Log
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXBookmarksModule
+ Name
+ Bookmarks Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXClassBrowserModule
+ Name
+ Class Browser
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXCVSModule
+ Name
+ Source Code Control Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXDebugBreakpointsModule
+ Name
+ Debug Breakpoints Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCDockableInspector
+ Name
+ Inspector
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXOpenQuicklyModule
+ Name
+ Open Quickly Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXDebugSessionModule
+ Name
+ Debugger
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXDebugCLIModule
+ Name
+ Debug Console
+
+
+ Description
+ DefaultDescriptionKey
+ DockingSystemVisible
+
+ Extension
+ mode1
+ FavBarConfig
+
+ PBXProjectModuleGUID
+ 2CDD4B6F0CB935C700549FAC
+ XCBarModuleItemNames
+
+ XCBarModuleItems
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ com.apple.perspectives.project.mode1
+ MajorVersion
+ 31
+ MinorVersion
+ 1
+ Name
+ Default
+ Notifications
+
+ OpenEditors
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CAE5FE50CE3B914009D9EF2
+ PBXProjectModuleLabel
+ USongs.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CAE5FE60CE3B914009D9EF2
+ PBXProjectModuleLabel
+ USongs.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CF1EFD70CE77D5600B5167D
+ history
+
+ 2C0B367E0CE3D50000158AB2
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {797, 748}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 15 212 797 789 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CC28B200CE3C14E00D16793
+ PBXProjectModuleLabel
+ UPlatformWindows.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CC28B210CE3C14E00D16793
+ PBXProjectModuleLabel
+ UPlatformWindows.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CF1EFD80CE77D5600B5167D
+ history
+
+ 2C0B367F0CE3D50000158AB2
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {776, 859}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 15 123 776 900 0 0 1680 1028
+
+
+
+ PerspectiveWidths
+
+ -1
+ -1
+
+ Perspectives
+
+
+ ChosenToolbarItems
+
+ active-target-popup
+ active-buildstyle-popup
+ action
+ NSToolbarFlexibleSpaceItem
+ buildOrClean
+ build-and-runOrDebug
+ com.apple.ide.PBXToolbarStopButton
+ get-info
+ toggle-editor
+ NSToolbarFlexibleSpaceItem
+ com.apple.pbx.toolbar.searchfield
+
+ ControllerClassBaseName
+
+ IconName
+ WindowOfProjectWithEditor
+ Identifier
+ perspective.project
+ IsVertical
+
+ Layout
+
+
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+ 1C08E77C0454961000C914BD
+ 1C37FABC05509CD000000102
+ 1C37FABC05539CD112110102
+ E2644B35053B69B200211256
+ 1C37FABC04509CD000100104
+ 1CC0EA4004350EF90044410B
+ 1CC0EA4004350EF90041110B
+
+ PBXProjectModuleGUID
+ 1CE0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ yes
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 266
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ DDC6850D09F5717A004E4BFF
+ DD7C45450A6E72DE003FA52B
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 17
+ 15
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 0}, {266, 694}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+
+ XCSharingToken
+ com.apple.Xcode.GFSharingToken
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {283, 712}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 266
+
+ RubberWindowFrame
+ 858 143 817 753 0 0 1680 1028
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 283pt
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CE0B20306471E060097A5F4
+ PBXProjectModuleLabel
+
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 1CE0B20406471E060097A5F4
+ PBXProjectModuleLabel
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {529, 0}}
+ RubberWindowFrame
+ 858 143 817 753 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 0pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CE0B20506471E060097A5F4
+ PBXProjectModuleLabel
+ Detail
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 5}, {529, 707}}
+ RubberWindowFrame
+ 858 143 817 753 0 0 1680 1028
+
+ Module
+ XCDetailModule
+ Proportion
+ 707pt
+
+
+ Proportion
+ 529pt
+
+
+ Name
+ Project
+ ServiceClasses
+
+ XCModuleDock
+ PBXSmartGroupTreeModule
+ XCModuleDock
+ PBXNavigatorGroup
+ XCDetailModule
+
+ TableOfContents
+
+ 2CF1EFD10CE77D5600B5167D
+ 1CE0B1FE06471DED0097A5F4
+ 2CF1EFD20CE77D5600B5167D
+ 1CE0B20306471E060097A5F4
+ 1CE0B20506471E060097A5F4
+
+ ToolbarConfiguration
+ xcode.toolbar.config.default
+
+
+ ControllerClassBaseName
+
+ IconName
+ WindowOfProject
+ Identifier
+ perspective.morph
+ IsVertical
+ 0
+ Layout
+
+
+ BecomeActive
+ 1
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+ 1C08E77C0454961000C914BD
+ 1C37FABC05509CD000000102
+ 1C37FABC05539CD112110102
+ E2644B35053B69B200211256
+ 1C37FABC04509CD000100104
+ 1CC0EA4004350EF90044410B
+ 1CC0EA4004350EF90041110B
+
+ PBXProjectModuleGUID
+ 11E0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ yes
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 186
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ 29B97314FDCFA39411CA2CEA
+ 1C37FABC05509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 0}, {186, 337}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+ 1
+ XCSharingToken
+ com.apple.Xcode.GFSharingToken
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {203, 355}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 186
+
+ RubberWindowFrame
+ 373 269 690 397 0 0 1440 878
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 100%
+
+
+ Name
+ Morph
+ PreferredWidth
+ 300
+ ServiceClasses
+
+ XCModuleDock
+ PBXSmartGroupTreeModule
+
+ TableOfContents
+
+ 11E0B1FE06471DED0097A5F4
+
+ ToolbarConfiguration
+ xcode.toolbar.config.default.short
+
+
+ PerspectivesBarVisible
+
+ ShelfIsVisible
+
+ SourceDescription
+ file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'
+ StatusbarIsVisible
+
+ TimeStamp
+ 0.0
+ ToolbarDisplayMode
+ 1
+ ToolbarIsVisible
+
+ ToolbarSizeMode
+ 1
+ Type
+ Perspectives
+ UpdateMessage
+ The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?
+ WindowJustification
+ 5
+ WindowOrderList
+
+ 2CC28B200CE3C14E00D16793
+ 2CAE5FE50CE3B914009D9EF2
+ 1C0AD2B3069F1EA900FABCE6
+ /Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj
+
+ WindowString
+ 858 143 817 753 0 0 1680 1028
+ WindowTools
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.build
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD0528F0623707200166675
+ PBXProjectModuleLabel
+
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {1346, 566}}
+ RubberWindowFrame
+ 106 169 1346 848 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 566pt
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ XCMainBuildResultsModuleGUID
+ PBXProjectModuleLabel
+ Build
+ XCBuildResultsTrigger_Collapse
+ 1021
+ XCBuildResultsTrigger_Open
+ 1011
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 571}, {1346, 236}}
+ RubberWindowFrame
+ 106 169 1346 848 0 0 1680 1028
+
+ Module
+ PBXBuildResultsModule
+ Proportion
+ 236pt
+
+
+ Proportion
+ 807pt
+
+
+ Name
+ Build Results
+ ServiceClasses
+
+ PBXBuildResultsModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 2CDD4B730CB935C700549FAC
+ 2C0B36810CE3D50000158AB2
+ 1CD0528F0623707200166675
+ XCMainBuildResultsModuleGUID
+
+ ToolbarConfiguration
+ xcode.toolbar.config.build
+ WindowString
+ 106 169 1346 848 0 0 1680 1028
+ WindowToolGUID
+ 2CDD4B730CB935C700549FAC
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.debugger
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ Debugger
+
+ HorizontalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {333, 414}}
+ {{333, 0}, {631, 414}}
+
+
+ VerticalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {964, 414}}
+ {{0, 414}, {964, 374}}
+
+
+
+ LauncherConfigVersion
+ 8
+ PBXProjectModuleGUID
+ 1C162984064C10D400B95A72
+ PBXProjectModuleLabel
+ Debug - GLUTExamples (Underwater)
+
+ GeometryConfiguration
+
+ DebugConsoleDrawerSize
+ {100, 120}
+ DebugConsoleVisible
+ None
+ DebugConsoleWindowFrame
+ {{200, 200}, {500, 300}}
+ DebugSTDIOWindowFrame
+ {{200, 200}, {500, 300}}
+ Frame
+ {{0, 0}, {964, 788}}
+ RubberWindowFrame
+ 227 162 964 829 0 0 1680 1028
+
+ Module
+ PBXDebugSessionModule
+ Proportion
+ 788pt
+
+
+ Proportion
+ 788pt
+
+
+ Name
+ Debugger
+ ServiceClasses
+
+ PBXDebugSessionModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1CD10A99069EF8BA00B06720
+ 2C89371D0CE3926A005D8A87
+ 1C162984064C10D400B95A72
+ 2C89371E0CE3926A005D8A87
+ 2C89371F0CE3926A005D8A87
+ 2C8937200CE3926A005D8A87
+ 2C8937210CE3926A005D8A87
+ 2C8937220CE3926A005D8A87
+ 2C8937230CE3926A005D8A87
+
+ ToolbarConfiguration
+ xcode.toolbar.config.debug
+ WindowString
+ 227 162 964 829 0 0 1680 1028
+ WindowToolGUID
+ 1CD10A99069EF8BA00B06720
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.find
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ Dock
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CDD528C0622207200134675
+ PBXProjectModuleLabel
+ UCommon.pas
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {790, 502}}
+ RubberWindowFrame
+ 821 68 790 888 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 790pt
+
+
+ Proportion
+ 502pt
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD0528E0623707200166675
+ PBXProjectModuleLabel
+ Project Find
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 507}, {790, 340}}
+ RubberWindowFrame
+ 821 68 790 888 0 0 1680 1028
+
+ Module
+ PBXProjectFindModule
+ Proportion
+ 340pt
+
+
+ Proportion
+ 847pt
+
+
+ Name
+ Project Find
+ ServiceClasses
+
+ PBXProjectFindModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C530D57069F1CE1000CFCEE
+ 2C5C69C90CE3B3AF00545A7B
+ 2C5C69CA0CE3B3AF00545A7B
+ 1CDD528C0622207200134675
+ 1CD0528E0623707200166675
+
+ WindowString
+ 821 68 790 888 0 0 1680 1028
+ WindowToolGUID
+ 1C530D57069F1CE1000CFCEE
+ WindowToolIsVisible
+
+
+
+ Identifier
+ MENUSEPARATOR
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.debuggerConsole
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1C78EAAC065D492600B07095
+ PBXProjectModuleLabel
+ Debugger Console
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {1245, 708}}
+ RubberWindowFrame
+ 410 84 1245 749 0 0 1680 1028
+
+ Module
+ PBXDebugCLIModule
+ Proportion
+ 708pt
+
+
+ Proportion
+ 708pt
+
+
+ Name
+ Debugger Console
+ ServiceClasses
+
+ PBXDebugCLIModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 2CDD4BFC0CB948FC00549FAC
+ 2C8937D00CE3A1FF005D8A87
+ 1C78EAAC065D492600B07095
+
+ WindowString
+ 410 84 1245 749 0 0 1680 1028
+ WindowToolGUID
+ 2CDD4BFC0CB948FC00549FAC
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.run
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ LauncherConfigVersion
+ 3
+ PBXProjectModuleGUID
+ 1CD0528B0623707200166675
+ PBXProjectModuleLabel
+ Run
+ Runner
+
+ HorizontalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {493, 167}}
+ {{0, 176}, {493, 267}}
+
+
+ VerticalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {405, 443}}
+ {{414, 0}, {514, 443}}
+
+
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {1092, 660}}
+ RubberWindowFrame
+ 266 221 1092 701 0 0 1680 1028
+
+ Module
+ PBXRunSessionModule
+ Proportion
+ 660pt
+
+
+ Proportion
+ 660pt
+
+
+ Name
+ Run Log
+ ServiceClasses
+
+ PBXRunSessionModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C0AD2B3069F1EA900FABCE6
+ 2CF1EFD50CE77D5600B5167D
+ 1CD0528B0623707200166675
+ 2CF1EFD60CE77D5600B5167D
+
+ ToolbarConfiguration
+ xcode.toolbar.config.run
+ WindowString
+ 266 221 1092 701 0 0 1680 1028
+ WindowToolGUID
+ 1C0AD2B3069F1EA900FABCE6
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.scm
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1C78EAB2065D492600B07095
+ PBXProjectModuleLabel
+
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {452, 0}}
+ RubberWindowFrame
+ 194 589 452 308 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 0pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD052920623707200166675
+ PBXProjectModuleLabel
+ SCM Results
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 5}, {452, 262}}
+ RubberWindowFrame
+ 194 589 452 308 0 0 1680 1028
+
+ Module
+ PBXCVSModule
+ Proportion
+ 262pt
+
+
+ Proportion
+ 267pt
+
+
+ Name
+ SCM
+ ServiceClasses
+
+ PBXCVSModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 2CBF1CB30CC566690030C462
+ 2CBF1CB40CC566690030C462
+ 1C78EAB2065D492600B07095
+ 1CD052920623707200166675
+
+ ToolbarConfiguration
+ xcode.toolbar.config.scm
+ WindowString
+ 194 589 452 308 0 0 1680 1028
+ WindowToolGUID
+ 2CBF1CB30CC566690030C462
+ WindowToolIsVisible
+
+
+
+ Identifier
+ windowTool.breakpoints
+ IsVertical
+ 0
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+ 1
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C77FABC04509CD000000102
+
+ PBXProjectModuleGUID
+ 1CE0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ no
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 168
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ 1C77FABC04509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 0}, {168, 350}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+ 0
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {185, 368}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 168
+
+ RubberWindowFrame
+ 315 424 744 409 0 0 1440 878
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 185pt
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CA1AED706398EBD00589147
+ PBXProjectModuleLabel
+ Detail
+
+ GeometryConfiguration
+
+ Frame
+ {{190, 0}, {554, 368}}
+ RubberWindowFrame
+ 315 424 744 409 0 0 1440 878
+
+ Module
+ XCDetailModule
+ Proportion
+ 554pt
+
+
+ Proportion
+ 368pt
+
+
+ MajorVersion
+ 2
+ MinorVersion
+ 0
+ Name
+ Breakpoints
+ ServiceClasses
+
+ PBXSmartGroupTreeModule
+ XCDetailModule
+
+ StatusbarIsVisible
+ 1
+ TableOfContents
+
+ 1CDDB66807F98D9800BB5817
+ 1CDDB66907F98D9800BB5817
+ 1CE0B1FE06471DED0097A5F4
+ 1CA1AED706398EBD00589147
+
+ ToolbarConfiguration
+ xcode.toolbar.config.breakpoints
+ WindowString
+ 315 424 744 409 0 0 1440 878
+ WindowToolGUID
+ 1CDDB66807F98D9800BB5817
+ WindowToolIsVisible
+ 1
+
+
+ Identifier
+ windowTool.debugAnimator
+ Layout
+
+
+ Dock
+
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Debug Visualizer
+ ServiceClasses
+
+ PBXNavigatorGroup
+
+ StatusbarIsVisible
+ 1
+ ToolbarConfiguration
+ xcode.toolbar.config.debugAnimator
+ WindowString
+ 100 100 700 500 0 0 1280 1002
+
+
+ Identifier
+ windowTool.bookmarks
+ Layout
+
+
+ Dock
+
+
+ Module
+ PBXBookmarksModule
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Bookmarks
+ ServiceClasses
+
+ PBXBookmarksModule
+
+ StatusbarIsVisible
+ 0
+ WindowString
+ 538 42 401 187 0 0 1280 1002
+
+
+ Identifier
+ windowTool.classBrowser
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+ 1
+ ContentConfiguration
+
+ OptionsSetName
+ Hierarchy, all classes
+ PBXProjectModuleGUID
+ 1CA6456E063B45B4001379D8
+ PBXProjectModuleLabel
+ Class Browser - NSObject
+
+ GeometryConfiguration
+
+ ClassesFrame
+ {{0, 0}, {374, 96}}
+ ClassesTreeTableConfiguration
+
+ PBXClassNameColumnIdentifier
+ 208
+ PBXClassBookColumnIdentifier
+ 22
+
+ Frame
+ {{0, 0}, {630, 331}}
+ MembersFrame
+ {{0, 105}, {374, 395}}
+ MembersTreeTableConfiguration
+
+ PBXMemberTypeIconColumnIdentifier
+ 22
+ PBXMemberNameColumnIdentifier
+ 216
+ PBXMemberTypeColumnIdentifier
+ 97
+ PBXMemberBookColumnIdentifier
+ 22
+
+ PBXModuleWindowStatusBarHidden2
+ 1
+ RubberWindowFrame
+ 385 179 630 352 0 0 1440 878
+
+ Module
+ PBXClassBrowserModule
+ Proportion
+ 332pt
+
+
+ Proportion
+ 332pt
+
+
+ Name
+ Class Browser
+ ServiceClasses
+
+ PBXClassBrowserModule
+
+ StatusbarIsVisible
+ 0
+ TableOfContents
+
+ 1C0AD2AF069F1E9B00FABCE6
+ 1C0AD2B0069F1E9B00FABCE6
+ 1CA6456E063B45B4001379D8
+
+ ToolbarConfiguration
+ xcode.toolbar.config.classbrowser
+ WindowString
+ 385 179 630 352 0 0 1440 878
+ WindowToolGUID
+ 1C0AD2AF069F1E9B00FABCE6
+ WindowToolIsVisible
+ 0
+
+
+
+
diff --git a/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 b/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
new file mode 100644
index 00000000..3a15da1d
--- /dev/null
+++ b/src/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3
@@ -0,0 +1,1740 @@
+
+
+
+
+ ActivePerspectiveName
+ Project
+ AllowedModules
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXSmartGroupTreeModule
+ Name
+ Groups and Files Outline View
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXNavigatorGroup
+ Name
+ Editor
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCTaskListModule
+ Name
+ Task List
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCDetailModule
+ Name
+ File and Smart Group Detail Viewer
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXBuildResultsModule
+ Name
+ Detailed Build Results Viewer
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXProjectFindModule
+ Name
+ Project Batch Find Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCProjectFormatConflictsModule
+ Name
+ Project Format Conflicts List
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXBookmarksModule
+ Name
+ Bookmarks Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXClassBrowserModule
+ Name
+ Class Browser
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXCVSModule
+ Name
+ Source Code Control Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXDebugBreakpointsModule
+ Name
+ Debug Breakpoints Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCDockableInspector
+ Name
+ Inspector
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ PBXOpenQuicklyModule
+ Name
+ Open Quickly Tool
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXDebugSessionModule
+ Name
+ Debugger
+
+
+ BundleLoadPath
+
+ MaxInstances
+ 1
+ Module
+ PBXDebugCLIModule
+ Name
+ Debug Console
+
+
+ BundleLoadPath
+
+ MaxInstances
+ n
+ Module
+ XCSnapshotModule
+ Name
+ Snapshots Tool
+
+
+ Description
+ DefaultDescriptionKey
+ DockingSystemVisible
+
+ Extension
+ mode1v3
+ FavBarConfig
+
+ PBXProjectModuleGUID
+ 2C349F430CF222D900A55A81
+ XCBarModuleItemNames
+
+ XCBarModuleItems
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ com.apple.perspectives.project.mode1v3
+ MajorVersion
+ 33
+ MinorVersion
+ 0
+ Name
+ Default
+ Notifications
+
+ OpenEditors
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CA608820D9998CC00EBC4A7
+ PBXProjectModuleLabel
+ UAudioPlayback_Bass.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CA608830D9998CC00EBC4A7
+ PBXProjectModuleLabel
+ UAudioPlayback_Bass.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA6088F0D99999100EBC4A7
+ history
+
+ 2CA608790D99987900EBC4A7
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {993, 838}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 38 123 993 879 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CA608850D9998CC00EBC4A7
+ PBXProjectModuleLabel
+ UAudioCore_Bass.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CA608860D9998CC00EBC4A7
+ PBXProjectModuleLabel
+ UAudioCore_Bass.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608900D99999100EBC4A7
+ history
+
+ 2CA608780D99987200EBC4A7
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {993, 838}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 15 144 993 879 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2C019A0B0D998D4A00974970
+ PBXProjectModuleLabel
+ UMain.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2C019A0C0D998D4A00974970
+ PBXProjectModuleLabel
+ UMain.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608910D99999100EBC4A7
+ history
+
+ 2CA607DD0D998F0B00EBC4A7
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {1052, 646}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 30 341 1052 687 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2C0199490D9981C000974970
+ PBXProjectModuleLabel
+ UCommon.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2C01994A0D9981C000974970
+ PBXProjectModuleLabel
+ UCommon.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608920D99999100EBC4A7
+ history
+
+ 2CA607DF0D998F0B00EBC4A7
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {754, 847}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 38 134 754 888 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2C0199430D9981C000974970
+ PBXProjectModuleLabel
+ UScreenMain.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2C0199440D9981C000974970
+ PBXProjectModuleLabel
+ UScreenMain.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608930D99999100EBC4A7
+ history
+
+ 2C019A190D998D4A00974970
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {754, 847}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 38 135 754 888 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2C0199930D9984F900974970
+ PBXProjectModuleLabel
+ UltraStarDX.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2C0199940D9984F900974970
+ PBXProjectModuleLabel
+ UltraStarDX.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608940D99999100EBC4A7
+ history
+
+ 2C019A1A0D998D4A00974970
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {987, 762}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 311 168 987 803 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2C01994C0D9981C000974970
+ PBXProjectModuleLabel
+ OpenGL12.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2C01994D0D9981C000974970
+ PBXProjectModuleLabel
+ OpenGL12.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608950D99999100EBC4A7
+ history
+
+ 2C019A1B0D998D4A00974970
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {1070, 868}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 1 119 1070 909 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CE603EA0D71601400DB0D88
+ PBXProjectModuleLabel
+ UTexture.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CE603EB0D71601400DB0D88
+ PBXProjectModuleLabel
+ UTexture.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608960D99999100EBC4A7
+ history
+
+ 2C019A1C0D998D4A00974970
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {776, 858}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 15 124 776 899 0 0 1680 1028
+
+
+
+ Content
+
+ PBXProjectModuleGUID
+ 2CE603EE0D71601400DB0D88
+ PBXProjectModuleLabel
+ UPlatformMacOSX.pas
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 2CE603EF0D71601400DB0D88
+ PBXProjectModuleLabel
+ UPlatformMacOSX.pas
+ _historyCapacity
+ 0
+ bookmark
+ 2CA608970D99999100EBC4A7
+ history
+
+ 2C019A1D0D998D4A00974970
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ Geometry
+
+ Frame
+ {{0, 20}, {776, 859}}
+ PBXModuleWindowStatusBarHidden2
+
+ RubberWindowFrame
+ 79 126 776 900 0 0 1680 1028
+
+
+
+ PerspectiveWidths
+
+ -1
+ -1
+
+ Perspectives
+
+
+ ChosenToolbarItems
+
+ active-target-popup
+ active-buildstyle-popup
+ action
+ NSToolbarFlexibleSpaceItem
+ buildOrClean
+ build-and-goOrGo
+ com.apple.ide.PBXToolbarStopButton
+ get-info
+ toggle-editor
+ NSToolbarFlexibleSpaceItem
+ com.apple.pbx.toolbar.searchfield
+
+ ControllerClassBaseName
+
+ IconName
+ WindowOfProjectWithEditor
+ Identifier
+ perspective.project
+ IsVertical
+
+ Layout
+
+
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+ 1C08E77C0454961000C914BD
+ 1C37FABC05509CD000000102
+ 1C37FABC05539CD112110102
+ E2644B35053B69B200211256
+ 1C37FABC04509CD000100104
+ 1CC0EA4004350EF90044410B
+ 1CC0EA4004350EF90041110B
+
+ PBXProjectModuleGUID
+ 1CE0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ yes
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 266
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ DDC6850D09F5717A004E4BFF
+ 2C4D9D980CC9EE0B0031092D
+ DD7C45450A6E72DE003FA52B
+ 2CF5510C0CDA28F000627463
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 23
+ 15
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 105}, {266, 694}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+
+ XCSharingToken
+ com.apple.Xcode.GFSharingToken
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {283, 712}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 266
+
+ RubberWindowFrame
+ 799 242 817 753 0 0 1680 1028
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 283pt
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CE0B20306471E060097A5F4
+ PBXProjectModuleLabel
+
+ PBXSplitModuleInNavigatorKey
+
+ Split0
+
+ PBXProjectModuleGUID
+ 1CE0B20406471E060097A5F4
+ PBXProjectModuleLabel
+
+
+ SplitCount
+ 1
+
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {529, 0}}
+ RubberWindowFrame
+ 799 242 817 753 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 0pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CE0B20506471E060097A5F4
+ PBXProjectModuleLabel
+ Detail
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 5}, {529, 707}}
+ RubberWindowFrame
+ 799 242 817 753 0 0 1680 1028
+
+ Module
+ XCDetailModule
+ Proportion
+ 707pt
+
+
+ Proportion
+ 529pt
+
+
+ Name
+ Project
+ ServiceClasses
+
+ XCModuleDock
+ PBXSmartGroupTreeModule
+ XCModuleDock
+ PBXNavigatorGroup
+ XCDetailModule
+
+ TableOfContents
+
+ 2CA607D80D998F0B00EBC4A7
+ 1CE0B1FE06471DED0097A5F4
+ 2CA607D90D998F0B00EBC4A7
+ 1CE0B20306471E060097A5F4
+ 1CE0B20506471E060097A5F4
+
+ ToolbarConfiguration
+ xcode.toolbar.config.defaultV3
+
+
+ ControllerClassBaseName
+
+ IconName
+ WindowOfProject
+ Identifier
+ perspective.morph
+ IsVertical
+
+ Layout
+
+
+ BecomeActive
+ 1
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C37FBAC04509CD000000102
+ 1C37FAAC04509CD000000102
+ 1C08E77C0454961000C914BD
+ 1C37FABC05509CD000000102
+ 1C37FABC05539CD112110102
+ E2644B35053B69B200211256
+ 1C37FABC04509CD000100104
+ 1CC0EA4004350EF90044410B
+ 1CC0EA4004350EF90041110B
+
+ PBXProjectModuleGUID
+ 11E0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ yes
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 186
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ 29B97314FDCFA39411CA2CEA
+ 1C37FABC05509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 0}, {186, 337}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+ 1
+ XCSharingToken
+ com.apple.Xcode.GFSharingToken
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {203, 355}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 186
+
+ RubberWindowFrame
+ 373 269 690 397 0 0 1440 878
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 100%
+
+
+ Name
+ Morph
+ PreferredWidth
+ 300
+ ServiceClasses
+
+ XCModuleDock
+ PBXSmartGroupTreeModule
+
+ TableOfContents
+
+ 11E0B1FE06471DED0097A5F4
+
+ ToolbarConfiguration
+ xcode.toolbar.config.default.shortV3
+
+
+ PerspectivesBarVisible
+
+ ShelfIsVisible
+
+ StatusbarIsVisible
+
+ TimeStamp
+ 0.0
+ ToolbarDisplayMode
+ 1
+ ToolbarIsVisible
+
+ ToolbarSizeMode
+ 1
+ Type
+ Perspectives
+ UpdateMessage
+ The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?
+ WindowJustification
+ 5
+ WindowOrderList
+
+ 2CA6081C0D9991E800EBC4A7
+ 2CA6081D0D9991E800EBC4A7
+ 1C530D57069F1CE1000CFCEE
+ 1C78EAAD065D492600B07095
+ 1CD10A99069EF8BA00B06720
+ 2C65660B0CF2236C0041F7DC
+ 2CE603EE0D71601400DB0D88
+ 2CE603EA0D71601400DB0D88
+ 2C01994C0D9981C000974970
+ 2C0199930D9984F900974970
+ 2C0199430D9981C000974970
+ 2C0199490D9981C000974970
+ 2C019A0B0D998D4A00974970
+ 2CA608850D9998CC00EBC4A7
+ /Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj
+ 2CA608820D9998CC00EBC4A7
+
+ WindowString
+ 799 242 817 753 0 0 1680 1028
+ WindowToolsV3
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.build
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD0528F0623707200166675
+ PBXProjectModuleLabel
+ UAudioInput_Bass.pas
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {942, 546}}
+ RubberWindowFrame
+ 105 189 942 828 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 546pt
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ XCMainBuildResultsModuleGUID
+ PBXProjectModuleLabel
+ Build
+ XCBuildResultsTrigger_Collapse
+ 1021
+ XCBuildResultsTrigger_Open
+ 1011
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 551}, {942, 236}}
+ RubberWindowFrame
+ 105 189 942 828 0 0 1680 1028
+
+ Module
+ PBXBuildResultsModule
+ Proportion
+ 236pt
+
+
+ Proportion
+ 787pt
+
+
+ Name
+ Build Results
+ ServiceClasses
+
+ PBXBuildResultsModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 2C65660B0CF2236C0041F7DC
+ 2CA607E60D998F0B00EBC4A7
+ 1CD0528F0623707200166675
+ XCMainBuildResultsModuleGUID
+
+ ToolbarConfiguration
+ xcode.toolbar.config.buildV3
+ WindowString
+ 105 189 942 828 0 0 1680 1028
+ WindowToolGUID
+ 2C65660B0CF2236C0041F7DC
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.debugger
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ Debugger
+
+ HorizontalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {312, 440}}
+ {{312, 0}, {591, 440}}
+
+
+ VerticalSplitView
+
+ _collapsingFrameDimension
+ 0.0
+ _indexOfCollapsedView
+ 0
+ _percentageOfCollapsedView
+ 0.0
+ isCollapsed
+ yes
+ sizes
+
+ {{0, 0}, {903, 440}}
+ {{0, 440}, {903, 385}}
+
+
+
+ LauncherConfigVersion
+ 8
+ PBXProjectModuleGUID
+ 1C162984064C10D400B95A72
+ PBXProjectModuleLabel
+ Debug - GLUTExamples (Underwater)
+
+ GeometryConfiguration
+
+ DebugConsoleVisible
+ None
+ DebugConsoleWindowFrame
+ {{200, 200}, {500, 300}}
+ DebugSTDIOWindowFrame
+ {{200, 200}, {500, 300}}
+ Frame
+ {{0, 0}, {903, 825}}
+ PBXDebugSessionStackFrameViewKey
+
+ DebugVariablesTableConfiguration
+
+ Name
+ 120
+ Value
+ 85
+ Summary
+ 361
+
+ Frame
+ {{312, 0}, {591, 440}}
+ RubberWindowFrame
+ 13 162 903 866 0 0 1680 1028
+
+ RubberWindowFrame
+ 13 162 903 866 0 0 1680 1028
+
+ Module
+ PBXDebugSessionModule
+ Proportion
+ 825pt
+
+
+ Proportion
+ 825pt
+
+
+ Name
+ Debugger
+ ServiceClasses
+
+ PBXDebugSessionModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1CD10A99069EF8BA00B06720
+ 2CA607E70D998F0B00EBC4A7
+ 1C162984064C10D400B95A72
+ 2CA607E80D998F0B00EBC4A7
+ 2CA607E90D998F0B00EBC4A7
+ 2CA607EA0D998F0B00EBC4A7
+ 2CA607EB0D998F0B00EBC4A7
+ 2CA607EC0D998F0B00EBC4A7
+
+ ToolbarConfiguration
+ xcode.toolbar.config.debugV3
+ WindowString
+ 13 162 903 866 0 0 1680 1028
+ WindowToolGUID
+ 1CD10A99069EF8BA00B06720
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.find
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CDD528C0622207200134675
+ PBXProjectModuleLabel
+ <No Editor>
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {790, 502}}
+ RubberWindowFrame
+ 821 68 790 888 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 790pt
+
+
+ Proportion
+ 502pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD0528E0623707200166675
+ PBXProjectModuleLabel
+ Project Find
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 507}, {790, 340}}
+ RubberWindowFrame
+ 821 68 790 888 0 0 1680 1028
+
+ Module
+ PBXProjectFindModule
+ Proportion
+ 340pt
+
+
+ Proportion
+ 847pt
+
+
+ Name
+ Project Find
+ ServiceClasses
+
+ PBXProjectFindModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C530D57069F1CE1000CFCEE
+ 2CA607ED0D998F0B00EBC4A7
+ 2CA607EE0D998F0B00EBC4A7
+ 1CDD528C0622207200134675
+ 1CD0528E0623707200166675
+
+ WindowString
+ 821 68 790 888 0 0 1680 1028
+ WindowToolGUID
+ 1C530D57069F1CE1000CFCEE
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ MENUSEPARATOR
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.debuggerConsole
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1C78EAAC065D492600B07095
+ PBXProjectModuleLabel
+ Debugger Console
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {779, 729}}
+ RubberWindowFrame
+ 886 204 779 770 0 0 1680 1028
+
+ Module
+ PBXDebugCLIModule
+ Proportion
+ 729pt
+
+
+ Proportion
+ 729pt
+
+
+ Name
+ Debugger Console
+ ServiceClasses
+
+ PBXDebugCLIModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C78EAAD065D492600B07095
+ 2CA607EF0D998F0B00EBC4A7
+ 1C78EAAC065D492600B07095
+
+ ToolbarConfiguration
+ xcode.toolbar.config.consoleV3
+ WindowString
+ 886 204 779 770 0 0 1680 1028
+ WindowToolGUID
+ 1C78EAAD065D492600B07095
+ WindowToolIsVisible
+
+
+
+ Identifier
+ windowTool.snapshots
+ Layout
+
+
+ Dock
+
+
+ Module
+ XCSnapshotModule
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Snapshots
+ ServiceClasses
+
+ XCSnapshotModule
+
+ StatusbarIsVisible
+ Yes
+ ToolbarConfiguration
+ xcode.toolbar.config.snapshots
+ WindowString
+ 315 824 300 550 0 0 1440 878
+ WindowToolIsVisible
+ Yes
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.scm
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1C78EAB2065D492600B07095
+ PBXProjectModuleLabel
+
+ StatusBarVisibility
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {452, 0}}
+ RubberWindowFrame
+ 194 589 452 308 0 0 1680 1028
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 0pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CD052920623707200166675
+ PBXProjectModuleLabel
+ SCM Results
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 5}, {452, 262}}
+ RubberWindowFrame
+ 194 589 452 308 0 0 1680 1028
+
+ Module
+ PBXCVSModule
+ Proportion
+ 262pt
+
+
+ Proportion
+ 267pt
+
+
+ Name
+ SCM
+ ServiceClasses
+
+ PBXCVSModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C78EAB4065D492600B07095
+ 1C78EAB5065D492600B07095
+ 1C78EAB2065D492600B07095
+ 1CD052920623707200166675
+
+ ToolbarConfiguration
+ xcode.toolbar.config.scm
+ WindowString
+ 194 589 452 308 0 0 1680 1028
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.breakpoints
+ IsVertical
+
+ Layout
+
+
+ Dock
+
+
+ ContentConfiguration
+
+ PBXBottomSmartGroupGIDs
+
+ 1C77FABC04509CD000000102
+
+ PBXProjectModuleGUID
+ 1CE0B1FE06471DED0097A5F4
+ PBXProjectModuleLabel
+ Files
+ PBXProjectStructureProvided
+ no
+ PBXSmartGroupTreeModuleColumnData
+
+ PBXSmartGroupTreeModuleColumnWidthsKey
+
+ 168
+
+ PBXSmartGroupTreeModuleColumnsKey_v4
+
+ MainColumn
+
+
+ PBXSmartGroupTreeModuleOutlineStateKey_v7
+
+ PBXSmartGroupTreeModuleOutlineStateExpansionKey
+
+ 1C77FABC04509CD000000102
+
+ PBXSmartGroupTreeModuleOutlineStateSelectionKey
+
+
+ 0
+
+
+ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey
+ {{0, 0}, {168, 350}}
+
+ PBXTopSmartGroupGIDs
+
+ XCIncludePerspectivesSwitch
+
+
+ GeometryConfiguration
+
+ Frame
+ {{0, 0}, {185, 368}}
+ GroupTreeTableConfiguration
+
+ MainColumn
+ 168
+
+ RubberWindowFrame
+ 424 558 744 409 0 0 1680 1028
+
+ Module
+ PBXSmartGroupTreeModule
+ Proportion
+ 185pt
+
+
+ BecomeActive
+
+ ContentConfiguration
+
+ PBXProjectModuleGUID
+ 1CA1AED706398EBD00589147
+ PBXProjectModuleLabel
+ Detail
+
+ GeometryConfiguration
+
+ Frame
+ {{190, 0}, {554, 368}}
+ RubberWindowFrame
+ 424 558 744 409 0 0 1680 1028
+
+ Module
+ XCDetailModule
+ Proportion
+ 554pt
+
+
+ Proportion
+ 368pt
+
+
+ MajorVersion
+ 3
+ MinorVersion
+ 0
+ Name
+ Breakpoints
+ ServiceClasses
+
+ PBXSmartGroupTreeModule
+ XCDetailModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 2CA2CD2C0CF61AD5008733A1
+ 2CA2CD2D0CF61AD5008733A1
+ 1CE0B1FE06471DED0097A5F4
+ 1CA1AED706398EBD00589147
+
+ ToolbarConfiguration
+ xcode.toolbar.config.breakpointsV3
+ WindowString
+ 424 558 744 409 0 0 1680 1028
+ WindowToolGUID
+ 2CA2CD2C0CF61AD5008733A1
+ WindowToolIsVisible
+
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.debugAnimator
+ Layout
+
+
+ Dock
+
+
+ Module
+ PBXNavigatorGroup
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Debug Visualizer
+ ServiceClasses
+
+ PBXNavigatorGroup
+
+ StatusbarIsVisible
+
+ ToolbarConfiguration
+ xcode.toolbar.config.debugAnimatorV3
+ WindowString
+ 100 100 700 500 0 0 1280 1002
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.bookmarks
+ Layout
+
+
+ Dock
+
+
+ Module
+ PBXBookmarksModule
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Bookmarks
+ ServiceClasses
+
+ PBXBookmarksModule
+
+ StatusbarIsVisible
+
+ WindowString
+ 538 42 401 187 0 0 1280 1002
+
+
+ Identifier
+ windowTool.projectFormatConflicts
+ Layout
+
+
+ Dock
+
+
+ Module
+ XCProjectFormatConflictsModule
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Project Format Conflicts
+ ServiceClasses
+
+ XCProjectFormatConflictsModule
+
+ StatusbarIsVisible
+
+ WindowContentMinSize
+ 450 300
+ WindowString
+ 50 850 472 307 0 0 1440 877
+
+
+ FirstTimeWindowDisplayed
+
+ Identifier
+ windowTool.classBrowser
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+ 1
+ ContentConfiguration
+
+ OptionsSetName
+ Hierarchy, all classes
+ PBXProjectModuleGUID
+ 1CA6456E063B45B4001379D8
+ PBXProjectModuleLabel
+ Class Browser - NSObject
+
+ GeometryConfiguration
+
+ ClassesFrame
+ {{0, 0}, {374, 96}}
+ ClassesTreeTableConfiguration
+
+ PBXClassNameColumnIdentifier
+ 208
+ PBXClassBookColumnIdentifier
+ 22
+
+ Frame
+ {{0, 0}, {630, 331}}
+ MembersFrame
+ {{0, 105}, {374, 395}}
+ MembersTreeTableConfiguration
+
+ PBXMemberTypeIconColumnIdentifier
+ 22
+ PBXMemberNameColumnIdentifier
+ 216
+ PBXMemberTypeColumnIdentifier
+ 97
+ PBXMemberBookColumnIdentifier
+ 22
+
+ PBXModuleWindowStatusBarHidden2
+ 1
+ RubberWindowFrame
+ 385 179 630 352 0 0 1440 878
+
+ Module
+ PBXClassBrowserModule
+ Proportion
+ 332pt
+
+
+ Proportion
+ 332pt
+
+
+ Name
+ Class Browser
+ ServiceClasses
+
+ PBXClassBrowserModule
+
+ StatusbarIsVisible
+
+ TableOfContents
+
+ 1C0AD2AF069F1E9B00FABCE6
+ 1C0AD2B0069F1E9B00FABCE6
+ 1CA6456E063B45B4001379D8
+
+ ToolbarConfiguration
+ xcode.toolbar.config.classbrowser
+ WindowString
+ 385 179 630 352 0 0 1440 878
+ WindowToolGUID
+ 1C0AD2AF069F1E9B00FABCE6
+ WindowToolIsVisible
+
+
+
+ Identifier
+ windowTool.refactoring
+ IncludeInToolsMenu
+
+ Layout
+
+
+ Dock
+
+
+ BecomeActive
+
+ GeometryConfiguration
+
+ Frame
+ {0, 0}, {500, 335}
+ RubberWindowFrame
+ {0, 0}, {500, 335}
+
+ Module
+ XCRefactoringModule
+ Proportion
+ 100%
+
+
+ Proportion
+ 100%
+
+
+ Name
+ Refactoring
+ ServiceClasses
+
+ XCRefactoringModule
+
+ WindowString
+ 200 200 500 356 0 0 1920 1200
+
+
+
+
diff --git a/src/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser b/src/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
new file mode 100644
index 00000000..e054f93e
--- /dev/null
+++ b/src/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
@@ -0,0 +1,1414 @@
+// !$*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}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1115}";
+ sepNavWindowFrame = "{{15, 465}, {750, 558}}";
+ };
+ };
+ 2C4D9C620CC9EC8C0031092D /* TextGL.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 7532}}";
+ sepNavSelRange = "{10589, 66}";
+ sepNavVisRange = "{10222, 893}";
+ sepNavVisRect = "{{0, 5908}, {758, 716}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {923, 2128}}";
+ sepNavSelRange = "{1154, 0}";
+ sepNavVisRect = "{{0, 354}, {923, 342}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 4130}}";
+ sepNavSelRange = "{79, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{84, 115}, {797, 845}}";
+ };
+ };
+ 2C4D9C670CC9EC8C0031092D /* UCommon.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {695, 4060}}";
+ sepNavSelRange = "{584, 24}";
+ sepNavVisRange = "{249, 1447}";
+ sepNavVisRect = "{{0, 508}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 78}, {754, 944}}";
+ };
+ };
+ 2C4D9C680CC9EC8C0031092D /* UCore.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1202, 7294}}";
+ sepNavSelRange = "{12520, 0}";
+ sepNavVisRect = "{{0, 844}, {758, 716}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {577, 1708}}";
+ sepNavSelRange = "{262, 0}";
+ sepNavVisRect = "{{0, 0}, {577, 612}}";
+ sepNavWindowFrame = "{{38, 261}, {616, 741}}";
+ };
+ };
+ 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 3668}}";
+ sepNavSelRange = "{49, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{130, 73}, {797, 845}}";
+ };
+ };
+ 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {4058, 5082}}";
+ sepNavSelRange = "{1600, 0}";
+ sepNavVisRect = "{{0, 1250}, {923, 342}}";
+ sepNavWindowFrame = "{{153, 52}, {797, 845}}";
+ };
+ };
+ 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1424, 3542}}";
+ sepNavSelRange = "{4330, 0}";
+ sepNavVisRange = "{3445, 1320}";
+ sepNavVisRect = "{{0, 456}, {758, 716}}";
+ sepNavWindowFrame = "{{15, 178}, {797, 845}}";
+ };
+ };
+ 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {836, 19516}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{6577, 1474}";
+ sepNavVisRect = "{{0, 4065}, {1277, 312}}";
+ sepNavWindowFrame = "{{61, 122}, {794, 859}}";
+ };
+ };
+ 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {815, 2086}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{2303, 2169}";
+ sepNavVisRect = "{{0, 4494}, {923, 342}}";
+ sepNavWindowFrame = "{{84, 77}, {874, 883}}";
+ };
+ };
+ 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {729, 10626}}";
+ sepNavSelRange = "{16099, 0}";
+ sepNavVisRange = "{13982, 870}";
+ sepNavVisRect = "{{0, 3790}, {749, 470}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1052, 9450}}";
+ sepNavSelRange = "{5863, 11}";
+ sepNavVisRect = "{{0, 2572}, {749, 470}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9C710CC9EC8C0031092D /* UHooks.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1277, 5964}}";
+ sepNavSelRange = "{11810, 0}";
+ sepNavVisRect = "{{0, 5652}, {1277, 312}}";
+ sepNavWindowFrame = "{{84, 115}, {797, 845}}";
+ };
+ };
+ 2C4D9C720CC9EC8C0031092D /* UIni.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 11214}}";
+ sepNavSelRange = "{5601, 15}";
+ sepNavVisRange = "{5183, 839}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {896, 3962}}";
+ sepNavSelRange = "{46, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{130, 73}, {797, 845}}";
+ };
+ };
+ 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {738, 3388}}";
+ sepNavSelRange = "{28, 58}";
+ sepNavVisRange = "{0, 1050}";
+ sepNavVisRect = "{{0, 914}, {923, 342}}";
+ sepNavWindowFrame = "{{153, 52}, {797, 845}}";
+ };
+ };
+ 2C4D9C760CC9EC8C0031092D /* ULCD.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {577, 4270}}";
+ sepNavSelRange = "{25, 0}";
+ sepNavVisRect = "{{0, 0}, {577, 612}}";
+ sepNavWindowFrame = "{{176, 135}, {616, 741}}";
+ };
+ };
+ 2C4D9C770CC9EC8C0031092D /* ULight.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 2282}}";
+ sepNavSelRange = "{1017, 0}";
+ sepNavVisRect = "{{0, 425}, {758, 716}}";
+ sepNavWindowFrame = "{{15, 178}, {797, 845}}";
+ };
+ };
+ 2C4D9C780CC9EC8C0031092D /* ULog.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 4102}}";
+ sepNavSelRange = "{6569, 0}";
+ sepNavVisRange = "{6421, 474}";
+ sepNavVisRect = "{{0, 147}, {758, 716}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1070, 5950}}";
+ sepNavSelRange = "{34, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{84, 115}, {797, 845}}";
+ };
+ };
+ 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 10626}}";
+ sepNavSelRange = "{6965, 12}";
+ sepNavVisRange = "{6549, 702}";
+ sepNavVisRect = "{{0, 4395}, {758, 716}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1026, 16268}}";
+ sepNavSelRange = "{31433, 0}";
+ sepNavVisRange = "{32193, 1839}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
+ sepNavWindowFrame = "{{30, 285}, {1052, 743}}";
+ };
+ };
+ 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {738, 3864}}";
+ sepNavSelRange = "{960, 0}";
+ sepNavVisRange = "{4488, 788}";
+ sepNavVisRect = "{{0, 1071}, {749, 470}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
+ sepNavSelRange = "{31, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{130, 73}, {797, 845}}";
+ };
+ };
+ 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {749, 4494}}";
+ sepNavSelRange = "{4994, 0}";
+ sepNavVisRect = "{{0, 4024}, {749, 470}}";
+ sepNavWindowFrame = "{{153, 52}, {797, 845}}";
+ };
+ };
+ 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {854, 8988}}";
+ sepNavSelRange = "{17977, 0}";
+ sepNavVisRange = "{16881, 1096}";
+ sepNavVisRect = "{{0, 3141}, {1305, 534}}";
+ sepNavWindowFrame = "{{15, 178}, {797, 845}}";
+ };
+ };
+ 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {824, 6496}}";
+ sepNavSelRange = "{51, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 2198}}";
+ sepNavSelRange = "{247, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{84, 115}, {797, 845}}";
+ };
+ };
+ 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1718, 11116}}";
+ sepNavSelRange = "{317, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9C840CC9EC8C0031092D /* URecord.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {738, 8372}}";
+ sepNavSelRange = "{10657, 20}";
+ sepNavVisRange = "{10176, 1198}";
+ sepNavVisRect = "{{0, 4312}, {758, 716}}";
+ sepNavWindowFrame = "{{130, 73}, {797, 845}}";
+ };
+ };
+ 2C4D9C850CC9EC8C0031092D /* UServices.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1916, 4494}}";
+ sepNavSelRange = "{9160, 4}";
+ sepNavVisRect = "{{0, 4182}, {1277, 312}}";
+ sepNavWindowFrame = "{{153, 52}, {797, 845}}";
+ };
+ };
+ 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
+ sepNavSelRange = "{52, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{15, 178}, {797, 845}}";
+ };
+ };
+ 2C4D9C870CC9EC8C0031092D /* USingScores.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {950, 13818}}";
+ sepNavSelRange = "{15011, 16}";
+ sepNavVisRect = "{{0, 5904}, {749, 470}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9C880CC9EC8C0031092D /* USkins.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 2450}}";
+ sepNavSelRange = "{2805, 0}";
+ sepNavVisRange = "{2928, 803}";
+ sepNavVisRect = "{{0, 550}, {923, 342}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9C890CC9EC8C0031092D /* USongs.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {920, 13636}}";
+ sepNavSelRange = "{6946, 0}";
+ sepNavVisRange = "{6429, 995}";
+ sepNavVisRect = "{{0, 4157}, {758, 716}}";
+ sepNavWindowFrame = "{{15, 156}, {797, 845}}";
+ };
+ };
+ 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1010, 854}}";
+ sepNavSelRange = "{54, 0}";
+ sepNavVisRect = "{{0, 138}, {758, 716}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {858, 16688}}";
+ sepNavSelRange = "{10496, 0}";
+ sepNavVisRange = "{9368, 1825}";
+ sepNavVisRect = "{{0, 3420}, {737, 826}}";
+ sepNavWindowFrame = "{{15, 68}, {776, 955}}";
+ };
+ };
+ 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 32242}}";
+ sepNavSelRange = "{59317, 12}";
+ sepNavVisRange = "{61073, 1036}";
+ sepNavVisRect = "{{0, 19678}, {923, 342}}";
+ sepNavWindowFrame = "{{28, 161}, {797, 845}}";
+ };
+ };
+ 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 1400}}";
+ sepNavSelRange = "{42, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{153, 52}, {797, 845}}";
+ };
+ };
+ 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {914, 9016}}";
+ sepNavSelRange = "{12966, 0}";
+ sepNavVisRange = "{12857, 955}";
+ sepNavVisRect = "{{0, 5722}, {749, 470}}";
+ sepNavWindowFrame = "{{15, 178}, {797, 845}}";
+ };
+ };
+ 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {974, 24374}}";
+ sepNavSelRange = "{1377, 0}";
+ sepNavVisRect = "{{0, 0}, {577, 612}}";
+ sepNavWindowFrame = "{{245, 72}, {616, 741}}";
+ };
+ };
+ 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1718, 10416}}";
+ sepNavSelRange = "{1255, 0}";
+ sepNavVisRect = "{{0, 373}, {577, 612}}";
+ sepNavWindowFrame = "{{15, 282}, {616, 741}}";
+ };
+ };
+ 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 6944}}";
+ sepNavSelRange = "{5028, 51}";
+ sepNavVisRange = "{4044, 1359}";
+ sepNavVisRect = "{{0, 4834}, {758, 716}}";
+ sepNavWindowFrame = "{{38, 157}, {797, 845}}";
+ };
+ };
+ 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {738, 1470}}";
+ sepNavSelRange = "{2779, 0}";
+ sepNavVisRange = "{937, 1764}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1284, 22162}}";
+ sepNavSelRange = "{51782, 0}";
+ sepNavVisRange = "{51126, 1038}";
+ sepNavVisRect = "{{0, 3972}, {749, 470}}";
+ sepNavWindowFrame = "{{38, 82}, {898, 920}}";
+ };
+ };
+ 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {934, 7546}}";
+ sepNavSelRange = "{10421, 15}";
+ sepNavVisRange = "{9357, 1695}";
+ sepNavVisRect = "{{0, 1104}, {577, 612}}";
+ sepNavWindowFrame = "{{44, 71}, {993, 935}}";
+ };
+ };
+ 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 1008}}";
+ sepNavSelRange = "{63, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{61, 136}, {797, 845}}";
+ };
+ };
+ 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 716}}";
+ sepNavSelRange = "{55, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{84, 115}, {797, 845}}";
+ };
+ };
+ 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {577, 2828}}";
+ sepNavSelRange = "{53, 0}";
+ sepNavVisRect = "{{0, 0}, {577, 612}}";
+ sepNavWindowFrame = "{{130, 177}, {616, 741}}";
+ };
+ };
+ 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 4928}}";
+ sepNavSelRange = "{58, 0}";
+ sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavWindowFrame = "{{107, 94}, {797, 845}}";
+ };
+ };
+ 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 1204}}";
+ sepNavSelRange = "{400, 0}";
+ sepNavVisRange = "{184, 530}";
+ sepNavVisRect = "{{0, 0}, {577, 612}}";
+ sepNavWindowFrame = "{{107, 198}, {616, 741}}";
+ };
+ };
+ 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {962, 5222}}";
+ sepNavSelRange = "{2165, 0}";
+ sepNavVisRect = "{{0, 707}, {758, 716}}";
+ sepNavWindowFrame = "{{130, 73}, {797, 845}}";
+ };
+ };
+ 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1268, 4788}}";
+ sepNavSelRange = "{15613, 0}";
+ sepNavVisRect = "{{0, 1736}, {1013, 614}}";
+ sepNavWindowFrame = "{{15, 280}, {1052, 743}}";
+ };
+ };
+ 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1268, 6552}}";
+ sepNavSelRange = "{8844, 12}";
+ sepNavVisRect = "{{0, 2054}, {749, 470}}";
+ };
+ };
+ 2C4D9E040CC9EF840031092D /* OpenGL12.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1608, 64064}}";
+ sepNavSelRange = "{213678, 0}";
+ sepNavVisRange = "{207797, 6669}";
+ sepNavVisRect = "{{0, 64932}, {1031, 840}}";
+ sepNavWindowFrame = "{{1, 63}, {1070, 965}}";
+ };
+ };
+ 2C4D9E090CC9EF840031092D /* Windows.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {577, 2352}}";
+ sepNavSelRange = "{2345, 0}";
+ sepNavVisRect = "{{0, 1278}, {577, 612}}";
+ sepNavWindowFrame = "{{176, 135}, {616, 741}}";
+ };
+ };
+ 2C4D9E440CC9F0ED0031092D /* switches.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {624, 1918}}";
+ sepNavSelRange = "{1326, 0}";
+ sepNavVisRange = "{657, 1095}";
+ sepNavVisRect = "{{0, 7}, {577, 612}}";
+ sepNavWindowFrame = "{{15, 282}, {616, 741}}";
+ };
+ };
+ 2C5663EE0D35645700D4FF53 /* portaudio.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 16842}}";
+ sepNavSelRange = "{2289, 0}";
+ sepNavVisRange = "{7295, 1046}";
+ };
+ };
+ 2C56642B0D35683200D4FF53 /* SDLMain.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 5404}}";
+ sepNavSelRange = "{247, 16}";
+ sepNavVisRange = "{0, 1181}";
+ };
+ };
+ 2C8937290CE393FB005D8A87 /* UPlatform.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {717, 1120}}";
+ sepNavSelRange = "{830, 0}";
+ sepNavVisRange = "{241, 1433}";
+ sepNavVisRect = "{{0, 0}, {737, 826}}";
+ sepNavWindowFrame = "{{200, 71}, {776, 955}}";
+ };
+ };
+ 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {744, 1890}}";
+ sepNavSelRange = "{717, 0}";
+ 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}, {842, 3766}}";
+ sepNavSelRange = "{5570, 0}";
+ sepNavVisRange = "{5295, 761}";
+ sepNavWindowFrame = "{{15, 140}, {874, 883}}";
+ };
+ };
+ 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {934, 6104}}";
+ sepNavSelRange = "{4658, 3}";
+ sepNavVisRange = "{4001, 1277}";
+ sepNavWindowFrame = "{{38, 67}, {993, 935}}";
+ };
+ };
+ 2CB9E87D0D43B78400214DFA /* USong.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1550, 10290}}";
+ sepNavSelRange = "{19153, 0}";
+ sepNavVisRange = "{18134, 1509}";
+ sepNavWindowFrame = "{{15, 88}, {993, 935}}";
+ };
+ };
+ 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 1022}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
+ sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
+ };
+ };
+ 2CDD4B5D0CB9354800549FAC /* UltraStarDX */ = {
+ isa = PBXExecutable;
+ activeArgIndices = (
+ );
+ argumentStrings = (
+ );
+ autoAttachOnCrash = 1;
+ breakpointsEnabled = 0;
+ configStateDict = {
+ };
+ customDataFormattersEnabled = 1;
+ debuggerPlugin = GDBDebugging;
+ disassemblyDisplayState = 0;
+ dylibVariantSuffix = "";
+ enableDebugStr = 1;
+ environmentEntries = (
+ );
+ executableSystemSymbolLevel = 0;
+ executableUserSymbolLevel = 0;
+ libgmallocEnabled = 0;
+ name = UltraStarDX;
+ savedGlobals = {
+ };
+ sourceDirectories = (
+ );
+ variableFormatDictionary = {
+ $cs = 1;
+ $ds = 1;
+ $eax = 1;
+ $ebp = 1;
+ $ebx = 1;
+ $ecx = 1;
+ $edi = 1;
+ $edx = 1;
+ $eflags = 1;
+ $eip = 1;
+ $es = 1;
+ $esi = 1;
+ $esp = 1;
+ $gs = 1;
+ $ss = 1;
+ };
+ };
+ 2CDD4B690CB9357000549FAC /* Source Control */ = {
+ isa = PBXSourceControlManager;
+ fallbackIsa = XCSourceControlManager;
+ isSCMEnabled = 0;
+ scmConfiguration = {
+ };
+ scmType = "";
+ };
+ 2CDD4B6A0CB9357000549FAC /* Code sense */ = {
+ isa = PBXCodeSenseManager;
+ indexTemplatePath = "";
+ };
+ 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {934, 1764}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1211}";
+ sepNavWindowFrame = "{{15, 88}, {993, 935}}";
+ };
+ };
+ 2CE603E10D715F8600DB0D88 /* UConfig.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 3080}}";
+ sepNavSelRange = "{7279, 0}";
+ sepNavVisRange = "{6847, 865}";
+ };
+ };
+ 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 686}}";
+ sepNavSelRange = "{598, 0}";
+ sepNavVisRange = "{214, 458}";
+ sepNavVisRect = "{{0, 0}, {737, 826}}";
+ sepNavWindowFrame = "{{15, 68}, {776, 955}}";
+ };
+ };
+ 2CF3EF210CDE13A0004F5956 /* Messages.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 614}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
+ sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
+ };
+ };
+ 2CF3EF260CDE13BA004F5956 /* MacResources.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {834, 1750}}";
+ sepNavSelRange = "{1218, 0}";
+ sepNavVisRect = "{{0, 1120}, {834, 610}}";
+ sepNavWindowFrame = "{{200, 248}, {873, 739}}";
+ };
+ };
+ 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {695, 19544}}";
+ sepNavSelRange = "{26865, 471}";
+ sepNavVisRange = "{25408, 2367}";
+ sepNavVisRect = "{{0, 1770}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1610}}";
+ sepNavSelRange = "{34, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {842, 8484}}";
+ sepNavSelRange = "{13516, 0}";
+ sepNavVisRange = "{13202, 415}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 5180}}";
+ sepNavSelRange = "{59, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1040, 19236}}";
+ sepNavSelRange = "{37, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1302}}";
+ sepNavSelRange = "{54, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 815}}";
+ sepNavSelRange = "{58, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {695, 4326}}";
+ sepNavSelRange = "{1560, 17}";
+ sepNavVisRange = "{1022, 1336}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {956, 3318}}";
+ sepNavSelRange = "{34, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 2366}}";
+ sepNavSelRange = "{55, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 2506}}";
+ sepNavSelRange = "{311, 0}";
+ sepNavVisRect = "{{0, 188}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1484}}";
+ sepNavSelRange = "{45, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1582}}";
+ sepNavSelRange = "{60, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1400}}";
+ sepNavSelRange = "{64, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1330}}";
+ sepNavSelRange = "{62, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {776, 1974}}";
+ sepNavSelRange = "{39, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1414}}";
+ sepNavSelRange = "{42, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1680}}";
+ sepNavSelRange = "{43, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {758, 5880}}";
+ sepNavSelRange = "{62, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 3640}}";
+ sepNavSelRange = "{61, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {956, 4648}}";
+ sepNavSelRange = "{62, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1046, 4116}}";
+ sepNavSelRange = "{61, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {752, 3640}}";
+ sepNavSelRange = "{59, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */ = {
+ uiCtxt = {
+ 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}, {792, 14714}}";
+ sepNavSelRange = "{4909, 0}";
+ sepNavVisRange = "{4202, 810}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1250, 18788}}";
+ sepNavSelRange = "{39356, 0}";
+ sepNavVisRange = "{39482, 1725}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 78}, {754, 944}}";
+ };
+ };
+ 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {729, 9912}}";
+ sepNavSelRange = "{21169, 11}";
+ sepNavVisRange = "{20602, 649}";
+ sepNavVisRect = "{{0, 187}, {1277, 312}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {881, 31066}}";
+ sepNavSelRange = "{7241, 96}";
+ sepNavVisRange = "{6687, 1426}";
+ sepNavVisRect = "{{0, 11219}, {1277, 312}}";
+ sepNavWindowFrame = "{{38, 78}, {754, 944}}";
+ };
+ };
+ 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1160, 2884}}";
+ sepNavSelRange = "{61, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */ = {
+ uiCtxt = {
+ 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}, {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}, {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}, {729, 2492}}";
+ sepNavSelRange = "{996, 0}";
+ sepNavVisRange = "{458, 883}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {715, 1694}}";
+ sepNavSelRange = "{58, 0}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{38, 58}, {754, 944}}";
+ };
+ };
+ 2CF5508B0CDA22B000627463 /* ModiSDK.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {986, 2128}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 2269}";
+ sepNavVisRect = "{{0, 0}, {715, 815}}";
+ sepNavWindowFrame = "{{15, 79}, {754, 944}}";
+ };
+ };
+ 2CF5510E0CDA293700627463 /* SQLite3.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1364, 2800}}";
+ sepNavSelRange = "{517, 0}";
+ sepNavVisRect = "{{0, 0}, {1031, 840}}";
+ sepNavWindowFrame = "{{15, 54}, {1070, 969}}";
+ };
+ };
+ 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1031, 10766}}";
+ sepNavSelRange = "{559, 0}";
+ sepNavVisRect = "{{0, 0}, {1031, 840}}";
+ sepNavWindowFrame = "{{15, 54}, {1070, 969}}";
+ };
+ };
+ 2CF551A70CDA356800627463 /* UltraStar.dpr */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {914, 2674}}";
+ sepNavSelRange = "{4560, 0}";
+ sepNavVisRect = "{{0, 990}, {737, 827}}";
+ sepNavWindowFrame = "{{15, 67}, {776, 956}}";
+ };
+ };
+ 2CF552110CDA3D1400627463 /* UPluginDefs.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 2506}}";
+ sepNavSelRange = "{5, 11}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
+ sepNavWindowFrame = "{{107, 196}, {1052, 743}}";
+ };
+ };
+ 2CF5529E0CDA42C900627463 /* avcodec.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {993, 28406}}";
+ sepNavSelRange = "{1536, 0}";
+ sepNavVisRange = "{0, 1591}";
+ sepNavVisRect = "{{0, 375}, {1013, 614}}";
+ sepNavWindowFrame = "{{176, 133}, {1052, 743}}";
+ };
+ };
+ 2CF5529F0CDA42C900627463 /* avformat.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {993, 10206}}";
+ sepNavSelRange = "{1559, 189}";
+ sepNavVisRange = "{1159, 858}";
+ sepNavVisRect = "{{0, 298}, {1013, 614}}";
+ sepNavWindowFrame = "{{245, 70}, {1052, 743}}";
+ };
+ };
+ 2CF552A00CDA42C900627463 /* avio.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 3598}}";
+ sepNavSelRange = "{347, 0}";
+ sepNavVisRect = "{{0, 190}, {1013, 614}}";
+ sepNavWindowFrame = "{{199, 112}, {1052, 743}}";
+ };
+ };
+ 2CF552A10CDA42C900627463 /* avutil.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {993, 2170}}";
+ sepNavSelRange = "{1520, 0}";
+ sepNavVisRange = "{0, 1756}";
+ sepNavVisRect = "{{0, 293}, {1013, 614}}";
+ sepNavWindowFrame = "{{222, 91}, {1052, 743}}";
+ };
+ };
+ 2CF553070CDA51B500627463 /* sdlutils.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 61068}}";
+ sepNavSelRange = "{8481, 20}";
+ sepNavVisRect = "{{0, 1054}, {1013, 614}}";
+ sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
+ };
+ };
+ 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */ = {
+ activeExec = 0;
+ };
+ 98B8BE5C0B1F974F00162019 /* sdl.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1268, 58492}}";
+ sepNavSelRange = "{157855, 0}";
+ sepNavVisRect = "{{0, 3444}, {948, 730}}";
+ sepNavWindowFrame = "{{211, 143}, {987, 859}}";
+ };
+ };
+ DD37F2420A60255800975B2D /* fpcrtl */ = {
+ activeExec = 0;
+ };
+ DDC6850F09F5717A004E4BFF /* Project object */ = {
+ activeArchitecture = i386;
+ activeBuildConfigurationName = Release;
+ activeExecutable = 2CDD4B5D0CB9354800549FAC /* UltraStarDX */;
+ activeTarget = DDC688C709F574E9004E4BFF /* UltraStarDX */;
+ addToTargets = (
+ );
+ breakpoints = (
+ );
+ codeSenseManager = 2CDD4B6A0CB9357000549FAC /* Code sense */;
+ executables = (
+ 2CDD4B5D0CB9354800549FAC /* UltraStarDX */,
+ );
+ perUserDictionary = {
+ "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 20,
+ 198,
+ 20,
+ 99,
+ 99,
+ 29,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXBreakpointsDataSource_ActionID,
+ PBXBreakpointsDataSource_TypeID,
+ PBXBreakpointsDataSource_BreakpointID,
+ PBXBreakpointsDataSource_UseID,
+ PBXBreakpointsDataSource_LocationID,
+ PBXBreakpointsDataSource_ConditionID,
+ PBXBreakpointsDataSource_IgnoreCountID,
+ PBXBreakpointsDataSource_ContinueID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 22,
+ 300,
+ 67,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXExecutablesDataSource_ActiveFlagID,
+ PBXExecutablesDataSource_NameID,
+ PBXExecutablesDataSource_CommentsID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 290,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 16,
+ 200,
+ 50,
+ 119,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXSymbolsDataSource_SymbolTypeIconID,
+ PBXSymbolsDataSource_SymbolNameID,
+ PBXSymbolsDataSource_SymbolTypeID,
+ PBXSymbolsDataSource_ReferenceNameID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 20,
+ 266,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_SCM_ColumnID,
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 250,
+ 60,
+ 20,
+ 48,
+ 43,
+ 43,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXTargetDataSource_PrimaryAttribute,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ );
+ };
+ PBXPerProjectTemplateStateSaveDate = 228166993;
+ PBXWorkspaceStateSaveDate = 228166993;
+ };
+ perUserProjectItems = {
+ 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 = {
+ };
+ };
+ DDC6851B09F57195004E4BFF /* UltraStarDX.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {928, 731}}";
+ sepNavSelRange = "{72, 0}";
+ sepNavVisRange = "{0, 152}";
+ sepNavVisRect = "{{0, 0}, {948, 730}}";
+ sepNavWindowFrame = "{{311, 112}, {987, 859}}";
+ };
+ };
+ DDC6868B09F571C2004E4BFF /* Info.plist */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 614}}";
+ sepNavSelRange = "{366, 0}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
+ sepNavWindowFrame = "{{15, 280}, {1052, 743}}";
+ };
+ };
+ DDC688C709F574E9004E4BFF /* UltraStarDX */ = {
+ activeExec = 0;
+ executables = (
+ 2CDD4B5D0CB9354800549FAC /* UltraStarDX */,
+ );
+ };
+ DDC688D409F57523004E4BFF /* Put all program sources also in this target */ = {
+ activeExec = 0;
+ };
+ DDC689B309F57C69004E4BFF /* InfoPlist.strings */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1385, 731}}";
+ sepNavSelRange = "{256, 0}";
+ sepNavVisRect = "{{0, 0}, {1385, 731}}";
+ sepNavWindowFrame = "{{38, 142}, {1424, 860}}";
+ };
+ };
+}
diff --git a/src/MacOSX/UltraStarDX.xcodeproj/project.pbxproj b/src/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..d7902145
--- /dev/null
+++ b/src/MacOSX/UltraStarDX.xcodeproj/project.pbxproj
@@ -0,0 +1,1613 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 2C4B70230CF7581000B0F0BD /* Until5000.dpr in Sources */ = {isa = PBXBuildFile; fileRef = 2C4B70220CF757A400B0F0BD /* Until5000.dpr */; };
+ 2C4B70240CF7584500B0F0BD /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
+ 2C4D9C8F0CC9EC8C0031092D /* TextGL.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C620CC9EC8C0031092D /* TextGL.pas */; };
+ 2C4D9C920CC9EC8C0031092D /* UCatCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */; };
+ 2C4D9C930CC9EC8C0031092D /* UCommandLine.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */; };
+ 2C4D9C940CC9EC8C0031092D /* UCommon.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; };
+ 2C4D9C950CC9EC8C0031092D /* UCore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C680CC9EC8C0031092D /* UCore.pas */; };
+ 2C4D9C960CC9EC8C0031092D /* UCoreModule.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */; };
+ 2C4D9C970CC9EC8C0031092D /* UCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */; };
+ 2C4D9C980CC9EC8C0031092D /* UDataBase.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */; };
+ 2C4D9C990CC9EC8C0031092D /* UDLLManager.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */; };
+ 2C4D9C9A0CC9EC8C0031092D /* UDraw.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */; };
+ 2C4D9C9B0CC9EC8C0031092D /* UFiles.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */; };
+ 2C4D9C9C0CC9EC8C0031092D /* UGraphic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */; };
+ 2C4D9C9D0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */; };
+ 2C4D9C9E0CC9EC8C0031092D /* UHooks.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C710CC9EC8C0031092D /* UHooks.pas */; };
+ 2C4D9C9F0CC9EC8C0031092D /* UIni.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C720CC9EC8C0031092D /* UIni.pas */; };
+ 2C4D9CA00CC9EC8C0031092D /* UJoystick.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */; };
+ 2C4D9CA10CC9EC8C0031092D /* ULanguage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */; };
+ 2C4D9CA30CC9EC8C0031092D /* ULCD.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C760CC9EC8C0031092D /* ULCD.pas */; };
+ 2C4D9CA40CC9EC8C0031092D /* ULight.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C770CC9EC8C0031092D /* ULight.pas */; };
+ 2C4D9CA50CC9EC8C0031092D /* ULog.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C780CC9EC8C0031092D /* ULog.pas */; };
+ 2C4D9CA60CC9EC8C0031092D /* ULyrics_bak.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */; };
+ 2C4D9CA70CC9EC8C0031092D /* ULyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */; };
+ 2C4D9CA80CC9EC8C0031092D /* UMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; };
+ 2C4D9CA90CC9EC8C0031092D /* UMedia_dummy.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */; };
+ 2C4D9CAA0CC9EC8C0031092D /* UModules.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */; };
+ 2C4D9CAB0CC9EC8C0031092D /* UMusic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */; };
+ 2C4D9CAC0CC9EC8C0031092D /* UParty.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */; };
+ 2C4D9CAD0CC9EC8C0031092D /* UPlaylist.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */; };
+ 2C4D9CAF0CC9EC8C0031092D /* UPluginInterface.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */; };
+ 2C4D9CB00CC9EC8C0031092D /* uPluginLoader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */; };
+ 2C4D9CB10CC9EC8C0031092D /* URecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C840CC9EC8C0031092D /* URecord.pas */; };
+ 2C4D9CB20CC9EC8C0031092D /* UServices.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C850CC9EC8C0031092D /* UServices.pas */; };
+ 2C4D9CB30CC9EC8C0031092D /* USingNotes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */; };
+ 2C4D9CB40CC9EC8C0031092D /* USingScores.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C870CC9EC8C0031092D /* USingScores.pas */; };
+ 2C4D9CB50CC9EC8C0031092D /* USkins.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C880CC9EC8C0031092D /* USkins.pas */; };
+ 2C4D9CB60CC9EC8C0031092D /* USongs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */; };
+ 2C4D9CB70CC9EC8C0031092D /* UTextClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */; };
+ 2C4D9CB80CC9EC8C0031092D /* UTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; };
+ 2C4D9CB90CC9EC8C0031092D /* UThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */; };
+ 2C4D9CBA0CC9EC8C0031092D /* UTime.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */; };
+ 2C4D9CBB0CC9EC8C0031092D /* UVideo.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */; };
+ 2C4D9CBC0CC9EC8C0031092D /* TextGL.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C620CC9EC8C0031092D /* TextGL.pas */; };
+ 2C4D9CBF0CC9EC8C0031092D /* UCatCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */; };
+ 2C4D9CC00CC9EC8C0031092D /* UCommandLine.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */; };
+ 2C4D9CC10CC9EC8C0031092D /* UCommon.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; };
+ 2C4D9CC20CC9EC8C0031092D /* UCore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C680CC9EC8C0031092D /* UCore.pas */; };
+ 2C4D9CC30CC9EC8C0031092D /* UCoreModule.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */; };
+ 2C4D9CC40CC9EC8C0031092D /* UCovers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */; };
+ 2C4D9CC50CC9EC8C0031092D /* UDataBase.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */; };
+ 2C4D9CC60CC9EC8C0031092D /* UDLLManager.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */; };
+ 2C4D9CC70CC9EC8C0031092D /* UDraw.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */; };
+ 2C4D9CC80CC9EC8C0031092D /* UFiles.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */; };
+ 2C4D9CC90CC9EC8C0031092D /* UGraphic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */; };
+ 2C4D9CCA0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */; };
+ 2C4D9CCB0CC9EC8C0031092D /* UHooks.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C710CC9EC8C0031092D /* UHooks.pas */; };
+ 2C4D9CCC0CC9EC8C0031092D /* UIni.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C720CC9EC8C0031092D /* UIni.pas */; };
+ 2C4D9CCD0CC9EC8C0031092D /* UJoystick.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */; };
+ 2C4D9CCE0CC9EC8C0031092D /* ULanguage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */; };
+ 2C4D9CD00CC9EC8C0031092D /* ULCD.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C760CC9EC8C0031092D /* ULCD.pas */; };
+ 2C4D9CD10CC9EC8C0031092D /* ULight.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C770CC9EC8C0031092D /* ULight.pas */; };
+ 2C4D9CD20CC9EC8C0031092D /* ULog.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C780CC9EC8C0031092D /* ULog.pas */; };
+ 2C4D9CD30CC9EC8C0031092D /* ULyrics_bak.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */; };
+ 2C4D9CD40CC9EC8C0031092D /* ULyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */; };
+ 2C4D9CD50CC9EC8C0031092D /* UMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; };
+ 2C4D9CD60CC9EC8C0031092D /* UMedia_dummy.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */; };
+ 2C4D9CD70CC9EC8C0031092D /* UModules.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */; };
+ 2C4D9CD80CC9EC8C0031092D /* UMusic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */; };
+ 2C4D9CD90CC9EC8C0031092D /* UParty.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */; };
+ 2C4D9CDA0CC9EC8C0031092D /* UPlaylist.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */; };
+ 2C4D9CDC0CC9EC8C0031092D /* UPluginInterface.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */; };
+ 2C4D9CDD0CC9EC8C0031092D /* uPluginLoader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */; };
+ 2C4D9CDE0CC9EC8C0031092D /* URecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C840CC9EC8C0031092D /* URecord.pas */; };
+ 2C4D9CDF0CC9EC8C0031092D /* UServices.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C850CC9EC8C0031092D /* UServices.pas */; };
+ 2C4D9CE00CC9EC8C0031092D /* USingNotes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */; };
+ 2C4D9CE10CC9EC8C0031092D /* USingScores.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C870CC9EC8C0031092D /* USingScores.pas */; };
+ 2C4D9CE20CC9EC8C0031092D /* USkins.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C880CC9EC8C0031092D /* USkins.pas */; };
+ 2C4D9CE30CC9EC8C0031092D /* USongs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */; };
+ 2C4D9CE40CC9EC8C0031092D /* UTextClasses.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */; };
+ 2C4D9CE50CC9EC8C0031092D /* UTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; };
+ 2C4D9CE60CC9EC8C0031092D /* UThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */; };
+ 2C4D9CE70CC9EC8C0031092D /* UTime.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */; };
+ 2C4D9CE80CC9EC8C0031092D /* UVideo.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */; };
+ 2C4D9D920CC9ED4F0031092D /* FreeBitmap.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */; };
+ 2C4D9D930CC9ED4F0031092D /* FreeImage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */; };
+ 2C4D9D940CC9ED4F0031092D /* FreeBitmap.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */; };
+ 2C4D9D950CC9ED4F0031092D /* FreeImage.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */; };
+ 2C4D9D970CC9EDEB0031092D /* libfreeimage.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */; };
+ 2C4D9D9A0CC9EE0B0031092D /* SDL_image.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */; };
+ 2C4D9D9B0CC9EE0B0031092D /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */; };
+ 2C4D9DD60CC9EE6F0031092D /* UDisplay.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */; };
+ 2C4D9DD70CC9EE6F0031092D /* UDrawTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */; };
+ 2C4D9DD80CC9EE6F0031092D /* UMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */; };
+ 2C4D9DD90CC9EE6F0031092D /* UMenuButton.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */; };
+ 2C4D9DDA0CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */; };
+ 2C4D9DDB0CC9EE6F0031092D /* UMenuInteract.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */; };
+ 2C4D9DDC0CC9EE6F0031092D /* UMenuSelect.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */; };
+ 2C4D9DDD0CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */; };
+ 2C4D9DDE0CC9EE6F0031092D /* UMenuStatic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */; };
+ 2C4D9DDF0CC9EE6F0031092D /* UMenuText.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */; };
+ 2C4D9DE00CC9EE6F0031092D /* UDisplay.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */; };
+ 2C4D9DE10CC9EE6F0031092D /* UDrawTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */; };
+ 2C4D9DE20CC9EE6F0031092D /* UMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */; };
+ 2C4D9DE30CC9EE6F0031092D /* UMenuButton.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */; };
+ 2C4D9DE40CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */; };
+ 2C4D9DE50CC9EE6F0031092D /* UMenuInteract.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */; };
+ 2C4D9DE60CC9EE6F0031092D /* UMenuSelect.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */; };
+ 2C4D9DE70CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */; };
+ 2C4D9DE80CC9EE6F0031092D /* UMenuStatic.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */; };
+ 2C4D9DE90CC9EE6F0031092D /* UMenuText.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */; };
+ 2C4D9DED0CC9EF0A0031092D /* sdl_image.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */; };
+ 2C4D9DEE0CC9EF0A0031092D /* sdl_image.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */; };
+ 2C4D9DF10CC9EF210031092D /* sdl_ttf.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */; };
+ 2C4D9DF30CC9EF210031092D /* sdl_ttf.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */; };
+ 2C4D9E100CC9EF840031092D /* OpenGL12.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; };
+ 2C4D9E150CC9EF840031092D /* Windows.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E090CC9EF840031092D /* Windows.pas */; };
+ 2C4D9E1C0CC9EF840031092D /* OpenGL12.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; };
+ 2C4D9E210CC9EF840031092D /* Windows.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E090CC9EF840031092D /* Windows.pas */; };
+ 2C4D9E450CC9F0ED0031092D /* switches.inc in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E440CC9F0ED0031092D /* switches.inc */; };
+ 2C4D9E460CC9F0ED0031092D /* switches.inc in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D9E440CC9F0ED0031092D /* switches.inc */; };
+ 2C4FA2A80CDBAD1E002CC3B0 /* ustar-icon_v01.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */; };
+ 2C5663EF0D35645700D4FF53 /* portaudio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C5663EE0D35645700D4FF53 /* portaudio.pas */; };
+ 2C5663F00D35645700D4FF53 /* portaudio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C5663EE0D35645700D4FF53 /* portaudio.pas */; };
+ 2C56642C0D35683200D4FF53 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C56642B0D35683200D4FF53 /* SDLMain.m */; };
+ 2C89372A0CE393FB005D8A87 /* UPlatform.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937290CE393FB005D8A87 /* UPlatform.pas */; };
+ 2C89372B0CE393FB005D8A87 /* UPlatform.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937290CE393FB005D8A87 /* UPlatform.pas */; };
+ 2C8937340CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; };
+ 2C8937370CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; };
+ 2CAC2BE20D3809F500CA518A /* UAudioInput_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */; };
+ 2CAC2BE40D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; };
+ 2CAC2BE70D3809F500CA518A /* UAudioInput_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */; };
+ 2CAC2BE90D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; };
+ 2CAC2BF10D380AC200CA518A /* libbass.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CAC2BF00D380AC200CA518A /* libbass.dylib */; };
+ 2CAC2BF40D380AE800CA518A /* libbass.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CAC2BF00D380AC200CA518A /* libbass.dylib */; };
+ 2CAC2BF80D380B1B00CA518A /* Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BF70D380B1B00CA518A /* Bass.pas */; };
+ 2CAC2BF90D380B1B00CA518A /* Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CAC2BF70D380B1B00CA518A /* Bass.pas */; };
+ 2CB9E87E0D43B78400214DFA /* USong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E87D0D43B78400214DFA /* USong.pas */; };
+ 2CB9E87F0D43B78400214DFA /* USong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E87D0D43B78400214DFA /* USong.pas */; };
+ 2CDC716C0CDB9CB70018F966 /* StrUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */; };
+ 2CDC716D0CDB9CB70018F966 /* StrUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */; };
+ 2CDD4BDE0CB947A400549FAC /* sdl.pas in Sources */ = {isa = PBXBuildFile; fileRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */; };
+ 2CDD4BE00CB947B100549FAC /* sdl.pas in Sources */ = {isa = PBXBuildFile; fileRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */; };
+ 2CDD4BE20CB947BE00549FAC /* UltraStarDX.pas in Sources */ = {isa = PBXBuildFile; fileRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; };
+ 2CDEA4F70CBD725B0096994C /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CDEA4F60CBD725B0096994C /* OpenGL.framework */; };
+ 2CDEC4960CC5264600FFA244 /* SDL.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98B8BE570B1F972400162019 /* SDL.framework */; };
+ 2CE603DA0D715F2100DB0D88 /* mathematics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603D90D715F2100DB0D88 /* mathematics.pas */; };
+ 2CE603DB0D715F2100DB0D88 /* mathematics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603D90D715F2100DB0D88 /* mathematics.pas */; };
+ 2CE603DE0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; };
+ 2CE603DF0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; };
+ 2CE603E20D715F8600DB0D88 /* UConfig.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603E10D715F8600DB0D88 /* UConfig.pas */; };
+ 2CE603E30D715F8600DB0D88 /* UConfig.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CE603E10D715F8600DB0D88 /* UConfig.pas */; };
+ 2CE907930D1BC8A800A1FDFF /* libavcodec.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */; };
+ 2CE907940D1BC8A800A1FDFF /* libavformat.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */; };
+ 2CE907950D1BC8A800A1FDFF /* libavutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */; };
+ 2CE907980D1BC90A00A1FDFF /* libavcodec.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */; };
+ 2CE907990D1BC91D00A1FDFF /* libavformat.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */; };
+ 2CE9079A0D1BC91D00A1FDFF /* libavutil.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */; };
+ 2CEA2AE00CE385190097A5FF /* Graphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADE0CE385190097A5FF /* Graphics.pas */; };
+ 2CEA2AE10CE385190097A5FF /* JPEG.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADF0CE385190097A5FF /* JPEG.pas */; };
+ 2CEA2AE20CE385190097A5FF /* Graphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADE0CE385190097A5FF /* Graphics.pas */; };
+ 2CEA2AE30CE385190097A5FF /* JPEG.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2ADF0CE385190097A5FF /* JPEG.pas */; };
+ 2CEA2AF10CE3868E0097A5FF /* PseudoThread.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */; };
+ 2CEA2AF20CE3868E0097A5FF /* PseudoThread.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */; };
+ 2CF3EF220CDE13A0004F5956 /* Messages.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF210CDE13A0004F5956 /* Messages.pas */; };
+ 2CF3EF230CDE13A0004F5956 /* Messages.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF210CDE13A0004F5956 /* Messages.pas */; };
+ 2CF3EF270CDE13BA004F5956 /* MacResources.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF260CDE13BA004F5956 /* MacResources.pas */; };
+ 2CF3EF280CDE13BA004F5956 /* MacResources.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF3EF260CDE13BA004F5956 /* MacResources.pas */; };
+ 2CF54F650CDA1B2B00627463 /* UScreenCredits.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */; };
+ 2CF54F660CDA1B2B00627463 /* UScreenEdit.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */; };
+ 2CF54F670CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */; };
+ 2CF54F680CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */; };
+ 2CF54F690CDA1B2B00627463 /* UScreenEditSub.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */; };
+ 2CF54F6A0CDA1B2B00627463 /* UScreenLevel.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */; };
+ 2CF54F6B0CDA1B2B00627463 /* UScreenLoading.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */; };
+ 2CF54F6C0CDA1B2B00627463 /* UScreenMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; };
+ 2CF54F6D0CDA1B2B00627463 /* UScreenName.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */; };
+ 2CF54F6E0CDA1B2B00627463 /* UScreenOpen.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */; };
+ 2CF54F6F0CDA1B2B00627463 /* UScreenOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */; };
+ 2CF54F700CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */; };
+ 2CF54F710CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */; };
+ 2CF54F720CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */; };
+ 2CF54F730CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */; };
+ 2CF54F740CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */; };
+ 2CF54F750CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */; };
+ 2CF54F760CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */; };
+ 2CF54F770CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */; };
+ 2CF54F780CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */; };
+ 2CF54F790CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */; };
+ 2CF54F7A0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */; };
+ 2CF54F7B0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */; };
+ 2CF54F7C0CDA1B2B00627463 /* UScreenPopup.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */; };
+ 2CF54F7D0CDA1B2B00627463 /* UScreenScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */; };
+ 2CF54F7E0CDA1B2B00627463 /* UScreenSing.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */; };
+ 2CF54F7F0CDA1B2B00627463 /* UScreenSingModi.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */; };
+ 2CF54F800CDA1B2B00627463 /* UScreenSong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */; };
+ 2CF54F810CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */; };
+ 2CF54F820CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */; };
+ 2CF54F830CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */; };
+ 2CF54F840CDA1B2B00627463 /* UScreenStatMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */; };
+ 2CF54F850CDA1B2B00627463 /* UScreenTop5.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */; };
+ 2CF54F860CDA1B2B00627463 /* UScreenWelcome.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */; };
+ 2CF54F870CDA1B2B00627463 /* UScreenCredits.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */; };
+ 2CF54F880CDA1B2B00627463 /* UScreenEdit.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */; };
+ 2CF54F890CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */; };
+ 2CF54F8A0CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */; };
+ 2CF54F8B0CDA1B2B00627463 /* UScreenEditSub.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */; };
+ 2CF54F8C0CDA1B2B00627463 /* UScreenLevel.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */; };
+ 2CF54F8D0CDA1B2B00627463 /* UScreenLoading.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */; };
+ 2CF54F8E0CDA1B2B00627463 /* UScreenMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; };
+ 2CF54F8F0CDA1B2B00627463 /* UScreenName.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */; };
+ 2CF54F900CDA1B2B00627463 /* UScreenOpen.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */; };
+ 2CF54F910CDA1B2B00627463 /* UScreenOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */; };
+ 2CF54F920CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */; };
+ 2CF54F930CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */; };
+ 2CF54F940CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */; };
+ 2CF54F950CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */; };
+ 2CF54F960CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */; };
+ 2CF54F970CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */; };
+ 2CF54F980CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */; };
+ 2CF54F990CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */; };
+ 2CF54F9A0CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */; };
+ 2CF54F9B0CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */; };
+ 2CF54F9C0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */; };
+ 2CF54F9D0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */; };
+ 2CF54F9E0CDA1B2B00627463 /* UScreenPopup.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */; };
+ 2CF54F9F0CDA1B2B00627463 /* UScreenScore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */; };
+ 2CF54FA00CDA1B2B00627463 /* UScreenSing.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */; };
+ 2CF54FA10CDA1B2B00627463 /* UScreenSingModi.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */; };
+ 2CF54FA20CDA1B2B00627463 /* UScreenSong.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */; };
+ 2CF54FA30CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */; };
+ 2CF54FA40CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */; };
+ 2CF54FA50CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */; };
+ 2CF54FA60CDA1B2B00627463 /* UScreenStatMain.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */; };
+ 2CF54FA70CDA1B2B00627463 /* UScreenTop5.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */; };
+ 2CF54FA80CDA1B2B00627463 /* UScreenWelcome.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */; };
+ 2CF5508C0CDA22B000627463 /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
+ 2CF5508D0CDA22B000627463 /* ModiSDK.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5508B0CDA22B000627463 /* ModiSDK.pas */; };
+ 2CF551100CDA293700627463 /* SQLite3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510E0CDA293700627463 /* SQLite3.pas */; };
+ 2CF551110CDA293700627463 /* SQLiteTable3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */; };
+ 2CF551120CDA293700627463 /* SQLite3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510E0CDA293700627463 /* SQLite3.pas */; };
+ 2CF551130CDA293700627463 /* SQLiteTable3.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */; };
+ 2CF5512D0CDA29C600627463 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */; };
+ 2CF552140CDA3D1400627463 /* UPluginDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552110CDA3D1400627463 /* UPluginDefs.pas */; };
+ 2CF552170CDA3D1400627463 /* UPluginDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552110CDA3D1400627463 /* UPluginDefs.pas */; };
+ 2CF552A70CDA42C900627463 /* avcodec.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529E0CDA42C900627463 /* avcodec.pas */; };
+ 2CF552A80CDA42C900627463 /* avformat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529F0CDA42C900627463 /* avformat.pas */; };
+ 2CF552A90CDA42C900627463 /* avio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A00CDA42C900627463 /* avio.pas */; };
+ 2CF552AA0CDA42C900627463 /* avutil.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A10CDA42C900627463 /* avutil.pas */; };
+ 2CF552AD0CDA42C900627463 /* opt.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A40CDA42C900627463 /* opt.pas */; };
+ 2CF552AE0CDA42C900627463 /* rational.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A50CDA42C900627463 /* rational.pas */; };
+ 2CF552B00CDA42C900627463 /* avcodec.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529E0CDA42C900627463 /* avcodec.pas */; };
+ 2CF552B10CDA42C900627463 /* avformat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF5529F0CDA42C900627463 /* avformat.pas */; };
+ 2CF552B20CDA42C900627463 /* avio.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A00CDA42C900627463 /* avio.pas */; };
+ 2CF552B30CDA42C900627463 /* avutil.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A10CDA42C900627463 /* avutil.pas */; };
+ 2CF552B60CDA42C900627463 /* opt.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A40CDA42C900627463 /* opt.pas */; };
+ 2CF552B70CDA42C900627463 /* rational.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF552A50CDA42C900627463 /* rational.pas */; };
+ 2CF553080CDA51B500627463 /* sdlutils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF553070CDA51B500627463 /* sdlutils.pas */; };
+ 2CF553090CDA51B500627463 /* sdlutils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF553070CDA51B500627463 /* sdlutils.pas */; };
+ 2CF553100CDA52D100627463 /* SDL_image.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */; };
+ 2CF5533B0CDA52E200627463 /* SDL_ttf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */; };
+ 2CF5533F0CDA531100627463 /* libfreeimage.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */; };
+ 2CF553400CDA531100627463 /* libsqlite3.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */; };
+ 2CF8E6BE0CDFA8E80053A996 /* UPartyDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */; };
+ 2CF8E6BF0CDFA8E80053A996 /* UPartyDefs.pas in Sources */ = {isa = PBXBuildFile; fileRef = 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */; };
+ 98B8BE340B1F947800162019 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE330B1F947800162019 /* AppKit.framework */; };
+ 98B8BE390B1F949C00162019 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE370B1F949C00162019 /* Cocoa.framework */; };
+ 98B8BE3A0B1F949C00162019 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE380B1F949C00162019 /* Foundation.framework */; };
+ 98B8BE580B1F972400162019 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98B8BE570B1F972400162019 /* SDL.framework */; };
+ DD37F23D0A60252800975B2D /* UltraStarDX.pas in Sources */ = {isa = PBXBuildFile; fileRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; };
+ DD37F2C70A6037EA00975B2D /* libfpcrtl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD37F2430A60255800975B2D /* libfpcrtl.a */; };
+ DDC689B509F57C69004E4BFF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDC689B309F57C69004E4BFF /* InfoPlist.strings */; };
+ DDC689B609F57C69004E4BFF /* SDLMain.nib in Resources */ = {isa = PBXBuildFile; fileRef = DDC689B409F57C69004E4BFF /* SDLMain.nib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXBuildRule section */
+ DD7C44CD0A6E5050003FA52B /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ filePatterns = "*.inc";
+ fileType = pattern.proxy;
+ isEditable = 1;
+ outputFiles = (
+ "$(TARGET_TEMP_DIR)/$(INPUT_FILE_NAME).compiled",
+ );
+ script = "echo \\\"-Fi$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\ntouch \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled\n";
+ };
+ DD7C45710A6E7E36003FA52B /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ filePatterns = "*.inc";
+ fileType = pattern.proxy;
+ isEditable = 1;
+ outputFiles = (
+ );
+ script = "";
+ };
+ DDC688F309F57599004E4BFF /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ fileType = sourcecode.pascal;
+ isEditable = 1;
+ outputFiles = (
+ "$(TARGET_TEMP_DIR)/$(INPUT_FILE_NAME).compiled",
+ );
+ script = "# set -vx\n\n# if FPC_MAIN_FILE is specified, only use that one\nif test \"x$FPC_MAIN_FILE\" = x ; then\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" >> \"$PROJECT_TEMP_DIR\"/files_to_compile\nelif test \"x$INPUT_FILE_NAME\" = \"x$FPC_MAIN_FILE\" || test \"x$INPUT_FILE_PATH\" = \"x$FPC_MAIN_FILE\" ; then\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/files_to_compile\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/mainfile\nfi\n\necho \\\"-Fu$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\necho \\\"-Fi$INPUT_FILE_DIR\\\" >> \"$PROJECT_TEMP_DIR\"/unitpaths\n\n# if this file was not yet before compiled, it may be a new file -> delete\n# source cache (there might be a new mainfile now, unless FPC_MAIN_FILE is specified)\nif test ! -f \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled && test \"x$FPC_MAIN_FILE\" = x ; then\n cd \"$PROJECT_TEMP_DIR\"\n rm -f mainfile scriptrun > /dev/null 2>&1\nfi\n\ntouch \"$TARGET_TEMP_DIR\"/\"$INPUT_FILE_NAME\".compiled\n";
+ };
+ DDC6891509F57648004E4BFF /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ fileType = sourcecode.pascal;
+ isEditable = 1;
+ outputFiles = (
+ "$(PROJECT_DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).s",
+ );
+ script = "";
+ };
+/* End PBXBuildRule section */
+
+/* Begin PBXContainerItemProxy section */
+ DD37F25D0A60268D00975B2D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DDC6850F09F5717A004E4BFF /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DD37F2420A60255800975B2D;
+ remoteInfo = fpcrtl;
+ };
+ DDC688ED09F57578004E4BFF /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DDC6850F09F5717A004E4BFF /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DDC688D409F57523004E4BFF;
+ remoteInfo = "Put unit sources in the 'Compile Sources' phase of this target";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 2CDEC44F0CC5255600FFA244 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 6;
+ files = (
+ 2CAC2BF40D380AE800CA518A /* libbass.dylib in CopyFiles */,
+ 2CE907990D1BC91D00A1FDFF /* libavformat.dylib in CopyFiles */,
+ 2CE9079A0D1BC91D00A1FDFF /* libavutil.dylib in CopyFiles */,
+ 2CE907980D1BC90A00A1FDFF /* libavcodec.dylib in CopyFiles */,
+ 2CF5533F0CDA531100627463 /* libfreeimage.dylib in CopyFiles */,
+ 2CF553400CDA531100627463 /* libsqlite3.dylib in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2CDEC4940CC5262700FFA244 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 2CDEC4960CC5264600FFA244 /* SDL.framework in CopyFiles */,
+ 2CF553100CDA52D100627463 /* SDL_image.framework in CopyFiles */,
+ 2CF5533B0CDA52E200627463 /* SDL_ttf.framework in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* 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; };
+ 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCommandLine.pas; path = ../Classes/UCommandLine.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C670CC9EC8C0031092D /* UCommon.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCommon.pas; path = ../Classes/UCommon.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C680CC9EC8C0031092D /* UCore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCore.pas; path = ../Classes/UCore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCoreModule.pas; path = ../Classes/UCoreModule.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCovers.pas; path = ../Classes/UCovers.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDataBase.pas; path = ../Classes/UDataBase.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDLLManager.pas; path = ../Classes/UDLLManager.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDraw.pas; path = ../Classes/UDraw.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UFiles.pas; path = ../Classes/UFiles.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UGraphic.pas; path = ../Classes/UGraphic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UGraphicClasses.pas; path = ../Classes/UGraphicClasses.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C710CC9EC8C0031092D /* UHooks.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UHooks.pas; path = ../Classes/UHooks.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C720CC9EC8C0031092D /* UIni.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UIni.pas; path = ../Classes/UIni.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */ = {isa = PBXFileReference; explicitFileType = sourcecode.pascal; fileEncoding = 5; indentWidth = 2; name = UJoystick.pas; path = ../Classes/UJoystick.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULanguage.pas; path = ../Classes/ULanguage.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C760CC9EC8C0031092D /* ULCD.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULCD.pas; path = ../Classes/ULCD.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C770CC9EC8C0031092D /* ULight.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULight.pas; path = ../Classes/ULight.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C780CC9EC8C0031092D /* ULog.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULog.pas; path = ../Classes/ULog.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULyrics_bak.pas; path = ../Classes/ULyrics_bak.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ULyrics.pas; path = ../Classes/ULyrics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMain.pas; path = ../Classes/UMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMedia_dummy.pas; path = ../Classes/UMedia_dummy.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UModules.pas; path = ../Classes/UModules.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMusic.pas; path = ../Classes/UMusic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UParty.pas; path = ../Classes/UParty.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPlaylist.pas; path = ../Classes/UPlaylist.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPluginInterface.pas; path = ../Classes/UPluginInterface.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = uPluginLoader.pas; path = ../Classes/uPluginLoader.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C840CC9EC8C0031092D /* URecord.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = URecord.pas; path = ../Classes/URecord.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C850CC9EC8C0031092D /* UServices.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UServices.pas; path = ../Classes/UServices.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USingNotes.pas; path = ../Classes/USingNotes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C870CC9EC8C0031092D /* USingScores.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USingScores.pas; path = ../Classes/USingScores.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C880CC9EC8C0031092D /* USkins.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USkins.pas; path = ../Classes/USkins.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C890CC9EC8C0031092D /* USongs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = USongs.pas; path = ../Classes/USongs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTextClasses.pas; path = ../Classes/UTextClasses.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTexture.pas; path = ../Classes/UTexture.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UThemes.pas; path = ../Classes/UThemes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UTime.pas; path = ../Classes/UTime.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UVideo.pas; path = ../Classes/UVideo.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = FreeBitmap.pas; path = ../lib/FreeImage/FreeBitmap.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = FreeImage.pas; path = ../lib/FreeImage/FreeImage.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreeimage.dylib; path = ../lib/FreeImage/libfreeimage.dylib; sourceTree = SOURCE_ROOT; };
+ 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_image.framework; path = /Library/Frameworks/SDL_image.framework; sourceTree = ""; };
+ 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = ""; };
+ 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDisplay.pas; path = ../Menu/UDisplay.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UDrawTexture.pas; path = ../Menu/UDrawTexture.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenu.pas; path = ../Menu/UMenu.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuButton.pas; path = ../Menu/UMenuButton.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuButtonCollection.pas; path = ../Menu/UMenuButtonCollection.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuInteract.pas; path = ../Menu/UMenuInteract.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuSelect.pas; path = ../Menu/UMenuSelect.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuSelectSlide.pas; path = ../Menu/UMenuSelectSlide.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuStatic.pas; path = ../Menu/UMenuStatic.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UMenuText.pas; path = ../Menu/UMenuText.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl_image.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL_image/sdl_image.pas"; sourceTree = ""; tabWidth = 2; };
+ 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl_ttf.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL_ttf/sdl_ttf.pas"; sourceTree = ""; tabWidth = 2; };
+ 2C4D9E040CC9EF840031092D /* OpenGL12.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = OpenGL12.pas; path = Wrapper/OpenGL12.pas; sourceTree = ""; tabWidth = 2; };
+ 2C4D9E090CC9EF840031092D /* Windows.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = Windows.pas; path = Wrapper/Windows.pas; sourceTree = ""; tabWidth = 2; };
+ 2C4D9E440CC9F0ED0031092D /* switches.inc */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = switches.inc; path = ../switches.inc; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = "ustar-icon_v01.icns"; path = "../../Graphics/ustar-icon_v01.icns"; sourceTree = SOURCE_ROOT; };
+ 2C5663EE0D35645700D4FF53 /* portaudio.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = portaudio.pas; path = ../lib/portaudio/delphi/portaudio.pas; sourceTree = SOURCE_ROOT; };
+ 2C56642B0D35683200D4FF53 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = SDLMain.m; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/SDLMain.m"; sourceTree = ""; };
+ 2C56642F0D35688200D4FF53 /* SDL.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = SDL.h; path = /Library/Frameworks/SDL.framework/Versions/A/Headers/SDL.h; sourceTree = ""; };
+ 2C8937290CE393FB005D8A87 /* UPlatform.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UPlatform.pas; path = ../Classes/UPlatform.pas; sourceTree = SOURCE_ROOT; };
+ 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; lineEnding = 0; name = UPlatformMacOSX.pas; path = ../Classes/UPlatformMacOSX.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UAudioInput_Bass.pas; path = ../Classes/UAudioInput_Bass.pas; sourceTree = SOURCE_ROOT; };
+ 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = UAudioPlayback_Bass.pas; path = ../Classes/UAudioPlayback_Bass.pas; sourceTree = SOURCE_ROOT; };
+ 2CAC2BF00D380AC200CA518A /* libbass.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbass.dylib; path = ../lib/bass/libbass.dylib; sourceTree = SOURCE_ROOT; };
+ 2CAC2BF70D380B1B00CA518A /* Bass.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = Bass.pas; path = ../lib/bass/MacOSX/Bass.pas; sourceTree = SOURCE_ROOT; };
+ 2CB9E87D0D43B78400214DFA /* USong.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = USong.pas; path = ../Classes/USong.pas; sourceTree = SOURCE_ROOT; };
+ 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = StrUtils.pas; path = ../../../Modis/SDK/StrUtils.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CDEA4F60CBD725B0096994C /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; };
+ 2CE603D90D715F2100DB0D88 /* mathematics.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = mathematics.pas; path = ../lib/ffmpeg/mathematics.pas; sourceTree = SOURCE_ROOT; };
+ 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = UAudioCore_Bass.pas; path = ../Classes/UAudioCore_Bass.pas; sourceTree = SOURCE_ROOT; };
+ 2CE603E10D715F8600DB0D88 /* UConfig.pas */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.pascal; name = UConfig.pas; path = ../Classes/UConfig.pas; sourceTree = SOURCE_ROOT; };
+ 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.dylib; path = ../lib/ffmpeg/libavcodec.dylib; sourceTree = SOURCE_ROOT; };
+ 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavformat.dylib; path = ../lib/ffmpeg/libavformat.dylib; sourceTree = SOURCE_ROOT; };
+ 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavutil.dylib; path = ../lib/ffmpeg/libavutil.dylib; sourceTree = SOURCE_ROOT; };
+ 2CEA2ADE0CE385190097A5FF /* Graphics.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = Graphics.pas; path = Wrapper/Graphics.pas; sourceTree = ""; };
+ 2CEA2ADF0CE385190097A5FF /* JPEG.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = JPEG.pas; path = Wrapper/JPEG.pas; sourceTree = ""; };
+ 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = PseudoThread.pas; path = Wrapper/PseudoThread.pas; sourceTree = ""; };
+ 2CF3EF210CDE13A0004F5956 /* Messages.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = Messages.pas; path = Wrapper/Messages.pas; sourceTree = ""; tabWidth = 2; };
+ 2CF3EF260CDE13BA004F5956 /* MacResources.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = MacResources.pas; path = Wrapper/MacResources.pas; sourceTree = ""; tabWidth = 2; };
+ 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenCredits.pas; path = ../Screens/UScreenCredits.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEdit.pas; path = ../Screens/UScreenEdit.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditConvert.pas; path = ../Screens/UScreenEditConvert.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditHeader.pas; path = ../Screens/UScreenEditHeader.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenEditSub.pas; path = ../Screens/UScreenEditSub.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenLevel.pas; path = ../Screens/UScreenLevel.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenLoading.pas; path = ../Screens/UScreenLoading.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenMain.pas; path = ../Screens/UScreenMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenName.pas; path = ../Screens/UScreenName.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOpen.pas; path = ../Screens/UScreenOpen.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptions.pas; path = ../Screens/UScreenOptions.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsAdvanced.pas; path = ../Screens/UScreenOptionsAdvanced.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsGame.pas; path = ../Screens/UScreenOptionsGame.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsGraphics.pas; path = ../Screens/UScreenOptionsGraphics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsLyrics.pas; path = ../Screens/UScreenOptionsLyrics.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsRecord.pas; path = ../Screens/UScreenOptionsRecord.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsSound.pas; path = ../Screens/UScreenOptionsSound.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenOptionsThemes.pas; path = ../Screens/UScreenOptionsThemes.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyNewRound.pas; path = ../Screens/UScreenPartyNewRound.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyOptions.pas; path = ../Screens/UScreenPartyOptions.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyPlayer.pas; path = ../Screens/UScreenPartyPlayer.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyScore.pas; path = ../Screens/UScreenPartyScore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPartyWin.pas; path = ../Screens/UScreenPartyWin.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenPopup.pas; path = ../Screens/UScreenPopup.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenScore.pas; path = ../Screens/UScreenScore.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSing.pas; path = ../Screens/UScreenSing.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSingModi.pas; path = ../Screens/UScreenSingModi.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSong.pas; path = ../Screens/UScreenSong.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSongJumpto.pas; path = ../Screens/UScreenSongJumpto.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenSongMenu.pas; path = ../Screens/UScreenSongMenu.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenStatDetail.pas; path = ../Screens/UScreenStatDetail.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenStatMain.pas; path = ../Screens/UScreenStatMain.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenTop5.pas; path = ../Screens/UScreenTop5.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UScreenWelcome.pas; path = ../Screens/UScreenWelcome.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5508B0CDA22B000627463 /* ModiSDK.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = ModiSDK.pas; path = ../../../Modis/SDK/ModiSDK.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5510E0CDA293700627463 /* SQLite3.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = SQLite3.pas; path = ../lib/SQLite/SQLite3.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = SQLiteTable3.pas; path = ../lib/SQLite/SQLiteTable3.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = ../lib/SQLite/libsqlite3.dylib; sourceTree = SOURCE_ROOT; };
+ 2CF551A70CDA356800627463 /* UltraStar.dpr */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = text; name = UltraStar.dpr; path = ../UltraStar.dpr; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF552110CDA3D1400627463 /* UPluginDefs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPluginDefs.pas; path = ../../../Modis/SDK/UPluginDefs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5529E0CDA42C900627463 /* avcodec.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avcodec.pas; path = ../lib/ffmpeg/avcodec.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF5529F0CDA42C900627463 /* avformat.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avformat.pas; path = ../lib/ffmpeg/avformat.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF552A00CDA42C900627463 /* avio.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avio.pas; path = ../lib/ffmpeg/avio.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF552A10CDA42C900627463 /* avutil.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = avutil.pas; path = ../lib/ffmpeg/avutil.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF552A40CDA42C900627463 /* opt.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = opt.pas; path = ../lib/ffmpeg/opt.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF552A50CDA42C900627463 /* rational.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = rational.pas; path = ../lib/ffmpeg/rational.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 2CF553070CDA51B500627463 /* sdlutils.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdlutils.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/sdlutils.pas"; sourceTree = ""; tabWidth = 2; };
+ 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libLib_UltraPong.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UPartyDefs.pas; path = ../../../Modis/SDK/UPartyDefs.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; };
+ 98B8BE330B1F947800162019 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = ""; };
+ 98B8BE370B1F949C00162019 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = ""; };
+ 98B8BE380B1F949C00162019 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = ""; };
+ 98B8BE570B1F972400162019 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; };
+ 98B8BE5C0B1F974F00162019 /* sdl.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = sdl.pas; path = "/Library/Frameworks/JEDI-SDL.framework/SDL/sdl.pas"; sourceTree = ""; tabWidth = 2; };
+ DD37F2430A60255800975B2D /* libfpcrtl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfpcrtl.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ DDC6851B09F57195004E4BFF /* UltraStarDX.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; path = UltraStarDX.pas; sourceTree = ""; tabWidth = 2; };
+ DDC6868B09F571C2004E4BFF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; };
+ DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UltraStar Deluxe.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ DDC688CA09F574E9004E4BFF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; };
+ DDC689B309F57C69004E4BFF /* InfoPlist.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = InfoPlist.strings; path = English.lproj/InfoPlist.strings; sourceTree = ""; };
+ DDC689B409F57C69004E4BFF /* SDLMain.nib */ = {isa = PBXFileReference; explicitFileType = wrapper.nib; name = SDLMain.nib; path = English.lproj/SDLMain.nib; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 2CF77DB40CF7556C00F3B101 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DDC688C609F574E9004E4BFF /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DD37F2C70A6037EA00975B2D /* libfpcrtl.a in Frameworks */,
+ 98B8BE340B1F947800162019 /* AppKit.framework in Frameworks */,
+ 98B8BE390B1F949C00162019 /* Cocoa.framework in Frameworks */,
+ 98B8BE3A0B1F949C00162019 /* Foundation.framework in Frameworks */,
+ 98B8BE580B1F972400162019 /* SDL.framework in Frameworks */,
+ 2CDEA4F70CBD725B0096994C /* OpenGL.framework in Frameworks */,
+ 2C4D9D970CC9EDEB0031092D /* libfreeimage.dylib in Frameworks */,
+ 2C4D9D9A0CC9EE0B0031092D /* SDL_image.framework in Frameworks */,
+ 2C4D9D9B0CC9EE0B0031092D /* SDL_ttf.framework in Frameworks */,
+ 2CF5512D0CDA29C600627463 /* libsqlite3.dylib in Frameworks */,
+ 2CE907930D1BC8A800A1FDFF /* libavcodec.dylib in Frameworks */,
+ 2CE907940D1BC8A800A1FDFF /* libavformat.dylib in Frameworks */,
+ 2CE907950D1BC8A800A1FDFF /* libavutil.dylib in Frameworks */,
+ 2CAC2BF10D380AC200CA518A /* libbass.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 2C4D9DEB0CC9EECC0031092D /* SDL */ = {
+ isa = PBXGroup;
+ children = (
+ 2C56642F0D35688200D4FF53 /* SDL.h */,
+ 2C56642B0D35683200D4FF53 /* SDLMain.m */,
+ 2CF553070CDA51B500627463 /* sdlutils.pas */,
+ 2C4D9DEF0CC9EF210031092D /* sdl_ttf.pas */,
+ 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */,
+ 98B8BE5C0B1F974F00162019 /* sdl.pas */,
+ );
+ name = SDL;
+ sourceTree = "";
+ };
+ 2C4D9DF50CC9EF3A0031092D /* Wrapper */ = {
+ isa = PBXGroup;
+ children = (
+ 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */,
+ 2CEA2ADE0CE385190097A5FF /* Graphics.pas */,
+ 2CEA2ADF0CE385190097A5FF /* JPEG.pas */,
+ 2CF3EF260CDE13BA004F5956 /* MacResources.pas */,
+ 2CF3EF210CDE13A0004F5956 /* Messages.pas */,
+ 2C4D9E040CC9EF840031092D /* OpenGL12.pas */,
+ 2C4D9E090CC9EF840031092D /* Windows.pas */,
+ );
+ name = Wrapper;
+ sourceTree = "";
+ };
+ 2C5663EC0D35642E00D4FF53 /* portaudio */ = {
+ isa = PBXGroup;
+ children = (
+ 2C5663EE0D35645700D4FF53 /* portaudio.pas */,
+ );
+ name = portaudio;
+ sourceTree = "";
+ };
+ 2CAC2BF60D380B0800CA518A /* BASS */ = {
+ isa = PBXGroup;
+ children = (
+ 2CAC2BF70D380B1B00CA518A /* Bass.pas */,
+ );
+ name = BASS;
+ sourceTree = "";
+ };
+ 2CDD43820CBBE8D400F364DE /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 2CE603E10D715F8600DB0D88 /* UConfig.pas */,
+ 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */,
+ 2CB9E87D0D43B78400214DFA /* USong.pas */,
+ 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */,
+ 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */,
+ 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */,
+ 2C8937290CE393FB005D8A87 /* UPlatform.pas */,
+ 2C4D9C620CC9EC8C0031092D /* TextGL.pas */,
+ 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */,
+ 2C4D9C660CC9EC8C0031092D /* UCommandLine.pas */,
+ 2C4D9C670CC9EC8C0031092D /* UCommon.pas */,
+ 2C4D9C680CC9EC8C0031092D /* UCore.pas */,
+ 2C4D9C690CC9EC8C0031092D /* UCoreModule.pas */,
+ 2C4D9C6A0CC9EC8C0031092D /* UCovers.pas */,
+ 2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */,
+ 2C4D9C6C0CC9EC8C0031092D /* UDLLManager.pas */,
+ 2C4D9C6D0CC9EC8C0031092D /* UDraw.pas */,
+ 2C4D9C6E0CC9EC8C0031092D /* UFiles.pas */,
+ 2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */,
+ 2C4D9C700CC9EC8C0031092D /* UGraphicClasses.pas */,
+ 2C4D9C710CC9EC8C0031092D /* UHooks.pas */,
+ 2C4D9C720CC9EC8C0031092D /* UIni.pas */,
+ 2C4D9C730CC9EC8C0031092D /* UJoystick.pas */,
+ 2C4D9C740CC9EC8C0031092D /* ULanguage.pas */,
+ 2C4D9C760CC9EC8C0031092D /* ULCD.pas */,
+ 2C4D9C770CC9EC8C0031092D /* ULight.pas */,
+ 2C4D9C780CC9EC8C0031092D /* ULog.pas */,
+ 2C4D9C790CC9EC8C0031092D /* ULyrics_bak.pas */,
+ 2C4D9C7A0CC9EC8C0031092D /* ULyrics.pas */,
+ 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */,
+ 2C4D9C7C0CC9EC8C0031092D /* UMedia_dummy.pas */,
+ 2C4D9C7D0CC9EC8C0031092D /* UModules.pas */,
+ 2C4D9C7E0CC9EC8C0031092D /* UMusic.pas */,
+ 2C4D9C7F0CC9EC8C0031092D /* UParty.pas */,
+ 2C4D9C800CC9EC8C0031092D /* UPlaylist.pas */,
+ 2C4D9C820CC9EC8C0031092D /* UPluginInterface.pas */,
+ 2C4D9C830CC9EC8C0031092D /* uPluginLoader.pas */,
+ 2C4D9C840CC9EC8C0031092D /* URecord.pas */,
+ 2C4D9C850CC9EC8C0031092D /* UServices.pas */,
+ 2C4D9C860CC9EC8C0031092D /* USingNotes.pas */,
+ 2C4D9C870CC9EC8C0031092D /* USingScores.pas */,
+ 2C4D9C880CC9EC8C0031092D /* USkins.pas */,
+ 2C4D9C890CC9EC8C0031092D /* USongs.pas */,
+ 2C4D9C8A0CC9EC8C0031092D /* UTextClasses.pas */,
+ 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */,
+ 2C4D9C8C0CC9EC8C0031092D /* UThemes.pas */,
+ 2C4D9C8D0CC9EC8C0031092D /* UTime.pas */,
+ 2C4D9C8E0CC9EC8C0031092D /* UVideo.pas */,
+ );
+ name = Classes;
+ sourceTree = "";
+ };
+ 2CDD438D0CBBE8F700F364DE /* Menu */ = {
+ isa = PBXGroup;
+ children = (
+ 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */,
+ 2C4D9DCD0CC9EE6F0031092D /* UDrawTexture.pas */,
+ 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */,
+ 2C4D9DCF0CC9EE6F0031092D /* UMenuButton.pas */,
+ 2C4D9DD00CC9EE6F0031092D /* UMenuButtonCollection.pas */,
+ 2C4D9DD10CC9EE6F0031092D /* UMenuInteract.pas */,
+ 2C4D9DD20CC9EE6F0031092D /* UMenuSelect.pas */,
+ 2C4D9DD30CC9EE6F0031092D /* UMenuSelectSlide.pas */,
+ 2C4D9DD40CC9EE6F0031092D /* UMenuStatic.pas */,
+ 2C4D9DD50CC9EE6F0031092D /* UMenuText.pas */,
+ );
+ name = Menu;
+ sourceTree = "";
+ };
+ 2CDD8D0B0CC5539900E4169D /* UltraStarDX Resources */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "UltraStarDX Resources";
+ sourceTree = "";
+ };
+ 2CE1F4080CC3EEA400CD02E5 /* FreeImage */ = {
+ isa = PBXGroup;
+ children = (
+ 2C4D9D900CC9ED4F0031092D /* FreeBitmap.pas */,
+ 2C4D9D910CC9ED4F0031092D /* FreeImage.pas */,
+ );
+ name = FreeImage;
+ sourceTree = "";
+ };
+ 2CF54F420CDA1B0C00627463 /* Screens */ = {
+ isa = PBXGroup;
+ children = (
+ 2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */,
+ 2CF54F440CDA1B2B00627463 /* UScreenEdit.pas */,
+ 2CF54F450CDA1B2B00627463 /* UScreenEditConvert.pas */,
+ 2CF54F460CDA1B2B00627463 /* UScreenEditHeader.pas */,
+ 2CF54F470CDA1B2B00627463 /* UScreenEditSub.pas */,
+ 2CF54F480CDA1B2B00627463 /* UScreenLevel.pas */,
+ 2CF54F490CDA1B2B00627463 /* UScreenLoading.pas */,
+ 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */,
+ 2CF54F4B0CDA1B2B00627463 /* UScreenName.pas */,
+ 2CF54F4C0CDA1B2B00627463 /* UScreenOpen.pas */,
+ 2CF54F4D0CDA1B2B00627463 /* UScreenOptions.pas */,
+ 2CF54F4E0CDA1B2B00627463 /* UScreenOptionsAdvanced.pas */,
+ 2CF54F4F0CDA1B2B00627463 /* UScreenOptionsGame.pas */,
+ 2CF54F500CDA1B2B00627463 /* UScreenOptionsGraphics.pas */,
+ 2CF54F510CDA1B2B00627463 /* UScreenOptionsLyrics.pas */,
+ 2CF54F520CDA1B2B00627463 /* UScreenOptionsRecord.pas */,
+ 2CF54F530CDA1B2B00627463 /* UScreenOptionsSound.pas */,
+ 2CF54F540CDA1B2B00627463 /* UScreenOptionsThemes.pas */,
+ 2CF54F550CDA1B2B00627463 /* UScreenPartyNewRound.pas */,
+ 2CF54F560CDA1B2B00627463 /* UScreenPartyOptions.pas */,
+ 2CF54F570CDA1B2B00627463 /* UScreenPartyPlayer.pas */,
+ 2CF54F580CDA1B2B00627463 /* UScreenPartyScore.pas */,
+ 2CF54F590CDA1B2B00627463 /* UScreenPartyWin.pas */,
+ 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */,
+ 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */,
+ 2CF54F5C0CDA1B2B00627463 /* UScreenSing.pas */,
+ 2CF54F5D0CDA1B2B00627463 /* UScreenSingModi.pas */,
+ 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */,
+ 2CF54F5F0CDA1B2B00627463 /* UScreenSongJumpto.pas */,
+ 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */,
+ 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */,
+ 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */,
+ 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */,
+ 2CF54F640CDA1B2B00627463 /* UScreenWelcome.pas */,
+ );
+ name = Screens;
+ sourceTree = "";
+ };
+ 2CF5508A0CDA228800627463 /* SDK */ = {
+ isa = PBXGroup;
+ children = (
+ 2CF8E6BD0CDFA8E80053A996 /* UPartyDefs.pas */,
+ 2CDC716B0CDB9CB70018F966 /* StrUtils.pas */,
+ 2CF552110CDA3D1400627463 /* UPluginDefs.pas */,
+ 2CF5508B0CDA22B000627463 /* ModiSDK.pas */,
+ );
+ name = SDK;
+ sourceTree = "";
+ };
+ 2CF5510C0CDA28F000627463 /* Lib */ = {
+ isa = PBXGroup;
+ children = (
+ 2CAC2BF60D380B0800CA518A /* BASS */,
+ 2C5663EC0D35642E00D4FF53 /* portaudio */,
+ 2CF5529C0CDA428000627463 /* ffmpeg */,
+ 2CE1F4080CC3EEA400CD02E5 /* FreeImage */,
+ 2C4D9DEB0CC9EECC0031092D /* SDL */,
+ 2CF5510D0CDA291200627463 /* SQLite */,
+ );
+ name = Lib;
+ sourceTree = "";
+ };
+ 2CF5510D0CDA291200627463 /* SQLite */ = {
+ isa = PBXGroup;
+ children = (
+ 2CF5510E0CDA293700627463 /* SQLite3.pas */,
+ 2CF5510F0CDA293700627463 /* SQLiteTable3.pas */,
+ );
+ name = SQLite;
+ sourceTree = "";
+ };
+ 2CF5529C0CDA428000627463 /* ffmpeg */ = {
+ isa = PBXGroup;
+ children = (
+ 2CE603D90D715F2100DB0D88 /* mathematics.pas */,
+ 2CF5529E0CDA42C900627463 /* avcodec.pas */,
+ 2CF5529F0CDA42C900627463 /* avformat.pas */,
+ 2CF552A00CDA42C900627463 /* avio.pas */,
+ 2CF552A10CDA42C900627463 /* avutil.pas */,
+ 2CF552A40CDA42C900627463 /* opt.pas */,
+ 2CF552A50CDA42C900627463 /* rational.pas */,
+ );
+ name = ffmpeg;
+ sourceTree = "";
+ };
+ 2CF77DBA0CF755CA00F3B101 /* Modis */ = {
+ isa = PBXGroup;
+ children = (
+ 2C4B70220CF757A400B0F0BD /* Until5000.dpr */,
+ );
+ name = Modis;
+ sourceTree = "";
+ };
+ DD7C45450A6E72DE003FA52B /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ 2CF5510C0CDA28F000627463 /* Lib */,
+ 2CDD43820CBBE8D400F364DE /* Classes */,
+ 2CF54F420CDA1B0C00627463 /* Screens */,
+ 2CDD438D0CBBE8F700F364DE /* Menu */,
+ 2CF5508A0CDA228800627463 /* SDK */,
+ 2C4D9DF50CC9EF3A0031092D /* Wrapper */,
+ 2CF77DBA0CF755CA00F3B101 /* Modis */,
+ DDC6851B09F57195004E4BFF /* UltraStarDX.pas */,
+ 2CF551A70CDA356800627463 /* UltraStar.dpr */,
+ 2C4D9E440CC9F0ED0031092D /* switches.inc */,
+ 2C0199800D99840900974970 /* config-macosx.inc */,
+ );
+ name = Source;
+ sourceTree = "";
+ };
+ DDC6850D09F5717A004E4BFF = {
+ isa = PBXGroup;
+ children = (
+ 2CAC2BF00D380AC200CA518A /* libbass.dylib */,
+ 2CE907900D1BC8A800A1FDFF /* libavcodec.dylib */,
+ 2CE907910D1BC8A800A1FDFF /* libavformat.dylib */,
+ 2CE907920D1BC8A800A1FDFF /* libavutil.dylib */,
+ 98B8BE570B1F972400162019 /* SDL.framework */,
+ 2C4D9D980CC9EE0B0031092D /* SDL_image.framework */,
+ 2C4D9D990CC9EE0B0031092D /* SDL_ttf.framework */,
+ 2CDEA4F60CBD725B0096994C /* OpenGL.framework */,
+ 98B8BE370B1F949C00162019 /* Cocoa.framework */,
+ 98B8BE380B1F949C00162019 /* Foundation.framework */,
+ 98B8BE330B1F947800162019 /* AppKit.framework */,
+ 2C4D9D960CC9EDEB0031092D /* libfreeimage.dylib */,
+ 2CF5512C0CDA29C600627463 /* libsqlite3.dylib */,
+ DD7C45450A6E72DE003FA52B /* Source */,
+ DDC6868A09F571C2004E4BFF /* Resources */,
+ 2CDD8D0B0CC5539900E4169D /* UltraStarDX Resources */,
+ DDC6888C09F57243004E4BFF /* Products */,
+ DDC688CA09F574E9004E4BFF /* Info.plist */,
+ );
+ comments = "(note: \"Main target\" is used below to indicate the target with the same name as your project)\n\nSee the comments for the \"Main target\" under \"Targets\" for detailed information on how this project operates.\n\nIn short:\n\na) add your sources to the target called 'Put all program sources also in this target'\nb) add your sources *EXCEPT FOR INCLUDE FILES* to the Main Target\nd) add all frameworks, resources, libraries etc to the Main target\n\nIf there are errors, the \"Errors and Warnings\" smart group will probably not work properly (e.g. errors may disappear after you double click on them). To work around this Xcode bug, go to the Build Transcript by double clicking on the icon of the \"Errors and Warnings\" smart group. There you can (double) click on the errors to go to the right position in the right source file.\n\nNote that the assembly view of Xcode does not work before Xcode 2.3. And in Xcode 2.3, you will not be able to step over PowerPC Pascal function calls (this should be fixed in the next Xcode release though).";
+ sourceTree = "";
+ };
+ DDC6868A09F571C2004E4BFF /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 2C4FA2A70CDBAD1E002CC3B0 /* ustar-icon_v01.icns */,
+ DDC689B309F57C69004E4BFF /* InfoPlist.strings */,
+ DDC689B409F57C69004E4BFF /* SDLMain.nib */,
+ DDC6868B09F571C2004E4BFF /* Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "";
+ };
+ DDC6888C09F57243004E4BFF /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */,
+ DD37F2430A60255800975B2D /* libfpcrtl.a */,
+ 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 2CF77DB20CF7556C00F3B101 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 2CF77DB90CF7558B00F3B101 /* Build configuration list for PBXNativeTarget "Modi_Until5000" */;
+ buildPhases = (
+ 2CF77DB20CF7556C00F3B101 /* Headers */,
+ 2CF77DB30CF7556C00F3B101 /* Sources */,
+ 2CF77DB40CF7556C00F3B101 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Modi_Until5000;
+ productName = Lib_UltraPong;
+ productReference = 2CF77DB60CF7556C00F3B101 /* libLib_UltraPong.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ DD37F2420A60255800975B2D /* fpcrtl */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DD37F2560A60258300975B2D /* Build configuration list for PBXNativeTarget "fpcrtl" */;
+ buildPhases = (
+ DD37F2460A60257100975B2D /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = fpcrtl;
+ productName = fpcrtl;
+ productReference = DD37F2430A60255800975B2D /* libfpcrtl.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ DDC688C709F574E9004E4BFF /* UltraStarDX */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DDC688CB09F574E9004E4BFF /* Build configuration list for PBXNativeTarget "UltraStarDX" */;
+ buildPhases = (
+ DDC688C409F574E9004E4BFF /* Resources */,
+ 2CDEC44F0CC5255600FFA244 /* CopyFiles */,
+ 2CDEC4940CC5262700FFA244 /* CopyFiles */,
+ DDC6891B09F576D9004E4BFF /* ShellScript */,
+ DDC688C509F574E9004E4BFF /* Sources */,
+ DDC688C609F574E9004E4BFF /* Frameworks */,
+ DDC6890909F5761D004E4BFF /* Rez */,
+ 2CDD8E450CC554A000E4169D /* ShellScript */,
+ );
+ buildRules = (
+ DD7C45710A6E7E36003FA52B /* PBXBuildRule */,
+ DDC6891509F57648004E4BFF /* PBXBuildRule */,
+ );
+ comments = "This is the main target that does the actual compilation work. Because of several Xcode bugs and holes in its support for third party compilers, the structure is quite convoluted. There are three targets, but you only have to care about the first two:\n\na) This target (make sure this target is set as the \"Active Target\"!)\n\nThis target does the assembling and linking. It is dependent on the three other targets, so the scripts for those targets are run first. Next, it runs a script which compiles the main program and units (using the previously gathered information) and generate the assembler code. Then its \"Compile Sources\" phase will assemble the code, because if we directly generate the object files then Xcode will not perform any linking.\n\nb) The target called 'Put all program sources also in this target'\n\nAs the name says, you should add your sources to that target. The \"compilation rule\" for the Pascal files in that target will add those source files to a list of files to be compiled.\n\nc) The target called 'fpcrtl'\n\nThis target creates a static library of the FPC run time library. You should not have to change this target (you cannot add sources to it either)\n\n\nThe standard Xcode process is used to link in any necessary frameworks, libraries and resources. Therefore these frameworks, libraries and resources can be added to the project and this (the main) target like in any other Xcode project.\n";
+ dependencies = (
+ DDC688EE09F57578004E4BFF /* PBXTargetDependency */,
+ DD37F25E0A60268D00975B2D /* PBXTargetDependency */,
+ );
+ name = UltraStarDX;
+ productName = "JEDI-SDLCocoa";
+ productReference = DDC688C809F574E9004E4BFF /* UltraStar Deluxe.app */;
+ productType = "com.apple.product-type.application";
+ };
+ DDC688D409F57523004E4BFF /* Put all program sources also in this target */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DDC688DC09F57542004E4BFF /* Build configuration list for PBXNativeTarget "Put all program sources also in this target" */;
+ buildPhases = (
+ DD37F2350A60250900975B2D /* ShellScript */,
+ DDC688D209F57523004E4BFF /* Sources */,
+ );
+ buildRules = (
+ DD7C44CD0A6E5050003FA52B /* PBXBuildRule */,
+ DDC688F309F57599004E4BFF /* PBXBuildRule */,
+ );
+ comments = "See the comments for the target called the same as your project for details.";
+ dependencies = (
+ );
+ name = "Put all program sources also in this target";
+ productName = "Put unit sources in the 'Compile Sources' phase of this target";
+ productType = "com.apple.product-type.objfile";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ DDC6850F09F5717A004E4BFF /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = DDC6851009F5717A004E4BFF /* Build configuration list for PBXProject "UltraStarDX" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 0;
+ mainGroup = DDC6850D09F5717A004E4BFF;
+ productRefGroup = DDC6888C09F57243004E4BFF /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ DDC688C709F574E9004E4BFF /* UltraStarDX */,
+ DDC688D409F57523004E4BFF /* Put all program sources also in this target */,
+ DD37F2420A60255800975B2D /* fpcrtl */,
+ 2CF77DB50CF7556C00F3B101 /* Modi_Until5000 */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ DDC688C409F574E9004E4BFF /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DDC689B509F57C69004E4BFF /* InfoPlist.strings in Resources */,
+ DDC689B609F57C69004E4BFF /* SDLMain.nib in Resources */,
+ 2C4FA2A80CDBAD1E002CC3B0 /* ustar-icon_v01.icns in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+ DDC6890909F5761D004E4BFF /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 2CDD8E450CC554A000E4169D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\nUS_RESOURCES_SOURCE_DIR=UltraStarResources\nUS_RESOURCES_DEST_DIR=\"$CONFIGURATION_BUILD_DIR\"/\"$PRODUCT_NAME\".app/Contents\n\n#cp -Rf $US_RESOURCES_SOURCE_DIR $US_RESOURCES_DEST_DIR";
+ };
+ DD37F2350A60250900975B2D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ "$(PROJECT_TEMP_DIR)/cleanscriptrun",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# hack to workaround Xcode bug that $PROJECT_TEMP_DIR isn't cleaned when you clean,\n# and that scripts aren't run when you clean a project\n\nmkdir -p \"$PROJECT_TEMP_DIR\"\n\n# when the \"scripts not run when cleaning\" bug is fixed, this doesn't have be run\n# when cleaning\n\nif [ x\"$ACTION\" = \"xbuild\" ]; then\n # remove unit path and source file cache\n cd \"$PROJECT_TEMP_DIR\"\n rm -f mainfile scriptrun unitpaths files_to_compile > /dev/null 2>&1\nfi\n\n# simple so that the script isn't run every time you compile\ntouch \"$PROJECT_TEMP_DIR\"/cleanscriptrun";
+ };
+ DD37F2460A60257100975B2D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ "$(TARGET_BUILD_DIR)/libfpcrtl.a",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# if you activate this to see what the script does, Xcode will take a *VERY LONG* time to process the output of the \"ar\" command line\n# set -vx\n\n\n# put the entire RTL in one static library so we can link it easily (without automatically linking all object files)\n\nif [ x\"$ACTION\" = \"xbuild\" ]; then\n \n rm -f \"$PROJECT_TEMP_DIR\"/rtllibs\n for arch in $ARCHS\n do\n # get the correct compiler name\n case $arch in\n i386)\n FPC_ARCH=386\n RTL_ARCH=i386\n ;;\n ppc)\n FPC_ARCH=ppc\n RTL_ARCH=powerpc\n ;;\n * )\n echo warning: Unsupported target architecture ${arch}, skipping...\n continue\n ;;\n esac\n\n FPC_VERSION=`/usr/local/bin/ppc${FPC_ARCH} -iV`\n if [ $? != 0 ]; then\n echo \"error: Cannot find the FPC binary for $RTL_ARCH (/usr/local/bin/ppc${FPC_ARCH}). Check if you have installed FPC for this architecture.\"\n exit 1\n fi\n MY_OUTPUT_FILE=\"$PROJECT_TEMP_DIR\"/libfpcrtl-${FPC_ARCH}.a\n ar -ru \"$MY_OUTPUT_FILE\" `ls \"$FPC_RTL_UNITS_BASE\"/\"$FPC_VERSION\"/units/${RTL_ARCH}-darwin/*/*.o | grep -v 'darwin/fv/'`\n if [ $? != 0 ]; then\n echo \"error: Problem creating static library for FPC Run Time Library. Check the FPC_RTL_UNITS_BASE setting in the global project configuration.\"\n exit 1\n fi\n echo -n \" \"\\\"\"$MY_OUTPUT_FILE\"\\\" >> \"$PROJECT_TEMP_DIR\"/rtllibs\n done\n /bin/sh -c \"lipo -create `cat \\\"$PROJECT_TEMP_DIR\\\"/rtllibs` -output \\\"$TARGET_BUILD_DIR\\\"/libfpcrtl.a\"\n ranlib \"$TARGET_BUILD_DIR\"/libfpcrtl.a > /dev/null 2>&1\n # delete working files\n rm -f `cat \"$PROJECT_TEMP_DIR\"/rtllibs`\n rm -f \"$PROJECT_TEMP_DIR\"/rtllibs\nfi\n";
+ };
+ DDC6891B09F576D9004E4BFF /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(PROJECT_TEMP_DIR)/files_to_compile",
+ );
+ outputPaths = (
+ "$(PROJECT_TEMP_DIR)/scriptrun",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# set -vx\n\nif [ x\"$ACTION\" = \"xclean\" ]; then\n exit 0\nfi\n\nfunction make_conditional() {\n for arch in $ARCHS\n do\n for file in \"$PROJECT_DERIVED_FILE_DIR\"/\"$arch\"/*.s\n do\n DEST_FILE=\"$PROJECT_DERIVED_FILE_DIR\"/`basename \"$file\"`\n echo \"#ifdef __${arch}__\" >> /\"$DEST_FILE\"\n cat \"$file\" >> \"$DEST_FILE\"\n echo \"#endif\" >> \"$DEST_FILE\"\n done\n done\n}\n\n\nUNIT_PATHS_FILE=\"$PROJECT_TEMP_DIR\"/unitpaths\n\n# remove duplicate unit search paths\nif test -f \"$UNIT_PATHS_FILE\"; then\n sort -u < \"$UNIT_PATHS_FILE\" > \"$UNIT_PATHS_FILE\".tmp\n mv \"$UNIT_PATHS_FILE\".tmp \"$UNIT_PATHS_FILE\"\nelse\n touch \"$UNIT_PATHS_FILE\"\nfi\n\n# Make sure there are some files to compile\nif test ! -f \"$PROJECT_TEMP_DIR\"/files_to_compile; then\n echo error: Add your main program and its units to the \\\"Put all program sources also in this target\\\" target\n exit 1\nfi\n\n\n# support for previous Xcode naming scheme\nif [ \"$BUILD_STYLE\" = Development ]\nthen\n BUILD_STYLE=Debug\nfi\n\nif [ \"$BUILD_STYLE\" = Deployment ]\nthen\n BUILD_STYLE=Release\nfi\n\n# keep track of whether we compiled the main program so that once we did, we can stop\nMAIN_PROGRAM_COMPILED=0\n\n# don't skip the first file, since it may be the main program.\nFIRST_FILE=1\n\nFILES_TO_SKIP=\n\nrm \"$PROJECT_DERIVED_FILE_DIR\"/*.s >/dev/null 2>&1\n\n\nwhile read INPUT_FILE_SUFFIX INPUT_FILE_PATH\ndo\n # skip include files (crude, may miss some)\n if ! egrep -qi 'end\\.' \"$INPUT_FILE_PATH\" >/dev/null 2>&1; then\n FIRST_FILE=0\n echo warning: Skipping compilation of \\\"$INPUT_FILE_PATH\\\", seems to be an include file or not a Pascal file\n FILES_TO_SKIP=`echo -e \"$INPUT_FILE_PATH\"'\\n'\"$FILES_TO_SKIP\"`\n continue\n fi\n\n for variant in $BUILD_VARIANTS\n do\n for arch in $ARCHS\n do\n # get the name of the objects file dir\n####\n #FULL_OBJECT_FILES_DIR=\"$OBJECT_FILE_DIR\"-\"$variant\"/\"$arch\"\n FULL_OBJECT_FILES_DIR=\"$PROJECT_DERIVED_FILE_DIR\"/\"$arch\"\n####\n\n # create the necessary directories (not done by Xcode because we only specify a fake output file)\n mkdir -p \"$PROJECT_TEMP_DIR\" \"$FULL_OBJECT_FILES_DIR\"\n \n # if the file was already compiled (because an earlier compiled unit depended on it), skip it\n if test \"$FULL_OBJECT_FILES_DIR\"/`basename \"$INPUT_FILE_PATH\" $INPUT_FILE_SUFFIX`.o -nt \"$INPUT_FILE_PATH\" -a $FIRST_FILE -ne 1 ; then\n continue 3\n fi\n \n # get the correct compiler name\n if [ \"$arch\" = \"i386\" ]\n then\n FPCARCH=386\n RTLARCH=i386\n else\n FPCARCH=ppc\n RTLARCH=powerpc\n fi\n\n # check if the compiler exists\n if ! test -f /usr/local/bin/ppc${FPCARCH}\n then\n echo \"error: FPC for $arch is not installed on this machine. You can probably solve this problem by setting the architectures to build for to your native target only and rebuilding.\"\n exit 2\n fi\n \n # go into the object files dir so we can use short paths\n cd \"$FULL_OBJECT_FILES_DIR\"\n \n # actually compile (but do not assemble nor link)\n echo -n /usr/local/bin/ppc${FPCARCH} \\\"$INPUT_FILE_PATH\\\" $FPC_SPECIFIC_OPTIONS $FPC_COMMON_OPTIONS -Tdarwin -a -s -FE. -vbr $FPC_OVERRIDE_OPTIONS > docompile.sh\n\n # add unit paths\n while read unitsearchpath\n do\n echo -n \" \" $unitsearchpath >> docompile.sh\n done < \"$UNIT_PATHS_FILE\"\n \n echo ' > \"$PROJECT_TEMP_DIR\"/compiler_output 2>&1' >> docompile.sh\n echo 'compres=$?' >> docompile.sh\n echo 'sed -e \"s/\\([^:]*\\):\\([^:]*\\):\\([^:]*\\):\\([^:]*\\):\\(.*\\)/\\1:\\2:\\3:column \\4 -\\5/\" < \"$PROJECT_TEMP_DIR\"/compiler_output' >> docompile.sh\n echo 'exit $compres' >> docompile.sh\n /bin/sh ./docompile.sh\n \n # Compilation successful?\n if [ $? == 0 ]; then\n \n # if it was a unit, continue with the next file (no need to compile all its variants and archs, that\n # will be done when compiling the main program)\n if test ! -f ./link.res; then\n continue 3\n fi\n \n echo Main file found!\n\n # this is the main program -> next time only compile this file\n # (if units are modified, they will be added after this file, but that doesn't matter\n echo \"$INPUT_FILE_SUFFIX\" \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/files_to_compile\n \n # record that the main program was compiled, so we don't have to compile any more units\n MAIN_PROGRAM_COMPILED=1\n \n # delete leftovers\n rm -f ppas.sh link.res\n \n # log the name of the input file so it can be touched if necessary for recompilation\n echo -n \"$INPUT_FILE_PATH\" > \"$PROJECT_TEMP_DIR\"/mainfile\n \n else\n exit 2\n fi\n done\n done\n\n # if the main program was compiled, we can stop\n if test $MAIN_PROGRAM_COMPILED -ne 0; then\n make_conditional\n touch \"$PROJECT_TEMP_DIR\"/scriptrun\n exit 0\n fi\n FIRST_FILE=0\n\ndone < \"$PROJECT_TEMP_DIR\"/files_to_compile\n\necho \"warning: It seems your project only contains units and no main program\"\ngrep -Fv \"$FILES_TO_SKIP\" < \"$PROJECT_TEMP_DIR\"/files_to_compile > \"$PROJECT_TEMP_DIR\"/files_to_compile.tmp\nsort -u < \"$PROJECT_TEMP_DIR\"/files_to_compile.tmp > \"$PROJECT_TEMP_DIR\"/files_to_compile\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2CF77DB30CF7556C00F3B101 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2C4B70240CF7584500B0F0BD /* ModiSDK.pas in Sources */,
+ 2C4B70230CF7581000B0F0BD /* Until5000.dpr in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DDC688C509F574E9004E4BFF /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2CDD4BE20CB947BE00549FAC /* UltraStarDX.pas in Sources */,
+ 2CDD4BE00CB947B100549FAC /* sdl.pas in Sources */,
+ 2C4D9C8F0CC9EC8C0031092D /* TextGL.pas in Sources */,
+ 2C4D9C920CC9EC8C0031092D /* UCatCovers.pas in Sources */,
+ 2C4D9C930CC9EC8C0031092D /* UCommandLine.pas in Sources */,
+ 2C4D9C940CC9EC8C0031092D /* UCommon.pas in Sources */,
+ 2C4D9C950CC9EC8C0031092D /* UCore.pas in Sources */,
+ 2C4D9C960CC9EC8C0031092D /* UCoreModule.pas in Sources */,
+ 2C4D9C970CC9EC8C0031092D /* UCovers.pas in Sources */,
+ 2C4D9C980CC9EC8C0031092D /* UDataBase.pas in Sources */,
+ 2C4D9C990CC9EC8C0031092D /* UDLLManager.pas in Sources */,
+ 2C4D9C9A0CC9EC8C0031092D /* UDraw.pas in Sources */,
+ 2C4D9C9B0CC9EC8C0031092D /* UFiles.pas in Sources */,
+ 2C4D9C9C0CC9EC8C0031092D /* UGraphic.pas in Sources */,
+ 2C4D9C9D0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */,
+ 2C4D9C9E0CC9EC8C0031092D /* UHooks.pas in Sources */,
+ 2C4D9C9F0CC9EC8C0031092D /* UIni.pas in Sources */,
+ 2C4D9CA00CC9EC8C0031092D /* UJoystick.pas in Sources */,
+ 2C4D9CA10CC9EC8C0031092D /* ULanguage.pas in Sources */,
+ 2C4D9CA30CC9EC8C0031092D /* ULCD.pas in Sources */,
+ 2C4D9CA40CC9EC8C0031092D /* ULight.pas in Sources */,
+ 2C4D9CA50CC9EC8C0031092D /* ULog.pas in Sources */,
+ 2C4D9CA60CC9EC8C0031092D /* ULyrics_bak.pas in Sources */,
+ 2C4D9CA70CC9EC8C0031092D /* ULyrics.pas in Sources */,
+ 2C4D9CA80CC9EC8C0031092D /* UMain.pas in Sources */,
+ 2C4D9CA90CC9EC8C0031092D /* UMedia_dummy.pas in Sources */,
+ 2C4D9CAA0CC9EC8C0031092D /* UModules.pas in Sources */,
+ 2C4D9CAB0CC9EC8C0031092D /* UMusic.pas in Sources */,
+ 2C4D9CAC0CC9EC8C0031092D /* UParty.pas in Sources */,
+ 2C4D9CAD0CC9EC8C0031092D /* UPlaylist.pas in Sources */,
+ 2C4D9CAF0CC9EC8C0031092D /* UPluginInterface.pas in Sources */,
+ 2C4D9CB00CC9EC8C0031092D /* uPluginLoader.pas in Sources */,
+ 2C4D9CB10CC9EC8C0031092D /* URecord.pas in Sources */,
+ 2C4D9CB20CC9EC8C0031092D /* UServices.pas in Sources */,
+ 2C4D9CB30CC9EC8C0031092D /* USingNotes.pas in Sources */,
+ 2C4D9CB40CC9EC8C0031092D /* USingScores.pas in Sources */,
+ 2C4D9CB50CC9EC8C0031092D /* USkins.pas in Sources */,
+ 2C4D9CB60CC9EC8C0031092D /* USongs.pas in Sources */,
+ 2C4D9CB70CC9EC8C0031092D /* UTextClasses.pas in Sources */,
+ 2C4D9CB80CC9EC8C0031092D /* UTexture.pas in Sources */,
+ 2C4D9CB90CC9EC8C0031092D /* UThemes.pas in Sources */,
+ 2C4D9CBA0CC9EC8C0031092D /* UTime.pas in Sources */,
+ 2C4D9CBB0CC9EC8C0031092D /* UVideo.pas in Sources */,
+ 2C4D9D920CC9ED4F0031092D /* FreeBitmap.pas in Sources */,
+ 2C4D9D930CC9ED4F0031092D /* FreeImage.pas in Sources */,
+ 2C4D9DD60CC9EE6F0031092D /* UDisplay.pas in Sources */,
+ 2C4D9DD70CC9EE6F0031092D /* UDrawTexture.pas in Sources */,
+ 2C4D9DD80CC9EE6F0031092D /* UMenu.pas in Sources */,
+ 2C4D9DD90CC9EE6F0031092D /* UMenuButton.pas in Sources */,
+ 2C4D9DDA0CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */,
+ 2C4D9DDB0CC9EE6F0031092D /* UMenuInteract.pas in Sources */,
+ 2C4D9DDC0CC9EE6F0031092D /* UMenuSelect.pas in Sources */,
+ 2C4D9DDD0CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */,
+ 2C4D9DDE0CC9EE6F0031092D /* UMenuStatic.pas in Sources */,
+ 2C4D9DDF0CC9EE6F0031092D /* UMenuText.pas in Sources */,
+ 2C4D9DED0CC9EF0A0031092D /* sdl_image.pas in Sources */,
+ 2C4D9DF10CC9EF210031092D /* sdl_ttf.pas in Sources */,
+ 2C4D9E100CC9EF840031092D /* OpenGL12.pas in Sources */,
+ 2C4D9E150CC9EF840031092D /* Windows.pas in Sources */,
+ 2C4D9E450CC9F0ED0031092D /* switches.inc in Sources */,
+ 2CF54F650CDA1B2B00627463 /* UScreenCredits.pas in Sources */,
+ 2CF54F660CDA1B2B00627463 /* UScreenEdit.pas in Sources */,
+ 2CF54F670CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */,
+ 2CF54F680CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */,
+ 2CF54F690CDA1B2B00627463 /* UScreenEditSub.pas in Sources */,
+ 2CF54F6A0CDA1B2B00627463 /* UScreenLevel.pas in Sources */,
+ 2CF54F6B0CDA1B2B00627463 /* UScreenLoading.pas in Sources */,
+ 2CF54F6C0CDA1B2B00627463 /* UScreenMain.pas in Sources */,
+ 2CF54F6D0CDA1B2B00627463 /* UScreenName.pas in Sources */,
+ 2CF54F6E0CDA1B2B00627463 /* UScreenOpen.pas in Sources */,
+ 2CF54F6F0CDA1B2B00627463 /* UScreenOptions.pas in Sources */,
+ 2CF54F700CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */,
+ 2CF54F710CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */,
+ 2CF54F720CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */,
+ 2CF54F730CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */,
+ 2CF54F740CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */,
+ 2CF54F750CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */,
+ 2CF54F760CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */,
+ 2CF54F770CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */,
+ 2CF54F780CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */,
+ 2CF54F790CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */,
+ 2CF54F7A0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */,
+ 2CF54F7B0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */,
+ 2CF54F7C0CDA1B2B00627463 /* UScreenPopup.pas in Sources */,
+ 2CF54F7D0CDA1B2B00627463 /* UScreenScore.pas in Sources */,
+ 2CF54F7E0CDA1B2B00627463 /* UScreenSing.pas in Sources */,
+ 2CF54F7F0CDA1B2B00627463 /* UScreenSingModi.pas in Sources */,
+ 2CF54F800CDA1B2B00627463 /* UScreenSong.pas in Sources */,
+ 2CF54F810CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */,
+ 2CF54F820CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */,
+ 2CF54F830CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */,
+ 2CF54F840CDA1B2B00627463 /* UScreenStatMain.pas in Sources */,
+ 2CF54F850CDA1B2B00627463 /* UScreenTop5.pas in Sources */,
+ 2CF54F860CDA1B2B00627463 /* UScreenWelcome.pas in Sources */,
+ 2CF5508C0CDA22B000627463 /* ModiSDK.pas in Sources */,
+ 2CF551100CDA293700627463 /* SQLite3.pas in Sources */,
+ 2CF551110CDA293700627463 /* SQLiteTable3.pas in Sources */,
+ 2CF552140CDA3D1400627463 /* UPluginDefs.pas in Sources */,
+ 2CF552B00CDA42C900627463 /* avcodec.pas in Sources */,
+ 2CF552B10CDA42C900627463 /* avformat.pas in Sources */,
+ 2CF552B20CDA42C900627463 /* avio.pas in Sources */,
+ 2CF552B30CDA42C900627463 /* avutil.pas in Sources */,
+ 2CF552B60CDA42C900627463 /* opt.pas in Sources */,
+ 2CF552B70CDA42C900627463 /* rational.pas in Sources */,
+ 2CF553080CDA51B500627463 /* sdlutils.pas in Sources */,
+ 2CDC716C0CDB9CB70018F966 /* StrUtils.pas in Sources */,
+ 2CF3EF220CDE13A0004F5956 /* Messages.pas in Sources */,
+ 2CF3EF270CDE13BA004F5956 /* MacResources.pas in Sources */,
+ 2CF8E6BE0CDFA8E80053A996 /* UPartyDefs.pas in Sources */,
+ 2CEA2AE00CE385190097A5FF /* Graphics.pas in Sources */,
+ 2CEA2AE10CE385190097A5FF /* JPEG.pas in Sources */,
+ 2CEA2AF10CE3868E0097A5FF /* PseudoThread.pas in Sources */,
+ 2C89372A0CE393FB005D8A87 /* UPlatform.pas in Sources */,
+ 2C8937340CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */,
+ 2C5663EF0D35645700D4FF53 /* portaudio.pas in Sources */,
+ 2C56642C0D35683200D4FF53 /* SDLMain.m in Sources */,
+ 2CAC2BE20D3809F500CA518A /* UAudioInput_Bass.pas in Sources */,
+ 2CAC2BE40D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */,
+ 2CAC2BF80D380B1B00CA518A /* Bass.pas in Sources */,
+ 2CB9E87E0D43B78400214DFA /* USong.pas in Sources */,
+ 2CE603DA0D715F2100DB0D88 /* mathematics.pas in Sources */,
+ 2CE603DE0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */,
+ 2CE603E20D715F8600DB0D88 /* UConfig.pas in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DDC688D209F57523004E4BFF /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2CDD4BDE0CB947A400549FAC /* sdl.pas in Sources */,
+ DD37F23D0A60252800975B2D /* UltraStarDX.pas in Sources */,
+ 2C4D9CBC0CC9EC8C0031092D /* TextGL.pas in Sources */,
+ 2C4D9CBF0CC9EC8C0031092D /* UCatCovers.pas in Sources */,
+ 2C4D9CC00CC9EC8C0031092D /* UCommandLine.pas in Sources */,
+ 2C4D9CC10CC9EC8C0031092D /* UCommon.pas in Sources */,
+ 2C4D9CC20CC9EC8C0031092D /* UCore.pas in Sources */,
+ 2C4D9CC30CC9EC8C0031092D /* UCoreModule.pas in Sources */,
+ 2C4D9CC40CC9EC8C0031092D /* UCovers.pas in Sources */,
+ 2C4D9CC50CC9EC8C0031092D /* UDataBase.pas in Sources */,
+ 2C4D9CC60CC9EC8C0031092D /* UDLLManager.pas in Sources */,
+ 2C4D9CC70CC9EC8C0031092D /* UDraw.pas in Sources */,
+ 2C4D9CC80CC9EC8C0031092D /* UFiles.pas in Sources */,
+ 2C4D9CC90CC9EC8C0031092D /* UGraphic.pas in Sources */,
+ 2C4D9CCA0CC9EC8C0031092D /* UGraphicClasses.pas in Sources */,
+ 2C4D9CCB0CC9EC8C0031092D /* UHooks.pas in Sources */,
+ 2C4D9CCC0CC9EC8C0031092D /* UIni.pas in Sources */,
+ 2C4D9CCD0CC9EC8C0031092D /* UJoystick.pas in Sources */,
+ 2C4D9CCE0CC9EC8C0031092D /* ULanguage.pas in Sources */,
+ 2C4D9CD00CC9EC8C0031092D /* ULCD.pas in Sources */,
+ 2C4D9CD10CC9EC8C0031092D /* ULight.pas in Sources */,
+ 2C4D9CD20CC9EC8C0031092D /* ULog.pas in Sources */,
+ 2C4D9CD30CC9EC8C0031092D /* ULyrics_bak.pas in Sources */,
+ 2C4D9CD40CC9EC8C0031092D /* ULyrics.pas in Sources */,
+ 2C4D9CD50CC9EC8C0031092D /* UMain.pas in Sources */,
+ 2C4D9CD60CC9EC8C0031092D /* UMedia_dummy.pas in Sources */,
+ 2C4D9CD70CC9EC8C0031092D /* UModules.pas in Sources */,
+ 2C4D9CD80CC9EC8C0031092D /* UMusic.pas in Sources */,
+ 2C4D9CD90CC9EC8C0031092D /* UParty.pas in Sources */,
+ 2C4D9CDA0CC9EC8C0031092D /* UPlaylist.pas in Sources */,
+ 2C4D9CDC0CC9EC8C0031092D /* UPluginInterface.pas in Sources */,
+ 2C4D9CDD0CC9EC8C0031092D /* uPluginLoader.pas in Sources */,
+ 2C4D9CDE0CC9EC8C0031092D /* URecord.pas in Sources */,
+ 2C4D9CDF0CC9EC8C0031092D /* UServices.pas in Sources */,
+ 2C4D9CE00CC9EC8C0031092D /* USingNotes.pas in Sources */,
+ 2C4D9CE10CC9EC8C0031092D /* USingScores.pas in Sources */,
+ 2C4D9CE20CC9EC8C0031092D /* USkins.pas in Sources */,
+ 2C4D9CE30CC9EC8C0031092D /* USongs.pas in Sources */,
+ 2C4D9CE40CC9EC8C0031092D /* UTextClasses.pas in Sources */,
+ 2C4D9CE50CC9EC8C0031092D /* UTexture.pas in Sources */,
+ 2C4D9CE60CC9EC8C0031092D /* UThemes.pas in Sources */,
+ 2C4D9CE70CC9EC8C0031092D /* UTime.pas in Sources */,
+ 2C4D9CE80CC9EC8C0031092D /* UVideo.pas in Sources */,
+ 2C4D9D940CC9ED4F0031092D /* FreeBitmap.pas in Sources */,
+ 2C4D9D950CC9ED4F0031092D /* FreeImage.pas in Sources */,
+ 2C4D9DE00CC9EE6F0031092D /* UDisplay.pas in Sources */,
+ 2C4D9DE10CC9EE6F0031092D /* UDrawTexture.pas in Sources */,
+ 2C4D9DE20CC9EE6F0031092D /* UMenu.pas in Sources */,
+ 2C4D9DE30CC9EE6F0031092D /* UMenuButton.pas in Sources */,
+ 2C4D9DE40CC9EE6F0031092D /* UMenuButtonCollection.pas in Sources */,
+ 2C4D9DE50CC9EE6F0031092D /* UMenuInteract.pas in Sources */,
+ 2C4D9DE60CC9EE6F0031092D /* UMenuSelect.pas in Sources */,
+ 2C4D9DE70CC9EE6F0031092D /* UMenuSelectSlide.pas in Sources */,
+ 2C4D9DE80CC9EE6F0031092D /* UMenuStatic.pas in Sources */,
+ 2C4D9DE90CC9EE6F0031092D /* UMenuText.pas in Sources */,
+ 2C4D9DEE0CC9EF0A0031092D /* sdl_image.pas in Sources */,
+ 2C4D9DF30CC9EF210031092D /* sdl_ttf.pas in Sources */,
+ 2C4D9E1C0CC9EF840031092D /* OpenGL12.pas in Sources */,
+ 2C4D9E210CC9EF840031092D /* Windows.pas in Sources */,
+ 2C4D9E460CC9F0ED0031092D /* switches.inc in Sources */,
+ 2CF54F870CDA1B2B00627463 /* UScreenCredits.pas in Sources */,
+ 2CF54F880CDA1B2B00627463 /* UScreenEdit.pas in Sources */,
+ 2CF54F890CDA1B2B00627463 /* UScreenEditConvert.pas in Sources */,
+ 2CF54F8A0CDA1B2B00627463 /* UScreenEditHeader.pas in Sources */,
+ 2CF54F8B0CDA1B2B00627463 /* UScreenEditSub.pas in Sources */,
+ 2CF54F8C0CDA1B2B00627463 /* UScreenLevel.pas in Sources */,
+ 2CF54F8D0CDA1B2B00627463 /* UScreenLoading.pas in Sources */,
+ 2CF54F8E0CDA1B2B00627463 /* UScreenMain.pas in Sources */,
+ 2CF54F8F0CDA1B2B00627463 /* UScreenName.pas in Sources */,
+ 2CF54F900CDA1B2B00627463 /* UScreenOpen.pas in Sources */,
+ 2CF54F910CDA1B2B00627463 /* UScreenOptions.pas in Sources */,
+ 2CF54F920CDA1B2B00627463 /* UScreenOptionsAdvanced.pas in Sources */,
+ 2CF54F930CDA1B2B00627463 /* UScreenOptionsGame.pas in Sources */,
+ 2CF54F940CDA1B2B00627463 /* UScreenOptionsGraphics.pas in Sources */,
+ 2CF54F950CDA1B2B00627463 /* UScreenOptionsLyrics.pas in Sources */,
+ 2CF54F960CDA1B2B00627463 /* UScreenOptionsRecord.pas in Sources */,
+ 2CF54F970CDA1B2B00627463 /* UScreenOptionsSound.pas in Sources */,
+ 2CF54F980CDA1B2B00627463 /* UScreenOptionsThemes.pas in Sources */,
+ 2CF54F990CDA1B2B00627463 /* UScreenPartyNewRound.pas in Sources */,
+ 2CF54F9A0CDA1B2B00627463 /* UScreenPartyOptions.pas in Sources */,
+ 2CF54F9B0CDA1B2B00627463 /* UScreenPartyPlayer.pas in Sources */,
+ 2CF54F9C0CDA1B2B00627463 /* UScreenPartyScore.pas in Sources */,
+ 2CF54F9D0CDA1B2B00627463 /* UScreenPartyWin.pas in Sources */,
+ 2CF54F9E0CDA1B2B00627463 /* UScreenPopup.pas in Sources */,
+ 2CF54F9F0CDA1B2B00627463 /* UScreenScore.pas in Sources */,
+ 2CF54FA00CDA1B2B00627463 /* UScreenSing.pas in Sources */,
+ 2CF54FA10CDA1B2B00627463 /* UScreenSingModi.pas in Sources */,
+ 2CF54FA20CDA1B2B00627463 /* UScreenSong.pas in Sources */,
+ 2CF54FA30CDA1B2B00627463 /* UScreenSongJumpto.pas in Sources */,
+ 2CF54FA40CDA1B2B00627463 /* UScreenSongMenu.pas in Sources */,
+ 2CF54FA50CDA1B2B00627463 /* UScreenStatDetail.pas in Sources */,
+ 2CF54FA60CDA1B2B00627463 /* UScreenStatMain.pas in Sources */,
+ 2CF54FA70CDA1B2B00627463 /* UScreenTop5.pas in Sources */,
+ 2CF54FA80CDA1B2B00627463 /* UScreenWelcome.pas in Sources */,
+ 2CF5508D0CDA22B000627463 /* ModiSDK.pas in Sources */,
+ 2CF551120CDA293700627463 /* SQLite3.pas in Sources */,
+ 2CF551130CDA293700627463 /* SQLiteTable3.pas in Sources */,
+ 2CF552170CDA3D1400627463 /* UPluginDefs.pas in Sources */,
+ 2CF552A70CDA42C900627463 /* avcodec.pas in Sources */,
+ 2CF552A80CDA42C900627463 /* avformat.pas in Sources */,
+ 2CF552A90CDA42C900627463 /* avio.pas in Sources */,
+ 2CF552AA0CDA42C900627463 /* avutil.pas in Sources */,
+ 2CF552AD0CDA42C900627463 /* opt.pas in Sources */,
+ 2CF552AE0CDA42C900627463 /* rational.pas in Sources */,
+ 2CF553090CDA51B500627463 /* sdlutils.pas in Sources */,
+ 2CDC716D0CDB9CB70018F966 /* StrUtils.pas in Sources */,
+ 2CF3EF230CDE13A0004F5956 /* Messages.pas in Sources */,
+ 2CF3EF280CDE13BA004F5956 /* MacResources.pas in Sources */,
+ 2CF8E6BF0CDFA8E80053A996 /* UPartyDefs.pas in Sources */,
+ 2CEA2AE20CE385190097A5FF /* Graphics.pas in Sources */,
+ 2CEA2AE30CE385190097A5FF /* JPEG.pas in Sources */,
+ 2CEA2AF20CE3868E0097A5FF /* PseudoThread.pas in Sources */,
+ 2C89372B0CE393FB005D8A87 /* UPlatform.pas in Sources */,
+ 2C8937370CE395CE005D8A87 /* UPlatformMacOSX.pas in Sources */,
+ 2C5663F00D35645700D4FF53 /* portaudio.pas in Sources */,
+ 2CAC2BE70D3809F500CA518A /* UAudioInput_Bass.pas in Sources */,
+ 2CAC2BE90D3809F500CA518A /* UAudioPlayback_Bass.pas in Sources */,
+ 2CAC2BF90D380B1B00CA518A /* Bass.pas in Sources */,
+ 2CB9E87F0D43B78400214DFA /* USong.pas in Sources */,
+ 2CE603DB0D715F2100DB0D88 /* mathematics.pas in Sources */,
+ 2CE603DF0D715F6700DB0D88 /* UAudioCore_Bass.pas in Sources */,
+ 2CE603E30D715F8600DB0D88 /* UConfig.pas in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ DD37F25E0A60268D00975B2D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DD37F2420A60255800975B2D /* fpcrtl */;
+ targetProxy = DD37F25D0A60268D00975B2D /* PBXContainerItemProxy */;
+ };
+ DDC688EE09F57578004E4BFF /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DDC688D409F57523004E4BFF /* Put all program sources also in this target */;
+ targetProxy = DDC688ED09F57578004E4BFF /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 2CF77DB70CF7556D00F3B101 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ EXECUTABLE_PREFIX = lib;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/local/lib;
+ LD_DYLIB_INSTALL_NAME = "@executable_path/libUntil5000.dylib";
+ PREBINDING = NO;
+ PRODUCT_NAME = Until5000;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ 2CF77DB80CF7556D00F3B101 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ EXECUTABLE_PREFIX = lib;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = /usr/local/lib;
+ PREBINDING = NO;
+ PRODUCT_NAME = Lib_UltraPong;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ DD37F2570A60258300975B2D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/local/lib;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpcrtl;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ DD37F2580A60258300975B2D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = /usr/local/lib;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpcrtl;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ DDC6851109F5717A004E4BFF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ FPC_COMMON_OPTIONS = "-Sd -XMSDL_main";
+ FPC_MAIN_FILE = "";
+ FPC_OVERRIDE_OPTIONS = "";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc/;
+ FPC_SPECIFIC_OPTIONS = "-Ci -Cr -Co -gl -O-";
+ FRAMEWORK_SEARCH_PATHS = "";
+ HEADER_SEARCH_PATHS = "";
+ LIBRARY_SEARCH_PATHS = "";
+ REZ_SEARCH_PATHS = "";
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ USER_HEADER_SEARCH_PATHS = "";
+ };
+ name = Debug;
+ };
+ DDC6851209F5717A004E4BFF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ FPC_COMMON_OPTIONS = "-Sd -XMSDL_main";
+ FPC_MAIN_FILE = "";
+ FPC_OVERRIDE_OPTIONS = "";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc/;
+ FPC_SPECIFIC_OPTIONS = "-Ci- -Cr- -Co- -O3 -Xs ";
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+ DDC688CC09F574E9004E4BFF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\"";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_4)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_5)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_6)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../lib/SQLite\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../lib/ffmpeg\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../lib/bass\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../lib/FreeImage\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../lib/ffmpeg\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../lib/bass\"";
+ LINK_WITH_STANDARD_LIBRARIES = YES;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Carbon,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = "UltraStar Deluxe";
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ DDC688CD09F574E9004E4BFF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+ );
+ FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\"";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_3)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_4)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_5)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_6)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_7)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_8)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_9)",
+ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+ );
+ LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/Bass\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/FreeImage\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/FreeImage\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../lib/bass\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../lib/FreeImage\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_7 = "\"$(SRCROOT)/../lib/SQLite\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_8 = "\"$(SRCROOT)/../lib/ffmpeg\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_9 = "\"$(SRCROOT)/../lib/ffmpeg\"";
+ LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../lib/bass\"";
+ LINK_WITH_STANDARD_LIBRARIES = YES;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Carbon,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = "UltraStar Deluxe";
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ DDC688DD09F57542004E4BFF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+ INSTALL_PATH = /usr/local/lib;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Carbon,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = "Put unit sources in the 'Compile Sources' phase of this target";
+ };
+ name = Debug;
+ };
+ DDC688DE09F57542004E4BFF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+ INSTALL_PATH = /usr/local/lib;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Carbon,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = "Put unit sources in the 'Compile Sources' phase of this target";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 2CF77DB90CF7558B00F3B101 /* Build configuration list for PBXNativeTarget "Modi_Until5000" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 2CF77DB70CF7556D00F3B101 /* Debug */,
+ 2CF77DB80CF7556D00F3B101 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ DD37F2560A60258300975B2D /* Build configuration list for PBXNativeTarget "fpcrtl" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DD37F2570A60258300975B2D /* Debug */,
+ DD37F2580A60258300975B2D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ DDC6851009F5717A004E4BFF /* Build configuration list for PBXProject "UltraStarDX" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DDC6851109F5717A004E4BFF /* Debug */,
+ DDC6851209F5717A004E4BFF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ DDC688CB09F574E9004E4BFF /* Build configuration list for PBXNativeTarget "UltraStarDX" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DDC688CC09F574E9004E4BFF /* Debug */,
+ DDC688CD09F574E9004E4BFF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ DDC688DC09F57542004E4BFF /* Build configuration list for PBXNativeTarget "Put all program sources also in this target" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DDC688DD09F57542004E4BFF /* Debug */,
+ DDC688DE09F57542004E4BFF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = DDC6850F09F5717A004E4BFF /* Project object */;
+}
diff --git a/src/MacOSX/Wrapper/MacResources.pas b/src/MacOSX/Wrapper/MacResources.pas
new file mode 100644
index 00000000..a97fb565
--- /dev/null
+++ b/src/MacOSX/Wrapper/MacResources.pas
@@ -0,0 +1,124 @@
+unit MacResources;
+
+{$I switches.inc}
+
+interface
+
+uses
+ Classes, Windows, SysUtils;
+
+type
+
+ TResourceStream = class(TFileStream)
+ private
+ public
+ constructor Create(Instance: THandle; const ResName: string; ResType: PChar);
+ end;
+
+ Function FindResource( hInstance : THandle; pcIdentifier : PChar; pcResType : PChar) : THandle;
+
+implementation
+
+Function FindResource( hInstance : THandle; pcIdentifier : PChar; pcResType : PChar) : THandle;
+begin
+ Result := 1;
+end;
+
+Function GetResourcesPath : String;
+var
+ x,
+ i : integer;
+begin
+ Result := ExtractFilePath(ParamStr(0));
+ for x := 0 to 2 do begin
+ i := Length(Result);
+ repeat
+ Delete( Result, i, 1);
+ i := Length(Result);
+ until (i = 0) or (Result[i] = '/');
+ end;
+end;
+
+{ TResourceStream }
+
+constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);
+var
+ sResNameLower : string;
+ sFileName : String;
+begin
+ sResNameLower := LowerCase(string(ResName));
+
+ if ResType = 'TEX' then begin
+ if sResNameLower = 'font' then
+ sFileName := GetResourcesPath + 'Fonts/Normal/eurostar_regular.png'
+ else if sResNameLower = 'fontb' then
+ sFileName := GetResourcesPath + 'Fonts/Bold/eurostar_regular_bold.png'
+ else if sResNameLower = 'fonto' then
+ sFileName := GetResourcesPath + 'Fonts/Outline 1/Outline 1.png'
+ else if sResNameLower = 'fonto2' then
+ sFileName := GetResourcesPath + 'Fonts/Outline 2/Outline 2.png'
+ else if sResNameLower = 'crdts_bg' then
+ sFileName := GetResourcesPath + 'Graphics/credits_v5_bg.png'
+ else if sResNameLower = 'crdts_ovl' then
+ sFileName := GetResourcesPath + 'Graphics/credits_v5_overlay.png'
+ else if sResNameLower = 'crdts_blindguard' then
+ sFileName := GetResourcesPath + 'Graphics/names_blindguard.png'
+ else if sResNameLower = 'crdts_blindy' then
+ sFileName := GetResourcesPath + 'Graphics/names_blindy.png'
+ else if sResNameLower = 'crdts_canni' then
+ sFileName := GetResourcesPath + 'Graphics/names_canni.png'
+ else if sResNameLower = 'crdts_commandio' then
+ sFileName := GetResourcesPath + 'Graphics/names_commandio.png'
+ else if sResNameLower = 'crdts_lazyjoker' then
+ sFileName := GetResourcesPath + 'Graphics/names_lazyjoker.png'
+ else if sResNameLower = 'crdts_mog' then
+ sFileName := GetResourcesPath + 'Graphics/names_mog.png'
+ else if sResNameLower = 'crdts_mota' then
+ sFileName := GetResourcesPath + 'Graphics/names_mota.png'
+ else if sResNameLower = 'crdts_skillmaster' then
+ sFileName := GetResourcesPath + 'Graphics/names_skillmaster.png'
+ else if sResNameLower = 'crdts_whiteshark' then
+ sFileName := GetResourcesPath + 'Graphics/names_whiteshark.png'
+ else if sResNameLower = 'intro_l01' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-01.png'
+ else if sResNameLower = 'intro_l02' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-02.png'
+ else if sResNameLower = 'intro_l03' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-03.png'
+ else if sResNameLower = 'intro_l04' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-04.png'
+ else if sResNameLower = 'intro_l05' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-05.png'
+ else if sResNameLower = 'intro_l06' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-06.png'
+ else if sResNameLower = 'intro_l07' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-07.png'
+ else if sResNameLower = 'intro_l08' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-08.png'
+ else if sResNameLower = 'intro_l09' then
+ sFileName := GetResourcesPath + 'Graphics/intro-l-09.png'
+ else if sResNameLower = 'outro_bg' then
+ sFileName := GetResourcesPath + 'Graphics/outro-bg.png'
+ else if sResNameLower = 'outro_esc' then
+ sFileName := GetResourcesPath + 'Graphics/outro-esc.png'
+ else if sResNameLower = 'outro_exd' then
+ sFileName := GetResourcesPath + 'Graphics/outro-exit-dark.png';
+ end
+ else if ResType = 'FNT' then begin
+ if sResNameLower = 'font' then
+ sFileName := GetResourcesPath + 'Fonts/Normal/eurostar_regular.dat'
+ else if sResNameLower = 'fontb' then
+ sFileName := GetResourcesPath + 'Fonts/Bold/eurostar_regular_bold.dat'
+ else if sResNameLower = 'fonto' then
+ sFileName := GetResourcesPath + 'Fonts/Outline 1/Outline 1.dat'
+ else if sResNameLower = 'fonto2' then
+ sFileName := GetResourcesPath + 'Fonts/Outline 2/Outline 2.dat';
+ end;
+
+ if FileExists(sFileName) then
+ inherited Create( sFileName, fmOpenReadWrite)
+ else
+ raise Exception.Create('MacResources.TResourceStream.Create: File "' + sFileName + '" not found.');
+end;
+
+end.
diff --git a/src/MacOSX/Wrapper/PseudoThread.pas b/src/MacOSX/Wrapper/PseudoThread.pas
new file mode 100644
index 00000000..16157646
--- /dev/null
+++ b/src/MacOSX/Wrapper/PseudoThread.pas
@@ -0,0 +1,48 @@
+unit PseudoThread;
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+interface
+
+type
+
+// Debugging threads with XCode doesn't seem to work.
+// We use PseudoThread in Debug mode to get proper debugging.
+TPseudoThread = class(TObject)
+ private
+ protected
+ Terminated,
+ FreeOnTerminate : Boolean;
+ procedure Execute; virtual; abstract;
+ procedure Resume;
+ procedure Suspend;
+ public
+ constructor Create(const suspended : Boolean);
+end;
+
+implementation
+
+{ TPseudoThread }
+
+constructor TPseudoThread.Create(const suspended : Boolean);
+begin
+ if not suspended then begin
+ Execute;
+ end;
+end;
+
+procedure TPseudoThread.Resume;
+begin
+ Execute;
+end;
+
+procedure TPseudoThread.Suspend;
+begin
+end;
+
+end.
+
diff --git a/src/MacOSX/Wrapper/Windows.pas b/src/MacOSX/Wrapper/Windows.pas
new file mode 100644
index 00000000..cee75591
--- /dev/null
+++ b/src/MacOSX/Wrapper/Windows.pas
@@ -0,0 +1,167 @@
+unit Windows;
+
+{$I switches.inc}
+
+interface
+
+uses Types;
+
+const
+ opengl32 = 'OpenGL';
+ MAX_PATH = 260;
+
+type
+
+ DWORD = Types.DWORD;
+ {$EXTERNALSYM DWORD}
+ BOOL = LongBool;
+ {$EXTERNALSYM BOOL}
+ PBOOL = ^BOOL;
+ {$EXTERNALSYM PBOOL}
+ PByte = Types.PByte;
+ PINT = ^Integer;
+ {$EXTERNALSYM PINT}
+ PSingle = ^Single;
+ PWORD = ^Word;
+ {$EXTERNALSYM PWORD}
+ PDWORD = ^DWORD;
+ {$EXTERNALSYM PDWORD}
+ LPDWORD = PDWORD;
+ {$EXTERNALSYM LPDWORD}
+ HDC = type LongWord;
+ {$EXTERNALSYM HDC}
+ HGLRC = type LongWord;
+ {$EXTERNALSYM HGLRC}
+ TLargeInteger = Int64;
+ HFONT = type LongWord;
+ {$EXTERNALSYM HFONT}
+ HWND = type LongWord;
+ {$EXTERNALSYM HWND}
+
+ PPaletteEntry = ^TPaletteEntry;
+ {$EXTERNALSYM tagPALETTEENTRY}
+ tagPALETTEENTRY = packed record
+ peRed: Byte;
+ peGreen: Byte;
+ peBlue: Byte;
+ peFlags: Byte;
+ end;
+ TPaletteEntry = tagPALETTEENTRY;
+ {$EXTERNALSYM PALETTEENTRY}
+ PALETTEENTRY = tagPALETTEENTRY;
+
+ PRGBQuad = ^TRGBQuad;
+ {$EXTERNALSYM tagRGBQUAD}
+ tagRGBQUAD = packed record
+ rgbBlue: Byte;
+ rgbGreen: Byte;
+ rgbRed: Byte;
+ rgbReserved: Byte;
+ end;
+ TRGBQuad = tagRGBQUAD;
+ {$EXTERNALSYM RGBQUAD}
+ RGBQUAD = tagRGBQUAD;
+
+ PBitmapInfoHeader = ^TBitmapInfoHeader;
+ {$EXTERNALSYM tagBITMAPINFOHEADER}
+ tagBITMAPINFOHEADER = packed record
+ biSize: DWORD;
+ biWidth: Longint;
+ biHeight: Longint;
+ biPlanes: Word;
+ biBitCount: Word;
+ biCompression: DWORD;
+ biSizeImage: DWORD;
+ biXPelsPerMeter: Longint;
+ biYPelsPerMeter: Longint;
+ biClrUsed: DWORD;
+ biClrImportant: DWORD;
+ end;
+ TBitmapInfoHeader = tagBITMAPINFOHEADER;
+ {$EXTERNALSYM BITMAPINFOHEADER}
+ BITMAPINFOHEADER = tagBITMAPINFOHEADER;
+
+ PBitmapInfo = ^TBitmapInfo;
+ {$EXTERNALSYM tagBITMAPINFO}
+ tagBITMAPINFO = packed record
+ bmiHeader: TBitmapInfoHeader;
+ bmiColors: array[0..0] of TRGBQuad;
+ end;
+ TBitmapInfo = tagBITMAPINFO;
+ {$EXTERNALSYM BITMAPINFO}
+ BITMAPINFO = tagBITMAPINFO;
+
+ PBitmapFileHeader = ^TBitmapFileHeader;
+ {$EXTERNALSYM tagBITMAPFILEHEADER}
+ tagBITMAPFILEHEADER = packed record
+ bfType: Word;
+ bfSize: DWORD;
+ bfReserved1: Word;
+ bfReserved2: Word;
+ bfOffBits: DWORD;
+ end;
+ TBitmapFileHeader = tagBITMAPFILEHEADER;
+ {$EXTERNALSYM BITMAPFILEHEADER}
+ BITMAPFILEHEADER = tagBITMAPFILEHEADER;
+
+
+ function MakeLong(a, b: Word): Longint;
+ procedure ZeroMemory(Destination: Pointer; Length: DWORD);
+ function QueryPerformanceFrequency(var lpFrequency: TLargeInteger): BOOL;
+ function QueryPerformanceCounter(var lpPerformanceCount: TLargeInteger): BOOL;
+ function GetTickCount : Cardinal;
+ Procedure ShowMessage(msg : string);
+ procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
+
+implementation
+
+uses SDL;
+
+procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
+begin
+ Move(Source^, Destination^, Length);
+end;
+
+Procedure ShowMessage(msg : string);
+begin
+ // to be implemented
+end;
+
+function MakeLong(A, B: Word): Longint;
+begin
+ Result := (LongInt(B) shl 16) + A;
+end;
+
+procedure ZeroMemory(Destination: Pointer; Length: DWORD);
+begin
+ FillChar( Destination^, Length, 0);
+end;
+
+function QueryPerformanceFrequency(var lpFrequency: TLargeInteger): BOOL;
+begin
+{$IFDEF MSWINDOWS}
+ Result := Windows.QueryPerformanceFrequency(lpFrequency);
+{$ENDIF}
+{$IFDEF MACOS}
+ Result := true;
+ lpFrequency := 1000;
+{$ENDIF}
+end;
+
+function QueryPerformanceCounter(var lpPerformanceCount: TLargeInteger): BOOL;
+begin
+{$IFDEF MSWINDOWS}
+ Result := Windows.QueryPerformanceCounter(lpPerformanceCount);
+{$ENDIF}
+{$IFDEF MACOS}
+ Result := true;
+ lpPerformanceCount := SDL_GetTicks;
+{$ENDIF}
+end;
+
+function GetTickCount : Cardinal;
+begin
+ Result := SDL_GetTicks;
+end;
+
+end.
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 00000000..8fc31bd8
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,393 @@
+#################################################
+# Makefile for @PACKAGE_STRING@
+# @configure_input@
+#################################################
+
+# general definitions
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+infodir = @infodir@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+datarootdir = @datarootdir@
+VPATH = @srcdir@
+usdxrootdir = @usdxrootdir@
+
+INSTALL_PATH_SUFFIX = @suffix@
+INSTALL_datadir = $(datarootdir)/$(INSTALL_PATH_SUFFIX)
+
+@SET_MAKE@
+
+# recursive dir creation tool
+MKDIR_P = @MKDIR_P@
+# install tool
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+# calls "ln -s"
+LN_S = @LN_S@
+
+# Package configuration
+USDX_PACKAGE_NAME = @PACKAGE_NAME@
+# should be $(USDX_PACKAGE_NAME) instead
+USDX_PREFIX = ultrastardx
+USDX_VERSION = @PACKAGE_VERSION@
+USDX_TARNAME = @PACKAGE_TARNAME@
+
+USDX_TOOLS_DIR = $(usdxrootdir)/Tools
+USDX_LIB_DIR = ./lib
+USDX_BUILD_DIR = ./build
+
+# file-type suffix of executables (e.g. ".exe" in windows)
+EXE_SUFFIX = @EXEEXT@
+
+# Free Pascal compiler
+PPC = @PPC@
+# FPC target platform and processor
+PPLATFORM = @FPC_PLATFORM@
+PPROCESSOR = @FPC_PROCESSOR@
+
+EXTRA_SRCDIRS =
+
+# RC resource extraction config
+RESEXTRACTOR_NAME = ResourceExtractor
+RESEXTRACTOR_DIR = $(USDX_TOOLS_DIR)/$(RESEXTRACTOR_NAME)
+RESEXTRACTOR_BIN = $(RESEXTRACTOR_DIR)/$(RESEXTRACTOR_NAME)$(EXE_SUFFIX)
+RESOURCE_DIR = $(usdxrootdir)/Resources
+RESOURCE_FILE = resource.inc
+RC_FILE = UltraStar.rc
+EXTRA_SRCDIRS += $(RESEXTRACTOR_DIR)
+
+# cwrapper settings
+PROJECTM_CWRAPPER_DIR = $(USDX_LIB_DIR)/projectM/cwrapper
+@COMMENT_PROJECTM_CWRAPPER@EXTRA_SRCDIRS += $(PROJECTM_CWRAPPER_DIR)
+
+# Directories added to the unit path
+PUNIT_TOKEN = -Fu
+PUNIT_FLAGS = $(PUNIT_TOKEN).
+
+# Directory where compiled units (.ppu and .o files) are stored
+PCUNIT_TOKEN = -FU
+PCUNIT_DIR = $(USDX_BUILD_DIR)/$(PPLATFORM)/fpc
+PCUNIT_FLAGS = $(PCUNIT_TOKEN)$(PCUNIT_DIR)
+
+# Directories added to the includes path
+PINC_TOKEN = -Fi
+PINC_FLAGS = $(PINC_TOKEN)$(USDX_LIB_DIR)/JEDI-SDL/SDL/Pas
+
+# FPC flags
+
+# The user can overwrite the default flags with
+# make PFLAGS_BASE="myflags"
+PFLAGS_BASE = -S2gi -vB
+# The user can specify additional flags with
+# make PFLAGS_EXTRA="myflags"
+PFLAGS_EXTRA = @PFLAGS_EXTRA@
+PFLAGS_DEBUG = @PFLAGS_DEBUG@
+PFLAGS_RELEASE = @PFLAGS_RELEASE@
+# the user's flags (specified with configure) must be the last in
+# the list to overwrite the defaults (e.g.with the - option: -Xs-).
+PFLAGS = $(PFLAGS_BASE) @PFLAGS_MAKE@ $(PFLAGS_EXTRA)
+
+LIBS = @LIBS@
+LDFLAGS = @LDFLAGS@
+linkflags = $(strip $(LDFLAGS) $(LIBS))
+ifneq ($(linkflags),)
+PLINKFLAGS = -k"$(linkflags)"
+endif
+
+# dpr project file used as input
+USDX_SRC = UltraStar.dpr
+# name of executable
+USDX_BIN_NAME = $(USDX_PREFIX)$(EXE_SUFFIX)
+USDX_BIN = $(usdxrootdir)/$(USDX_BIN_NAME)
+
+# name of the modification timestamp filename
+modfile = lastmod
+
+# otool: Mac OS X object file displaying tool
+OTOOL = /usr/bin/otool
+# install_name_tool: Mac OS X tool to change dynamic shared library install names
+INSTALL_NAME_TOOL = /usr/bin/install_name_tool
+# hdiutil: Mac OS X disk image tool
+HDIUTIL = /usr/bin/hdiutil
+
+#################################################
+# general targets
+#################################################
+
+.PHONY: debug release recursive all recursive-all dependencies install install-local install-global install-data install-data-recursive install-exec uninstall uninstall-local uninstall-global uninstall-data uninstall-exec clean recursive-clean distclean recursive-distclean clean_obj clean_res dist debian-package update-modfile $(EXTRA_SRCDIRS)
+
+debug: PFLAGS = $(PFLAGS_BASE) $(PFLAGS_DEBUG) $(PFLAGS_EXTRA)
+debug: all
+
+release: PFLAGS = $(PFLAGS_BASE) $(PFLAGS_RELEASE) $(PFLAGS_EXTRA)
+release: all
+
+all: recursive-all update-modfile dependencies $(USDX_BIN)
+
+recursive-all: recursive-target = all
+recursive-all: recursive
+
+dependencies: $(RESOURCE_FILE)
+
+# call Makefiles in other source-dirs
+recursive: $(EXTRA_SRCDIRS)
+$(EXTRA_SRCDIRS):
+ $(MAKE) -C $@ $(recursive-target)
+
+#################################################
+# build
+#################################################
+
+# clean old data before compiling, otherwise FPC might miss some changes.
+$(USDX_BIN): lastmod
+ $(MAKE) clean_obj
+ mkdir -p "$(PCUNIT_DIR)"
+ $(PPC) $(strip $(PFLAGS) $(PDEFINES) $(PLINKFLAGS) $(PINC_FLAGS) $(PUNIT_FLAGS) $(PCUNIT_FLAGS)) -o$@ $(USDX_SRC)
+
+#################################################
+# install/uninstall
+#################################################
+
+install: all install-@install_type@
+
+uninstall: uninstall-@install_type@
+
+
+# local build
+
+install-local:
+
+uninstall-local:
+ rm -f "$(USDX_BIN)"
+
+
+# global build
+
+install-global: install-data install-exec
+
+install-data:
+ $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Artwork" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Artwork" install-data-recursive
+ $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Languages" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Languages" install-data-recursive
+ $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Sounds" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Sounds" install-data-recursive
+ $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Themes" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Themes" install-data-recursive
+ $(MAKE) RECURSIVE_SRC_DIR="$(usdxrootdir)/Resources" RECURSIVE_DST_DIR="$(INSTALL_datadir)/Resources" install-data-recursive
+ $(INSTALL_DATA) "$(usdxrootdir)/License.txt" "$(INSTALL_datadir)"
+
+install-data-recursive:
+ $(MKDIR_P) "$(RECURSIVE_DST_DIR)"
+ @for file in "$(RECURSIVE_SRC_DIR)"/*; do \
+ if test -f "$$file"; then \
+ echo $(INSTALL_DATA) "$$file" "$(RECURSIVE_DST_DIR)"; \
+ $(INSTALL_DATA) "$$file" "$(RECURSIVE_DST_DIR)"; \
+ fi; \
+ if test -d "$$file"; then \
+ subdir="$$file"; \
+ subdirname=`basename "$$subdir"`; \
+ $(MAKE) RECURSIVE_SRC_DIR="$$subdir" RECURSIVE_DST_DIR="$(RECURSIVE_DST_DIR)/$$subdirname" install-data-recursive; \
+ fi; \
+ done
+
+install-exec:
+ $(MKDIR_P) "$(bindir)"
+ $(INSTALL) "$(USDX_BIN)" "$(bindir)"
+
+uninstall-global: uninstall-data uninstall-exec
+
+uninstall-data:
+ rm -rf "$(INSTALL_datadir)/Artwork"
+ rm -rf "$(INSTALL_datadir)/Languages"
+ rm -rf "$(INSTALL_datadir)/Sounds"
+ rm -rf "$(INSTALL_datadir)/Themes"
+ rm -rf "$(INSTALL_datadir)/Resources"
+ rm -f "$(INSTALL_datadir)/License.txt"
+ -rmdir "$(INSTALL_datadir)"
+
+uninstall-exec:
+ rm -f "$(bindir)/$(USDX_BIN_NAME)"
+
+#################################################
+# Distributable source-package (TODO)
+#################################################
+
+disttmpdir = ./distdir
+
+dist:
+# $(MKDIR_P) $(disttmpdir)
+# acm $(usdxrootdir) $(disttmpdir)
+# $(MAKE) -C $(disttmpdir)/Game/Code distclean
+# tar cvzf $(USDX_TARNAME)-$(USDX_VERSION).tar.gz $(usdxrootdir)
+ @echo "Comming soon"
+
+#################################################
+# Debian package
+#################################################
+
+debpkgoutdir = $(usdxrootdir)/packages
+debpkgtmpdir = $(debpkgoutdir)/deb-package
+# should be $(USDX_PACKAGE_NAME) instead
+debpkgprefix = ultrastardx
+debpkgname = $(debpkgprefix)_$(USDX_VERSION)_$(PPROCESSOR).deb
+
+debian-pkg: all
+ rm -rf $(debpkgtmpdir)
+ rm -rf $(debpkgoutdir)
+
+ $(MKDIR_P) $(debpkgoutdir)
+ $(MKDIR_P) $(debpkgtmpdir)/DEBIAN
+
+ $(MAKE) prefix=$(debpkgtmpdir)/$(prefix) install
+
+ $(INSTALL_DATA) $(debpkgprefix).control $(debpkgtmpdir)/DEBIAN/control
+
+ dpkg-deb --build $(debpkgtmpdir)
+ mv $(debpkgtmpdir)/../deb-package.deb $(debpkgoutdir)/$(debpkgname)
+
+ rm -rf $(debpkgtmpdir)
+
+#################################################
+# RPM (TODO)
+#################################################
+
+rpm: all
+ @echo "Coming soon"
+
+#################################################
+# Mac OS X app-bundle
+#################################################
+
+macosx_bundle_path = $(usdxrootdir)/UltraStarDeluxe.app/Contents
+macosx-app: all
+# Create double clickable Mac OS X application.
+
+ @echo ""
+ @echo "Creating the Mac OS X application"
+ @echo ""
+
+ $(MKDIR_P) $(macosx_bundle_path)/Resources
+
+# Put the icon file into its particular place.
+# Must be done BEFORE info.plist is created.
+ $(INSTALL_DATA) $(usdxrootdir)/Resources/Graphics/ustar-icon_v01.icns $(macosx_bundle_path)/Resources/
+
+# the info.plist file
+ $(INSTALL_DATA) MacOSX/Info.plist $(macosx_bundle_path)/
+
+# Copy the resources.
+ $(MAKE) install-global INSTALL_datadir=$(macosx_bundle_path)/Resources bindir=$(macosx_bundle_path)/MacOS
+
+# final messages
+ @echo ""
+ @echo "Mac OS X application created."
+ @echo "Please report issues to the developer team, preferably mischi."
+ @echo "Have fun."
+ @echo ""
+
+macosx-standalone-app: macosx-app
+# Create double clickable standalone (does not need fink) Mac OS X
+# application. Not fully test, but should work on 10.5.
+
+ @echo ""
+ @echo "Creating the standalone Mac OS X application"
+ @echo ""
+
+# copy the dylib and change its install names
+
+define install_osx_libraries
+ $(shell $(INSTALL) -m 755 $(dylib) $(macosx_bundle_path)/MacOS)
+ $(shell $(INSTALL_NAME_TOOL) -change $(dylib) @executable_path/$(notdir $(dylib)) $(macosx_bundle_path)/MacOS/ultrastardx)
+ $(shell $(INSTALL_NAME_TOOL) -id @executable_path/$(notdir $(dylib)) $(macosx_bundle_path)/MacOS/$(notdir $(dylib)))
+ $(foreach linked_dylibs_2,$(shell $(OTOOL) -L $(dylib) | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \usr\/lib | grep -v executable_path),$(rename_secondary_osx_libraries))
+endef
+
+define rename_secondary_osx_libraries
+ $(shell $(INSTALL_NAME_TOOL) -change $(linked_dylibs_2) @executable_path/$(notdir $(linked_dylibs_2)) $(macosx_bundle_path)/MacOS/$(notdir $(dylib)))
+endef
+
+# work on the dylibs in $(macosx_bundle_path)/MacOS/ultrastardx
+ $(foreach dylib,$(shell $(OTOOL) -L $(macosx_bundle_path)/MacOS/ultrastardx | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
+
+# work on the secondary dylibs from ffmpeg
+# libavcodec references all tertiary libraries of the ffmpeg libs
+ $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libavcodec.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
+# same procedure in libfaac. it gets libgnugetopt
+ $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libfaac.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
+
+# same procedure for tertiary libs in SDL_image
+ $(foreach dylib,$(shell $(OTOOL) -L /sw/lib/libSDL_image.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
+
+# X11 libs as well, because users may not have installed it on 10.4
+ $(foreach dylib,$(shell $(OTOOL) -L /usr/X11R6/lib/libX11.dylib | grep version | cut -f 1 -d ' ' | grep -v \/System\/Library | grep -v \/usr\/lib),$(install_osx_libraries))
+
+# final messages
+ @echo "Standalone Mac OS X application created."
+ @echo ""
+
+macosx-disk-image: macosx-standalone-app
+ /bin/rm -f ultrastardx.dmg
+ $(HDIUTIL) create -type SPARSE -size 30m -fs HFS+ -volname UltraStarDeluxe -ov -attach UltraStarDeluxe.sparseimage
+ /bin/cp -R ../../UltraStarDeluxe.app /Volumes/UltraStarDeluxe
+# /bin/cp ultrastardx/icons/UltraStarDeluxeVolumeIcon.icns /Volumes/UltraStarDeluxe/.VolumeIcon.icns
+# /Developer/Tools/SetFile -a C /Volumes/UltraStarDeluxe/.VolumeIcon.icns /Volumes/UltraStarDeluxe
+ $(HDIUTIL) detach /Volumes/UltraStarDeluxe
+ $(HDIUTIL) convert UltraStarDeluxe.sparseimage -format UDBZ -o ultrastardx.dmg
+ /bin/rm -f UltraStarDeluxe.sparseimage
+#################################################
+# clean-up
+#################################################
+
+clean: recursive-clean clean_obj
+
+recursive-clean: recursive-target = clean
+recursive-clean: recursive
+
+distclean: recursive-distclean clean clean_res
+ find . -name "*.o" -o -name "*.ppu" -o -name "*.rst" -o -name "*.compiled" | xargs rm -f
+ find . -name "*~" -name "*.bak" -o -name "*.orig" -o -name "*.dcu" | xargs rm -f
+ find . -name "__history" | xargs rm -r -f
+ rm -f "$(USDX_PREFIX).res" "$(USDX_PREFIX).identcache"
+ rm -f config.inc Makefile config.log config.status configure aclocal.m4
+ rm -rf autom4te.cache
+
+recursive-distclean: recursive-target = distclean
+recursive-distclean: recursive
+
+clean_obj:
+ find "$(PCUNIT_DIR)" -name "*.o" -o -name "*.ppu" -o -name "*.rst" -o -name "*.compiled" | xargs rm -f
+ rm -f "$(USDX_BIN)"
+
+#################################################
+# Resource-file
+#################################################
+
+$(RESOURCE_FILE): $(RC_FILE)
+ $(RESEXTRACTOR_BIN) $(RC_FILE) $(RESOURCE_DIR) $(RESOURCE_FILE)
+
+clean_res:
+ rm -f "$(RESOURCE_FILE)"
+
+#################################################
+# auto-update
+#################################################
+
+# FPC does not recognize changes correctly. E.g. sometimes changes in .inc-files or
+# conditional .pas dependencies are ignored which results in corrupted builds.
+# So check for changes with a modification timestamp.
+update-modfile:
+ test -e $(modfile) || touch $(modfile)
+ find . \( -name "*.pas" -o -name "*.pp" -o -name "*.inc" -o -name "*.dpr" \) -newer $(modfile) -exec touch $(modfile) \;
+ find $(USDX_LIB_DIR) -name "*.a" -newer $(modfile) -exec touch $(modfile) \;
+
+Makefile: Makefile.in config.status
+ ./config.status
+
+config.status: configure
+ ./config.status --recheck
+
+configure: configure.ac config.inc.in aclocal.m4
+ autoconf
+
+aclocal.m4: m4/*
+ aclocal -I m4
diff --git a/src/Menu/UDisplay.pas b/src/Menu/UDisplay.pas
new file mode 100644
index 00000000..2b10b2c6
--- /dev/null
+++ b/src/Menu/UDisplay.pas
@@ -0,0 +1,383 @@
+unit UDisplay;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ ucommon,
+ SDL,
+ UMenu,
+ gl,
+ glu,
+ SysUtils;
+
+type
+ TDisplay = class
+ private
+ //fade-to-black-hack
+ BlackScreen: Boolean;
+
+ FadeEnabled: Boolean; // true if fading is enabled
+ FadeFailed: Boolean; // true if fading is possible (enough memory, etc.)
+ FadeState: integer; // fading state, 0 means that the fade texture must be initialized
+ LastFadeTime: Cardinal; // last fade update time
+
+ FadeTex: array[1..2] of GLuint;
+
+ FPSCounter : Cardinal;
+ LastFPS : Cardinal;
+ NextFPSSwap : Cardinal;
+
+ OSD_LastError : String;
+
+ procedure DrawDebugInformation;
+ public
+ NextScreen : PMenu;
+ CurrentScreen : PMenu;
+
+ //popup data
+ NextScreenWithCheck: Pmenu;
+ CheckOK : Boolean;
+
+ // FIXME: Fade is set to 0 in UMain and other files but not used here anymore.
+ Fade : Real;
+
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure SaveScreenShot;
+
+ function Draw: Boolean;
+ end;
+
+var
+ Display: TDisplay;
+
+implementation
+
+uses
+ UImage,
+ TextGL,
+ ULog,
+ UMain,
+ UTexture,
+ UIni,
+ UGraphic,
+ UTime,
+ UCommandLine;
+
+constructor TDisplay.Create;
+var
+ i: integer;
+begin
+ inherited Create;
+
+ //popup hack
+ CheckOK := False;
+ NextScreen := nil;
+ NextScreenWithCheck := nil;
+ BlackScreen := False;
+
+ // fade mod
+ FadeState := 0;
+ FadeEnabled := (Ini.ScreenFade = 1);
+ FadeFailed:= false;
+
+ glGenTextures(2, @FadeTex);
+
+ for i := 1 to 2 do
+ begin
+ glBindTexture(GL_TEXTURE_2D, FadeTex[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ end;
+
+ //Set LastError for OSD to No Error
+ OSD_LastError := 'No Errors';
+end;
+
+destructor TDisplay.Destroy;
+begin
+ glDeleteTextures(2, @FadeTex);
+ inherited Destroy;
+end;
+
+function TDisplay.Draw: Boolean;
+var
+ S: integer;
+ FadeStateSquare: Real;
+ currentTime: Cardinal;
+ glError: glEnum;
+begin
+ Result := True;
+
+ glClearColor(1, 1, 1 , 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ for S := 1 to Screens do
+ begin
+ ScreenAct := S;
+
+ //if Screens = 1 then ScreenX := 0;
+ //if (Screens = 2) and (S = 1) then ScreenX := -1;
+ //if (Screens = 2) and (S = 2) then ScreenX := 1;
+ ScreenX := 0;
+
+ glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
+
+ // popup hack
+ // check was successful... move on
+ if CheckOK then
+ begin
+ if assigned(NextScreenWithCheck) then
+ begin
+ NextScreen := NextScreenWithCheck;
+ NextScreenWithCheck := nil;
+ CheckOk := False;
+ end
+ else
+ begin
+ // on end of game fade to black before exit
+ BlackScreen := True;
+ end;
+ end;
+
+ if (not assigned(NextScreen)) and (not BlackScreen) then
+ begin
+ CurrentScreen.Draw;
+
+ //popup mod
+ if (ScreenPopupError <> nil) and ScreenPopupError.Visible then
+ ScreenPopupError.Draw
+ else if (ScreenPopupCheck <> nil) and ScreenPopupCheck.Visible then
+ ScreenPopupCheck.Draw;
+
+ // fade mod
+ FadeState := 0;
+ if ((Ini.ScreenFade = 1) and (not FadeFailed)) then
+ FadeEnabled := True
+ else if (Ini.ScreenFade = 0) then
+ FadeEnabled := False;
+ end
+ else
+ begin
+ // disable fading if initialization failed
+ if (FadeEnabled and FadeFailed) then
+ begin
+ FadeEnabled := False;
+ end;
+
+ if (FadeEnabled and not FadeFailed) then
+ begin
+ //Create Fading texture if we're just starting
+ if FadeState = 0 then
+ begin
+ // save old viewport and resize to fit texture
+ glPushAttrib(GL_VIEWPORT_BIT);
+ glViewPort(0, 0, 512, 512);
+
+ // draw screen that will be faded
+ CurrentScreen.Draw;
+
+ // clear OpenGL errors, otherwise fading might be disabled due to some
+ // older errors in previous OpenGL calls.
+ glGetError();
+
+ // copy screen to texture
+ glBindTexture(GL_TEXTURE_2D, FadeTex[S]);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0);
+ glError := glGetError();
+ if (glError <> GL_NO_ERROR) then
+ begin
+ FadeFailed := true;
+ Log.LogWarn('Fading disabled: ' + gluErrorString(glError), 'TDisplay.Draw');
+ end;
+
+ // restore viewport
+ glPopAttrib();
+
+ // blackscreen-hack
+ if not BlackScreen then
+ NextScreen.onShow;
+
+ // update fade state
+ LastFadeTime := SDL_GetTicks();
+ if (S = 2) or (Screens = 1) then
+ FadeState := FadeState + 1;
+ end; // end texture creation in first fading step
+
+ //do some time-based fading
+ currentTime := SDL_GetTicks();
+ if (currentTime > LastFadeTime+30) and (S = 1) then
+ begin
+ FadeState := FadeState + 4;
+ LastFadeTime := currentTime;
+ end;
+
+ // blackscreen-hack
+ if not BlackScreen then
+ NextScreen.Draw // draw next screen
+ else if ScreenAct = 1 then
+ begin
+ glClearColor(0, 0, 0 , 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+
+ // and draw old screen over it... slowly fading out
+
+ FadeStateSquare := (FadeState*FadeState)/10000;
+
+ glBindTexture(GL_TEXTURE_2D, FadeTex[S]);
+ glColor4f(1, 1, 1, 1-FadeStateSquare);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0+FadeStateSquare, 0+FadeStateSquare); glVertex2f(0, 600);
+ glTexCoord2f(0+FadeStateSquare, 1-FadeStateSquare); glVertex2f(0, 0);
+ glTexCoord2f(1-FadeStateSquare, 1-FadeStateSquare); glVertex2f(800, 0);
+ glTexCoord2f(1-FadeStateSquare, 0+FadeStateSquare); glVertex2f(800, 600);
+ glEnd;
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end
+ // blackscreen hack
+ else if not BlackScreen then
+ begin
+ NextScreen.OnShow;
+ end;
+
+ if ((FadeState > 40) or (not FadeEnabled) or FadeFailed) and (S = 1) then
+ begin
+ // fade out complete...
+ FadeState := 0;
+ CurrentScreen.onHide;
+ CurrentScreen.ShowFinish := False;
+ CurrentScreen := NextScreen;
+ NextScreen := nil;
+ if not BlackScreen then
+ begin
+ CurrentScreen.onShowFinish;
+ CurrentScreen.ShowFinish := true;
+ end
+ else
+ begin
+ Result := False;
+ Break;
+ end;
+ end;
+ end; // if
+
+ //Draw OSD only on first Screen if Debug Mode is enabled
+ if ((Ini.Debug = 1) or (Params.Debug)) and (S = 1) then
+ DrawDebugInformation;
+ end; // for
+end;
+
+procedure TDisplay.SaveScreenShot;
+var
+ Num: integer;
+ FileName: string;
+ ScreenData: PChar;
+ Surface: PSDL_Surface;
+ Success: boolean;
+ Align: integer;
+ RowSize: integer;
+begin
+ // Exit if Screenshot-path does not exist or read-only
+ if (ScreenshotsPath = '') then
+ Exit;
+
+ for Num := 1 to 9999 do
+ begin
+ FileName := IntToStr(Num);
+ while Length(FileName) < 4 do
+ FileName := '0' + FileName;
+ FileName := ScreenshotsPath + 'screenshot' + FileName + '.png';
+ if not FileExists(FileName) then
+ break
+ end;
+
+ // we must take the row-alignment (4byte by default) into account
+ glGetIntegerv(GL_PACK_ALIGNMENT, @Align);
+ // calc aligned row-size
+ RowSize := ((ScreenW*3 + (Align-1)) div Align) * Align;
+
+ GetMem(ScreenData, RowSize * ScreenH);
+ glReadPixels(0, 0, ScreenW, ScreenH, GL_RGB, GL_UNSIGNED_BYTE, ScreenData);
+ Surface := SDL_CreateRGBSurfaceFrom(
+ ScreenData, ScreenW, ScreenH, 24, RowSize,
+ $0000FF, $00FF00, $FF0000, 0);
+
+ //Success := WriteJPGImage(FileName, Surface, 95);
+ //Success := WriteBMPImage(FileName, Surface);
+ Success := WritePNGImage(FileName, Surface);
+ if Success then
+ ScreenPopupError.ShowPopup('Screenshot saved: ' + ExtractFileName(FileName))
+ else
+ ScreenPopupError.ShowPopup('Screenshot failed');
+
+ SDL_FreeSurface(Surface);
+ FreeMem(ScreenData);
+end;
+
+//------------
+// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
+//------------
+procedure TDisplay.DrawDebugInformation;
+var Ticks: Cardinal;
+begin
+ //Some White Background for information
+ glEnable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 0.5);
+ glBegin(GL_QUADS);
+ glVertex2f(690, 44);
+ glVertex2f(690, 0);
+ glVertex2f(800, 0);
+ glVertex2f(800, 44);
+ glEnd;
+ glDisable(GL_BLEND);
+
+ //Set Font Specs
+ SetFontStyle(0);
+ SetFontSize(7);
+ SetFontItalic(False);
+ glColor4f(0, 0, 0, 1);
+
+ //Calculate FPS
+ Ticks := SDL_GetTicks();
+ if (Ticks >= NextFPSSwap) then
+ begin
+ LastFPS := FPSCounter * 4;
+ FPSCounter := 0;
+ NextFPSSwap := Ticks + 250;
+ end;
+
+ Inc(FPSCounter);
+
+ //Draw Text
+
+ //FPS
+ SetFontPos(695, 0);
+ glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
+
+ //RSpeed
+ SetFontPos(695, 13);
+ glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
+
+ //LastError
+ SetFontPos(695, 26);
+ glColor4f(1, 0, 0, 1);
+ glPrint (PChar(OSD_LastError));
+
+ glColor4f(1, 1, 1, 1);
+end;
+
+end.
diff --git a/src/Menu/UDrawTexture.pas b/src/Menu/UDrawTexture.pas
new file mode 100644
index 00000000..a7dde18f
--- /dev/null
+++ b/src/Menu/UDrawTexture.pas
@@ -0,0 +1,105 @@
+unit UDrawTexture;
+
+interface
+
+{$I switches.inc}
+
+uses UTexture;
+
+procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
+procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
+procedure DrawTexture(Texture: TTexture);
+
+implementation
+
+uses gl;
+
+procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
+begin
+ glColor3f(ColR, ColG, ColB);
+ glBegin(GL_LINES);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glEnd;
+end;
+
+procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
+begin
+ glColor3f(ColR, ColG, ColB);
+ glBegin(GL_QUADS);
+ glVertex2f(x, y);
+ glVertex2f(x, y+h);
+ glVertex2f(x+w, y+h);
+ glVertex2f(x+w, y);
+ glEnd;
+end;
+
+procedure DrawTexture(Texture: TTexture);
+var
+ x1, x2, x3, x4: real;
+ y1, y2, y3, y4: real;
+ xt1, xt2, xt3, xt4: real;
+ yt1, yt2, yt3, yt4: real;
+begin
+ with Texture do begin
+ // rysuje paski gracza
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+// glDepthFunc(GL_GEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+// glBlendFunc(GL_SRC_COLOR, GL_ZERO);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ x1 := x;
+ x2 := x;
+ x3 := x+w*scaleW;
+ x4 := x+w*scaleW;
+ y1 := y;
+ y2 := y+h*scaleH;
+ y3 := y+h*scaleH;
+ y4 := y;
+ if Rot <> 0 then begin
+ xt1 := x1 - (x + w/2);
+ xt2 := x2 - (x + w/2);
+ xt3 := x3 - (x + w/2);
+ xt4 := x4 - (x + w/2);
+ yt1 := y1 - (y + h/2);
+ yt2 := y2 - (y + h/2);
+ yt3 := y3 - (y + h/2);
+ yt4 := y4 - (y + h/2);
+
+ x1 := (x + w/2) + xt1 * cos(Rot) - yt1 * sin(Rot);
+ x2 := (x + w/2) + xt2 * cos(Rot) - yt2 * sin(Rot);
+ x3 := (x + w/2) + xt3 * cos(Rot) - yt3 * sin(Rot);
+ x4 := (x + w/2) + xt4 * cos(Rot) - yt4 * sin(Rot);
+
+ y1 := (y + h/2) + yt1 * cos(Rot) + xt1 * sin(Rot);
+ y2 := (y + h/2) + yt2 * cos(Rot) + xt2 * sin(Rot);
+ y3 := (y + h/2) + yt3 * cos(Rot) + xt3 * sin(Rot);
+ y4 := (y + h/2) + yt4 * cos(Rot) + xt4 * sin(Rot);
+
+ end;
+
+{ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(x1, y1, z);
+ glTexCoord2f(0, TexH); glVertex3f(x2, y2, z);
+ glTexCoord2f(TexW, TexH); glVertex3f(x3, y3, z);
+ glTexCoord2f(TexW, 0); glVertex3f(x4, y4, z);
+ glEnd;}
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(TexX1*TexW, TexY1*TexH); glVertex3f(x1, y1, z);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH); glVertex3f(x2, y2, z);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH); glVertex3f(x3, y3, z);
+ glTexCoord2f(TexX2*TexW, TexY1*TexH); glVertex3f(x4, y4, z);
+ glEnd;
+ end;
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+end.
diff --git a/src/Menu/UMenu.pas b/src/Menu/UMenu.pas
new file mode 100644
index 00000000..e352febd
--- /dev/null
+++ b/src/Menu/UMenu.pas
@@ -0,0 +1,1432 @@
+unit UMenu;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses gl, SysUtils, UTexture, UMenuStatic, UMenuText, UMenuButton, UMenuSelectSlide,
+ UMenuInteract, UThemes, UMenuButtonCollection, Math, UMusic;
+
+type
+{ Int16 = SmallInt;}
+
+ PMenu = ^TMenu;
+ TMenu = class
+ protected
+ ButtonPos: Integer;
+
+ Interactions: array of TInteract;
+ SelInteraction: integer;
+ Button: array of TButton;
+ SelectsS: array of TSelectSlide;
+ ButtonCollection: array of TButtonCollection;
+ BackImg: TTexture;
+ BackW: integer;
+ BackH: integer;
+
+ fFileName : string;
+ public
+ Text: array of TText;
+ Static: array of TStatic;
+ mX: integer; // mouse X
+ mY: integer; // mouse Y
+
+ Fade: integer; // fade type
+ ShowFinish: boolean; // true if there is no fade
+
+
+ destructor Destroy; override;
+ constructor Create; overload; virtual;
+ //constructor Create(Back: string); overload; virtual; // Back is a JPG resource name for background
+ //constructor Create(Back: string; W, H: integer); overload; virtual; // W and H are the number of overlaps
+
+ // interaction
+ function WideCharUpperCase(wchar: WideChar) : WideString;
+ function WideStringUpperCase(wstring: WideString) : WideString;
+ procedure AddInteraction(Typ, Num: integer);
+ procedure SetInteraction(Num: integer);
+ property Interaction: integer read SelInteraction write SetInteraction;
+
+ //Procedure Load BG, Texts, Statics and Button Collections from ThemeBasic
+ procedure LoadFromTheme(const ThemeBasic: TThemeBasic);
+
+ procedure PrepareButtonCollections(const Collections: AThemeButtonCollection);
+ procedure AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
+
+ // background
+ procedure AddBackground(Name: string);
+
+ // static
+ function AddStatic(ThemeStatic: TThemeStatic): integer; overload;
+ function AddStatic(X, Y, W, H: real; const Name: string): integer; overload;
+ function AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer; overload;
+ function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload;
+ function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: Boolean; ReflectionSpacing: Real): integer; overload;
+
+ // text
+ function AddText(ThemeText: TThemeText): integer; overload;
+ function AddText(X, Y: real; const Text_: string): integer; overload;
+ function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer; overload;
+ function AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: Boolean; ReflectionSpacing_: Real; Z : Real): integer; overload;
+
+ // button
+ Procedure SetButtonLength(Length: Cardinal); //Function that Set Length of Button Array in one Step instead of register new Memory for every Button
+ function AddButton(ThemeButton: TThemeButton): integer; overload;
+ function AddButton(X, Y, W, H: real; const Name: String): integer; overload;
+ function AddButton(X, Y, W, H: real; const Name: String; Typ: TTextureType; Reflection: Boolean): integer; overload;
+ function AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; const Name: String; Typ: TTextureType; Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer; overload;
+ procedure ClearButtons;
+ procedure AddButtonText(AddX, AddY: real; const AddText: string); overload;
+ procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string); overload;
+ procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload;
+ procedure AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload;
+
+ // select slide
+ function AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer; overload;
+ function AddSelectSlide(X, Y, W, H, SkipX, SBGW, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ const Name: String; Typ: TTextureType; const SBGName: String; SBGTyp: TTextureType;
+ const Caption: string; var Data: integer): integer; overload;
+ procedure AddSelectSlideOption(const AddText: string); overload;
+ procedure AddSelectSlideOption(SelectNo: Cardinal; const AddText: string); overload;
+ procedure UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
+
+// function AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
+// procedure ClearWidgets(MinNumber : Int16);
+ procedure FadeTo(Screen: PMenu); overload;
+ procedure FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream); overload;
+ //popup hack
+ procedure CheckFadeTo(Screen: PMenu; msg: String);
+
+ function DrawBG: boolean; virtual;
+ function DrawFG: boolean; virtual;
+ function Draw: boolean; virtual;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown : Boolean): Boolean; virtual;
+ // FIXME: ParseMouse is not implemented in any subclass and not even used anywhere in the code
+ // -> do this before activation of this method
+ //function ParseMouse(Typ: integer; X: integer; Y: integer): Boolean; virtual; abstract;
+ procedure onShow; virtual;
+ procedure onShowFinish; virtual;
+ procedure onHide; virtual;
+
+ procedure SetAnimationProgress(Progress: real); virtual;
+
+ function IsSelectable(Int: Cardinal): Boolean;
+
+ procedure InteractNext; virtual;
+ procedure InteractCustom(CustomSwitch: integer); virtual;
+ procedure InteractPrev; virtual;
+ procedure InteractInc; virtual;
+ procedure InteractDec; virtual;
+ procedure InteractNextRow; virtual; // this is for the options screen, so button down makes sense
+ procedure InteractPrevRow; virtual; // this is for the options screen, so button up makes sense
+ procedure AddBox(X, Y, W, H: real);
+ end;
+
+const
+ pmMove = 1;
+ pmClick = 2;
+ pmUnClick = 3;
+
+ iButton = 0; // interaction type
+ iText = 2;
+ iSelectS = 3;
+ iBCollectionChild = 5;
+
+// fBlack = 0; // fade type
+// fWhite = 1;
+
+implementation
+
+uses UCommon,
+ ULog,
+ UMain,
+ UDrawTexture,
+ UGraphic,
+ UDisplay,
+ UCovers,
+ UTime,
+ USkins;
+
+destructor TMenu.Destroy;
+begin
+ inherited;
+end;
+
+constructor TMenu.Create;
+begin
+ inherited;
+
+ Fade := 0;//fWhite;
+
+ SetLength(Static, 0);
+ SetLength(Button, 0);
+
+ BackImg.TexNum := 0;
+
+ //Set ButtonPos to Autoset Length
+ ButtonPos := -1;
+end;
+{
+constructor TMenu.Create(Back: String);
+begin
+ inherited Create;
+
+ if Back <> '' then begin
+// BackImg := Texture.GetTexture(true, Back, TEXTURE_TYPE_PLAIN, 0);
+ BackImg := Texture.GetTexture(Back, TEXTURE_TYPE_PLAIN, 0); // new theme system
+ BackImg.W := 800;//640;
+ BackImg.H := 600;//480;
+ BackW := 1;
+ BackH := 1;
+ end else
+ BackImg.TexNum := 0;
+
+ //Set ButtonPos to Autoset Length
+ ButtonPos := -1;
+end;
+
+constructor TMenu.Create(Back: string; W, H: integer);
+begin
+ Create(Back);
+ BackImg.W := BackImg.W / W;
+ BackImg.H := BackImg.H / H;
+ BackW := W;
+ BackH := H;
+end; }
+
+function RGBFloatToInt(R, G, B: Double): Cardinal;
+begin
+ Result := (Trunc(255 * R) shl 16) or
+ (Trunc(255 * G) shl 8) or
+ Trunc(255 * B);
+end;
+
+procedure TMenu.AddInteraction(Typ, Num: integer);
+var
+ IntNum: integer;
+begin
+ IntNum := Length(Interactions);
+ SetLength(Interactions, IntNum+1);
+ Interactions[IntNum].Typ := Typ;
+ Interactions[IntNum].Num := Num;
+ Interaction := 0;
+end;
+
+procedure TMenu.SetInteraction(Num: integer);
+var
+ OldNum, OldTyp: integer;
+ NewNum, NewTyp: integer;
+begin
+ // set inactive
+ OldNum := Interactions[Interaction].Num;
+ OldTyp := Interactions[Interaction].Typ;
+
+ NewNum := Interactions[Num].Num;
+ NewTyp := Interactions[Num].Typ;
+
+ case OldTyp of
+ iButton: Button[OldNum].Selected := False;
+ iText: Text[OldNum].Selected := False;
+ iSelectS: SelectsS[OldNum].Selected := False;
+ //Button Collection Mod
+ iBCollectionChild:
+ begin
+ Button[OldNum].Selected := False;
+
+ //Deselect Collection if Next Button is Not from Collection
+ if (NewTyp <> iButton) Or (Button[NewNum].Parent <> Button[OldNum].Parent) then
+ ButtonCollection[Button[OldNum].Parent-1].Selected := False;
+ end;
+ end;
+
+ // set active
+ SelInteraction := Num;
+ case NewTyp of
+ iButton: Button[NewNum].Selected := True;
+ iText: Text[NewNum].Selected := True;
+ iSelectS: SelectsS[NewNum].Selected := True;
+
+ //Button Collection Mod
+ iBCollectionChild:
+ begin
+ Button[NewNum].Selected := True;
+ ButtonCollection[Button[NewNum].Parent-1].Selected := True;
+ end;
+ end;
+end;
+
+//----------------------
+//LoadFromTheme - Load BG, Texts, Statics and
+//Button Collections from ThemeBasic
+//----------------------
+procedure TMenu.LoadFromTheme(const ThemeBasic: TThemeBasic);
+var
+ I: Integer;
+begin
+ //Add Button Collections (Set Button CollectionsLength)
+ //Button Collections are Created when the first ChildButton is Created
+ PrepareButtonCollections(ThemeBasic.ButtonCollection);
+
+ //Add Background
+ AddBackground(ThemeBasic.Background.Tex);
+
+ //Add Statics and Texts
+ for I := 0 to High(ThemeBasic.Static) do
+ AddStatic(ThemeBasic.Static[I]);
+
+ for I := 0 to High(ThemeBasic.Text) do
+ AddText(ThemeBasic.Text[I]);
+end;
+
+procedure TMenu.AddBackground(Name: string);
+//var
+// lFileName : string;
+begin
+ if Name <> '' then
+ begin
+ fFileName := Skin.GetTextureFileName(Name);
+ fFileName := AdaptFilePaths( fFileName );
+
+ if fileexists( fFileName ) then
+ begin
+ BackImg := Texture.GetTexture( fFileName , TEXTURE_TYPE_PLAIN);
+
+ if ( BackImg.TexNum = 0 ) then
+ begin
+ if VideoPlayback.Open( fFileName ) then
+ begin
+ VideoBGTimer.SetTime(0);
+ VideoPlayback.Play;
+ end;
+ end;
+
+ BackImg.W := 800;
+ BackImg.H := 600;
+ BackW := 1;
+ BackH := 1;
+ end;
+ end;
+end;
+
+//----------------------
+//PrepareButtonCollections:
+//Add Button Collections (Set Button CollectionsLength)
+//----------------------
+procedure TMenu.PrepareButtonCollections(const Collections: AThemeButtonCollection);
+var
+ I: Integer;
+begin
+ SetLength(ButtonCollection, Length(Collections));
+ For I := 0 to High(ButtonCollection) do
+ AddButtonCollection(Collections[I], I);
+end;
+
+//----------------------
+//AddButtonCollection:
+//Create a Button Collection;
+//----------------------
+procedure TMenu.AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
+var
+ BT, BTLen: Integer;
+ TempCol, TempDCol: Cardinal;
+
+begin
+ if (Num > High(ButtonCollection)) then
+ exit;
+
+ TempCol := 0;
+
+ // colorize hack
+ if (ThemeCollection.Style.Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ TempCol := RGBFloatToInt(ThemeCollection.Style.ColR, ThemeCollection.Style.ColG, ThemeCollection.Style.ColB);
+ TempDCol := RGBFloatToInt(ThemeCollection.Style.DColR, ThemeCollection.Style.DColG, ThemeCollection.Style.DColB);
+ // give encoded color to GetTexture()
+ ButtonCollection[Num] := TButtonCollection.Create(
+ Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempCol),
+ Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempDCol));
+ end
+ else
+ begin
+ ButtonCollection[Num] := TButtonCollection.Create(Texture.GetTexture(
+ Skin.GetTextureFileName(ThemeCollection.Style.Tex), ThemeCollection.Style.Typ));
+ end;
+
+ //Set Parent menu
+ ButtonCollection[Num].ScreenButton := @Self.Button;
+
+ //Set Attributes
+ ButtonCollection[Num].FirstChild := ThemeCollection.FirstChild;
+ ButtonCollection[Num].CountChilds := ThemeCollection.ChildCount;
+ ButtonCollection[Num].Parent := Num + 1;
+
+ //Set Style
+ ButtonCollection[Num].X := ThemeCollection.Style.X;
+ ButtonCollection[Num].Y := ThemeCollection.Style.Y;
+ ButtonCollection[Num].W := ThemeCollection.Style.W;
+ ButtonCollection[Num].H := ThemeCollection.Style.H;
+ if (ThemeCollection.Style.Typ <> TEXTURE_TYPE_COLORIZED) then begin
+ ButtonCollection[Num].SelectColR := ThemeCollection.Style.ColR;
+ ButtonCollection[Num].SelectColG := ThemeCollection.Style.ColG;
+ ButtonCollection[Num].SelectColB := ThemeCollection.Style.ColB;
+ ButtonCollection[Num].DeselectColR := ThemeCollection.Style.DColR;
+ ButtonCollection[Num].DeselectColG := ThemeCollection.Style.DColG;
+ ButtonCollection[Num].DeselectColB := ThemeCollection.Style.DColB;
+ end;
+ ButtonCollection[Num].SelectInt := ThemeCollection.Style.Int;
+ ButtonCollection[Num].DeselectInt := ThemeCollection.Style.DInt;
+ ButtonCollection[Num].Texture.TexX1 := 0;
+ ButtonCollection[Num].Texture.TexY1 := 0;
+ ButtonCollection[Num].Texture.TexX2 := 1;
+ ButtonCollection[Num].Texture.TexY2 := 1;
+ ButtonCollection[Num].SetSelect(false);
+
+ ButtonCollection[Num].Reflection := ThemeCollection.Style.Reflection;
+ ButtonCollection[Num].Reflectionspacing := ThemeCollection.Style.ReflectionSpacing;
+ ButtonCollection[Num].DeSelectReflectionspacing := ThemeCollection.Style.DeSelectReflectionSpacing;
+
+ ButtonCollection[Num].Z := ThemeCollection.Style.Z;
+
+ //Some Things from ButtonFading
+ ButtonCollection[Num].SelectH := ThemeCollection.Style.SelectH;
+ ButtonCollection[Num].SelectW := ThemeCollection.Style.SelectW;
+
+ ButtonCollection[Num].Fade := ThemeCollection.Style.Fade;
+ ButtonCollection[Num].FadeText := ThemeCollection.Style.FadeText;
+ if (ThemeCollection.Style.Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ ButtonCollection[Num].FadeTex := Texture.GetTexture(
+ Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), TEXTURE_TYPE_COLORIZED, TempCol)
+ end else begin
+ ButtonCollection[Num].FadeTex := Texture.GetTexture(
+ Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), ThemeCollection.Style.Typ);
+ end;
+ ButtonCollection[Num].FadeTexPos := ThemeCollection.Style.FadeTexPos;
+
+
+ BTLen := Length(ThemeCollection.Style.Text);
+ for BT := 0 to BTLen-1 do begin
+ AddButtonText(ButtonCollection[Num], ThemeCollection.Style.Text[BT].X, ThemeCollection.Style.Text[BT].Y,
+ ThemeCollection.Style.Text[BT].ColR, ThemeCollection.Style.Text[BT].ColG, ThemeCollection.Style.Text[BT].ColB,
+ ThemeCollection.Style.Text[BT].Font, ThemeCollection.Style.Text[BT].Size, ThemeCollection.Style.Text[BT].Align,
+ ThemeCollection.Style.Text[BT].Text);
+ end;
+end;
+
+function TMenu.AddStatic(ThemeStatic: TThemeStatic): integer;
+begin
+ Result := AddStatic(ThemeStatic.X, ThemeStatic.Y, ThemeStatic.W, ThemeStatic.H, ThemeStatic.Z,
+ ThemeStatic.ColR, ThemeStatic.ColG, ThemeStatic.ColB,
+ ThemeStatic.TexX1, ThemeStatic.TexY1, ThemeStatic.TexX2, ThemeStatic.TexY2,
+ Skin.GetTextureFileName(ThemeStatic.Tex),
+ ThemeStatic.Typ, $FFFFFF, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing);
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; const Name: string): integer;
+begin
+ Result := AddStatic(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN);
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer;
+begin
+ Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, Name, Typ, $FFFFFF);
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer;
+begin
+ Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, Name, Typ, $FFFFFF);
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer;
+var
+ StatNum: integer;
+begin
+ // adds static
+ StatNum := Length(Static);
+ SetLength(Static, StatNum + 1);
+ Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, $FF00FF)); // new skin
+
+ // configures static
+ Static[StatNum].Texture.X := X;
+ Static[StatNum].Texture.Y := Y;
+ Static[StatNum].Texture.W := W;
+ Static[StatNum].Texture.H := H;
+ Static[StatNum].Visible := true;
+ Result := StatNum;
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer;
+begin
+ Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, Name, Typ, Color);
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer;
+begin
+ Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, 0, 0, 1, 1, Name, Typ, Color, False, 0);
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: Boolean; ReflectionSpacing: Real): integer;
+var
+ StatNum: integer;
+begin
+ // adds static
+ StatNum := Length(Static);
+ SetLength(Static, StatNum + 1);
+
+ // colorize hack
+ if (Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ // give encoded color to GetTexture()
+ Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)));
+ end
+ else
+ begin
+ Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, Color)); // new skin
+ end;
+
+ // configures static
+ Static[StatNum].Texture.X := X;
+ Static[StatNum].Texture.Y := Y;
+ Static[StatNum].Texture.W := W;
+ Static[StatNum].Texture.H := H;
+ Static[StatNum].Texture.Z := Z;
+ if (Typ <> TEXTURE_TYPE_COLORIZED) then
+ begin
+ Static[StatNum].Texture.ColR := ColR;
+ Static[StatNum].Texture.ColG := ColG;
+ Static[StatNum].Texture.ColB := ColB;
+ end;
+ Static[StatNum].Texture.TexX1 := TexX1;
+ Static[StatNum].Texture.TexY1 := TexY1;
+ Static[StatNum].Texture.TexX2 := TexX2;
+ Static[StatNum].Texture.TexY2 := TexY2;
+ Static[StatNum].Texture.Alpha := 1;
+ Static[StatNum].Visible := true;
+
+ //ReflectionMod
+ Static[StatNum].Reflection := Reflection;
+ Static[StatNum].ReflectionSpacing := ReflectionSpacing;
+
+ Result := StatNum;
+end;
+
+function TMenu.AddText(ThemeText: TThemeText): integer;
+begin
+ Result := AddText(ThemeText.X, ThemeText.Y, ThemeText.W, ThemeText.Font, ThemeText.Size,
+ ThemeText.ColR, ThemeText.ColG, ThemeText.ColB, ThemeText.Align, ThemeText.Text, ThemeText.Reflection, ThemeText.ReflectionSpacing, ThemeText.Z);
+end;
+
+function TMenu.AddText(X, Y: real; const Text_: string): integer;
+var
+ TextNum: integer;
+begin
+ // adds text
+ TextNum := Length(Text);
+ SetLength(Text, TextNum + 1);
+ Text[TextNum] := TText.Create(X, Y, Text_);
+ Result := TextNum;
+end;
+
+function TMenu.AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer;
+begin
+ Result := AddText(X, Y, 0, Style, Size, ColR, ColG, ColB, 0, Text, false, 0, 0);
+end;
+
+function TMenu.AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: Boolean; ReflectionSpacing_: Real; Z : Real): integer;
+var
+ TextNum: integer;
+begin
+ // adds text
+ TextNum := Length(Text);
+ SetLength(Text, TextNum + 1);
+ Text[TextNum] := TText.Create(X, Y, W, Style, Size, ColR, ColG, ColB, Align, Text_, Reflection_, ReflectionSpacing_, Z);
+ Result := TextNum;
+end;
+
+//Function that Set Length of Button Array in one Step instead of register new Memory for every Button
+Procedure TMenu.SetButtonLength(Length: Cardinal);
+begin
+ if (ButtonPos = -1) AND (Length > 0) then
+ begin
+ //Set Length of Button
+ SetLength(Button, Length);
+
+ //Set ButtonPos to start with 0
+ ButtonPos := 0;
+ end;
+end;
+
+
+// Method to add a button in our TMenu. It returns the assigned ButtonNumber
+function TMenu.AddButton(ThemeButton: TThemeButton): integer;
+var
+ BT: integer;
+ BTLen: integer;
+begin
+ Result := AddButton(ThemeButton.X, ThemeButton.Y, ThemeButton.W, ThemeButton.H,
+ ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB, ThemeButton.Int,
+ ThemeButton.DColR, ThemeButton.DColG, ThemeButton.DColB, ThemeButton.DInt,
+ Skin.GetTextureFileName(ThemeButton.Tex), ThemeButton.Typ,
+ ThemeButton.Reflection, ThemeButton.Reflectionspacing, ThemeButton.DeSelectReflectionspacing);
+
+ Button[Result].Z := ThemeButton.Z;
+
+ //Button Visibility
+ Button[Result].Visible := ThemeButton.Visible;
+
+ //Some Things from ButtonFading
+ Button[Result].SelectH := ThemeButton.SelectH;
+ Button[Result].SelectW := ThemeButton.SelectW;
+
+ Button[Result].Fade := ThemeButton.Fade;
+ Button[Result].FadeText := ThemeButton.FadeText;
+ if (ThemeButton.Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ Button[Result].FadeTex := Texture.GetTexture(
+ Skin.GetTextureFileName(ThemeButton.FadeTex), TEXTURE_TYPE_COLORIZED,
+ RGBFloatToInt(ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB));
+ end
+ else
+ begin
+ Button[Result].FadeTex := Texture.GetTexture(
+ Skin.GetTextureFileName(ThemeButton.FadeTex), ThemeButton.Typ);
+ end;
+
+ Button[Result].FadeTexPos := ThemeButton.FadeTexPos;
+
+ BTLen := Length(ThemeButton.Text);
+ for BT := 0 to BTLen-1 do
+ begin
+ AddButtonText(ThemeButton.Text[BT].X, ThemeButton.Text[BT].Y,
+ ThemeButton.Text[BT].ColR, ThemeButton.Text[BT].ColG, ThemeButton.Text[BT].ColB,
+ ThemeButton.Text[BT].Font, ThemeButton.Text[BT].Size, ThemeButton.Text[BT].Align,
+ ThemeButton.Text[BT].Text);
+ end;
+
+ //BAutton Collection Mod
+ if (ThemeButton.Parent <> 0) then
+ begin
+ //If Collection Exists then Change Interaction to Child Button
+ if (@ButtonCollection[ThemeButton.Parent-1] <> nil) then
+ begin
+ Interactions[High(Interactions)].Typ := iBCollectionChild;
+ Button[Result].Visible := False;
+
+ for BT := 0 to BTLen-1 do
+ Button[Result].Text[BT].Alpha := 0;
+
+ Button[Result].Parent := ThemeButton.Parent;
+ if (ButtonCollection[ThemeButton.Parent-1].Fade) then
+ Button[Result].Texture.Alpha := 0;
+ end;
+ end;
+ Log.BenchmarkEnd(6);
+ Log.LogBenchmark('====> Screen Options32', 6);
+end;
+
+function TMenu.AddButton(X, Y, W, H: real; const Name: String): integer;
+begin
+ Result := AddButton(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN, False);
+end;
+
+function TMenu.AddButton(X, Y, W, H: real; const Name: String; Typ: TTextureType; Reflection: Boolean): integer;
+begin
+ Result := AddButton(X, Y, W, H, 1, 1, 1, 1, 1, 1, 1, 0.5, Name, TEXTURE_TYPE_PLAIN, Reflection, 15, 15);
+end;
+
+function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real;
+ const Name: String; Typ: TTextureType;
+ Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer;
+begin
+ // adds button
+ //SetLength is used once to reduce Memory usement
+ if (ButtonPos <> -1) then
+ begin
+ Result := ButtonPos;
+ Inc(ButtonPos)
+ end
+ else //Old Method -> Reserve new Memory for every Button
+ begin
+ Result := Length(Button);
+ SetLength(Button, Result + 1);
+ end;
+
+ // colorize hack
+ if (Typ = TEXTURE_TYPE_COLORIZED) then
+ begin
+ // give encoded color to GetTexture()
+ Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)),
+ Texture.GetTexture(Name, Typ, RGBFloatToInt(DColR, DColG, DColB)));
+ end
+ else
+ begin
+ Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ));
+ end;
+
+ // configures button
+ Button[Result].X := X;
+ Button[Result].Y := Y;
+ Button[Result].W := W;
+ Button[Result].H := H;
+ if (Typ <> TEXTURE_TYPE_COLORIZED) then
+ begin
+ Button[Result].SelectColR := ColR;
+ Button[Result].SelectColG := ColG;
+ Button[Result].SelectColB := ColB;
+ Button[Result].DeselectColR := DColR;
+ Button[Result].DeselectColG := DColG;
+ Button[Result].DeselectColB := DColB;
+ end;
+ Button[Result].SelectInt := Int;
+ Button[Result].DeselectInt := DInt;
+ Button[Result].Texture.TexX1 := 0;
+ Button[Result].Texture.TexY1 := 0;
+ Button[Result].Texture.TexX2 := 1;
+ Button[Result].Texture.TexY2 := 1;
+ Button[Result].SetSelect(false);
+
+ Button[Result].Reflection := Reflection;
+ Button[Result].Reflectionspacing := ReflectionSpacing;
+ Button[Result].DeSelectReflectionspacing := DeSelectReflectionSpacing;
+
+ //Button Collection Mod
+ Button[Result].Parent := 0;
+
+
+ // adds interaction
+ AddInteraction(iButton, Result);
+ Interaction := 0;
+end;
+
+procedure TMenu.ClearButtons;
+begin
+ Setlength(Button, 0);
+end;
+
+// Method to draw our TMenu and all his child buttons
+function TMenu.DrawBG: boolean;
+begin
+ BackImg.ColR := 1;
+ BackImg.ColG := 1;
+ BackImg.ColB := 1;
+ BackImg.TexX1 := 0;
+ BackImg.TexY1 := 0;
+ BackImg.TexX2 := 1;
+ BackImg.TexY2 := 1;
+
+ if (BackImg.TexNum > 0) then
+ begin
+ BackImg.X := 0;
+ BackImg.Y := 0;
+ BackImg.Z := 0; // todo: eddie: to the opengl experts: please check this! On the mac z is not initialized???
+ BackImg.W := 800;
+ BackImg.H := 600;
+ DrawTexture(BackImg);
+ end
+ else if (VideoPlayback <> nil) then
+ begin
+ VideoPlayback.GetFrame(VideoBGTimer.GetTime());
+ // FIXME: why do we draw on screen 2? Seems to be wrong.
+ VideoPlayback.DrawGL(2);
+ end;
+
+ Result := true;
+end;
+
+function TMenu.DrawFG: boolean;
+var
+ J: Integer;
+begin
+ // We don't forget about newly implemented static for nice skin ...
+ for J := 0 to Length(Static) - 1 do
+ Static[J].Draw;
+
+ // ... and slightly implemented menutext unit
+ for J := 0 to Length(Text) - 1 do
+ Text[J].Draw;
+
+ // Draw all ButtonCollections
+ for J := 0 to High(ButtonCollection) do
+ ButtonCollection[J].Draw;
+
+ // Second, we draw all of our buttons
+ for J := 0 to Length(Button) - 1 do
+ Button[J].Draw;
+
+ for J := 0 to Length(SelectsS) - 1 do
+ SelectsS[J].Draw;
+
+ // Third, we draw all our widgets
+ // for J := 0 to Length(WidgetsSrc) - 1 do
+ // SDL_BlitSurface(WidgetsSrc[J], nil, ParentBackBuf, WidgetsRect[J]);
+ Result := True;
+end;
+
+function TMenu.Draw: boolean;
+begin
+ DrawBG;
+ DrawFG;
+ Result := true;
+end;
+
+{
+function TMenu.GetNextScreen(): PMenu;
+begin
+ Result := NextScreen;
+end;
+}
+
+{
+function TMenu.AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
+var
+ WidgetNum : Int16;
+begin
+ if (Assigned(WidgetSrc)) then
+ begin
+ WidgetNum := Length(WidgetsSrc);
+
+ SetLength(WidgetsSrc, WidgetNum + 1);
+ SetLength(WidgetsRect, WidgetNum + 1);
+
+ WidgetsSrc[WidgetNum] := WidgetSrc;
+ WidgetsRect[WidgetNum] := new(PSDL_Rect);
+ WidgetsRect[WidgetNum]^.x := X;
+ WidgetsRect[WidgetNum]^.y := Y;
+ WidgetsRect[WidgetNum]^.w := WidgetSrc^.w;
+ WidgetsRect[WidgetNum]^.h := WidgetSrc^.h;
+
+ Result := WidgetNum;
+ end
+ else
+ Result := -1;
+end;
+}
+
+{
+procedure TMenu.ClearWidgets(MinNumber : Int16);
+var
+ J : Int16;
+begin
+ for J := MinNumber to (Length(WidgetsSrc) - 1) do
+ begin
+ SDL_FreeSurface(WidgetsSrc[J]);
+ dispose(WidgetsRect[J]);
+ end;
+
+ SetLength(WidgetsSrc, MinNumber);
+ SetLength(WidgetsRect, MinNumber);
+end;
+}
+
+function TMenu.IsSelectable(Int: Cardinal): Boolean;
+begin
+ Result := True;
+ case Interactions[Int].Typ of
+ //Button
+ iButton: Result := Button[Interactions[Int].Num].Visible and Button[Interactions[Int].Num].Selectable;
+
+ //Select Slide
+ iSelectS: Result := SelectsS[Interactions[Int].Num].Visible;
+
+ //ButtonCollection Child
+ iBCollectionChild:
+ Result := (ButtonCollection[Button[Interactions[Int].Num].Parent - 1].FirstChild - 1 = Int) and ((Interactions[Interaction].Typ <> iBCollectionChild) or (Button[Interactions[Interaction].Num].Parent <> Button[Interactions[Int].Num].Parent));
+ end;
+end;
+
+// implemented for the sake of usablility
+// [curser down] picks the button left to the actual atm
+// this behaviour doesn't make sense for two rows of buttons
+procedure TMenu.InteractPrevRow;
+var
+ Int: integer;
+begin
+// these two procedures just make sense for at least 5 buttons, because we
+// usually start a second row when there are more than 4 buttons
+ Int := Interaction;
+
+ Int := Int - ceil(Length(Interactions) / 2);
+
+ //Set Interaction
+ if ((Int < 0) or (Int > Length(Interactions) - 1))
+ then Int := Interaction //nonvalid button, keep current one
+ else Interaction := Int; //select row above
+end;
+
+procedure TMenu.InteractNextRow;
+var
+ Int: integer;
+begin
+ Int := Interaction;
+
+ Int := Int + ceil(Length(Interactions) / 2);
+
+ //Set Interaction
+ if ((Int < 0) or (Int > Length(Interactions) - 1))
+ then Int := Interaction //nonvalid button, keep current one
+ else Interaction := Int; //select row above
+end;
+
+procedure TMenu.InteractNext;
+var
+ Int: integer;
+begin
+ Int := Interaction;
+
+ // change interaction as long as it's needed
+ repeat
+ Int := (Int + 1) mod Length(Interactions);
+
+ //If no Interaction is Selectable Simply Select Next
+ if (Int = Interaction) then Break;
+
+ until IsSelectable(Int);
+
+ //Set Interaction
+ Interaction := Int;
+end;
+
+procedure TMenu.InteractPrev;
+var
+ Int: integer;
+begin
+ Int := Interaction;
+
+ // change interaction as long as it's needed
+ repeat
+ Int := Int - 1;
+ if Int = -1 then Int := High(Interactions);
+
+ //If no Interaction is Selectable Simply Select Next
+ if (Int = Interaction) then Break;
+ until IsSelectable(Int);
+
+ //Set Interaction
+ Interaction := Int
+end;
+
+
+procedure TMenu.InteractCustom(CustomSwitch: integer);
+{ needed only for below
+var
+ Num: integer;
+ Typ: integer;
+ Again: boolean;
+}
+begin
+ //Code Commented atm, because it needs to be Rewritten
+ //it doesn't work with Button Collections
+ {then begin
+ CustomSwitch:= CustomSwitch*(-1);
+ Again := true;
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := SelInteraction - CustomSwitch;
+ if Num = -1 then Num := High(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+ end
+ else if num>0 then begin
+ Again := true;
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := (Interaction + CustomSwitch) Mod Length(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+ end }
+end;
+
+
+procedure TMenu.FadeTo(Screen: PMenu);
+begin
+ Display.Fade := 0;
+ Display.NextScreen := Screen;
+end;
+
+procedure TMenu.FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream);
+begin
+ FadeTo( Screen );
+ AudioPlayback.PlaySound( aSound );
+end;
+
+
+//popup hack
+procedure TMenu.CheckFadeTo(Screen: PMenu; msg: String);
+begin
+ Display.Fade := 0;
+ Display.NextScreenWithCheck := Screen;
+ Display.CheckOK:=False;
+ ScreenPopupCheck.ShowPopup(msg);
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; const AddText: string);
+begin
+ AddButtonText(AddX, AddY, 1, 1, 1, AddText);
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string);
+var
+ Il: integer;
+begin
+ with Button[High(Button)] do begin
+ Il := Length(Text);
+ SetLength(Text, Il+1);
+ Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
+ Text[Il].ColR := ColR;
+ Text[Il].ColG := ColG;
+ Text[Il].ColB := ColB;
+ Text[Il].Int := 1;//0.5;
+ end;
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string);
+var
+ Il: integer;
+begin
+ with Button[High(Button)] do begin
+ Il := Length(Text);
+ SetLength(Text, Il+1);
+ Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
+ Text[Il].ColR := ColR;
+ Text[Il].ColG := ColG;
+ Text[Il].ColB := ColB;
+ Text[Il].Int := 1;//0.5;
+ Text[Il].Style := Font;
+ Text[Il].Size := Size;
+ Text[Il].Align := Align;
+ end;
+end;
+
+procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string);
+var
+ Il: integer;
+begin
+ with CustomButton do begin
+ Il := Length(Text);
+ SetLength(Text, Il+1);
+ Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
+ Text[Il].ColR := ColR;
+ Text[Il].ColG := ColG;
+ Text[Il].ColB := ColB;
+ Text[Il].Int := 1;//0.5;
+ Text[Il].Style := Font;
+ Text[Il].Size := Size;
+ Text[Il].Align := Align;
+ end;
+end;
+
+
+function TMenu.AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer;
+var
+ SO: integer;
+begin
+ Result := AddSelectSlide(ThemeSelectS.X, ThemeSelectS.Y, ThemeSelectS.W, ThemeSelectS.H, ThemeSelectS.SkipX, ThemeSelectS.SBGW,
+ ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeSelectS.Int,
+ ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeSelectS.DInt,
+ ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeSelectS.TInt,
+ ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeSelectS.TDInt,
+ ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeSelectS.SBGInt,
+ ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeSelectS.SBGDInt,
+ ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeSelectS.STInt,
+ ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeSelectS.STDInt,
+ Skin.GetTextureFileName(ThemeSelectS.Tex), TEXTURE_TYPE_COLORIZED,
+ Skin.GetTextureFileName(ThemeSelectS.TexSBG), TEXTURE_TYPE_COLORIZED,
+ ThemeSelectS.Text, Data);
+ for SO := 0 to High(Values) do
+ AddSelectSlideOption(Values[SO]);
+
+ SelectsS[High(SelectsS)].Text.Size := ThemeSelectS.TextSize;
+
+ SelectsS[High(SelectsS)].Texture.Z := ThemeSelectS.Z;
+ SelectsS[High(SelectsS)].TextureSBG.Z := ThemeSelectS.Z;
+
+ //Generate Lines
+ SelectsS[High(SelectsS)].GenLines;
+
+ SelectsS[High(SelectsS)].SelectedOption := SelectsS[High(SelectsS)].SelectOptInt; // refresh
+end;
+
+function TMenu.AddSelectSlide(X, Y, W, H, SkipX, SBGW, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ const Name: String; Typ: TTextureType; const SBGName: String; SBGTyp: TTextureType;
+ const Caption: string; var Data: integer): integer;
+var
+ S: integer;
+ I: integer;
+begin
+ S := Length(SelectsS);
+ SetLength(SelectsS, S + 1);
+ SelectsS[S] := TSelectSlide.Create;
+
+ if (Typ = TEXTURE_TYPE_COLORIZED) then
+ SelectsS[S].Texture := Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB))
+ else
+ SelectsS[S].Texture := Texture.GetTexture(Name, Typ);
+ SelectsS[S].X := X;
+ SelectsS[S].Y := Y;
+ SelectsS[S].W := W;
+ SelectsS[S].H := H;
+
+ SelectsS[S].ColR := ColR;
+ SelectsS[S].ColG := ColG;
+ SelectsS[S].ColB := ColB;
+ SelectsS[S].Int := Int;
+ SelectsS[S].DColR := DColR;
+ SelectsS[S].DColG := DColG;
+ SelectsS[S].DColB := DColB;
+ SelectsS[S].DInt := DInt;
+
+ if (SBGTyp = TEXTURE_TYPE_COLORIZED) then
+ SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGColR, SBGColG, SBGColB))
+ else
+ SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp);
+ SelectsS[S].TextureSBG.X := X + W + SkipX;
+ SelectsS[S].TextureSBG.Y := Y;
+ //SelectsS[S].TextureSBG.W := 450;
+ SelectsS[S].SBGW := SBGW;
+ SelectsS[S].TextureSBG.H := H;
+ SelectsS[S].SBGColR := SBGColR;
+ SelectsS[S].SBGColG := SBGColG;
+ SelectsS[S].SBGColB := SBGColB;
+ SelectsS[S].SBGInt := SBGInt;
+ SelectsS[S].SBGDColR := SBGDColR;
+ SelectsS[S].SBGDColG := SBGDColG;
+ SelectsS[S].SBGDColB := SBGDColB;
+ SelectsS[S].SBGDInt := SBGDInt;
+
+ SelectsS[S].Text.X := X + 20;
+ SelectsS[S].Text.Y := Y + (SelectsS[S].TextureSBG.H / 2) - 15;
+ SelectsS[S].Text.Text := Caption;
+ SelectsS[S].Text.Size := 10;
+ SelectsS[S].Text.Visible := true;
+ SelectsS[S].TColR := TColR;
+ SelectsS[S].TColG := TColG;
+ SelectsS[S].TColB := TColB;
+ SelectsS[S].TInt := TInt;
+ SelectsS[S].TDColR := TDColR;
+ SelectsS[S].TDColG := TDColG;
+ SelectsS[S].TDColB := TDColB;
+ SelectsS[S].TDInt := TDInt;
+
+ SelectsS[S].STColR := STColR;
+ SelectsS[S].STColG := STColG;
+ SelectsS[S].STColB := STColB;
+ SelectsS[S].STInt := STInt;
+ SelectsS[S].STDColR := STDColR;
+ SelectsS[S].STDColG := STDColG;
+ SelectsS[S].STDColB := STDColB;
+ SelectsS[S].STDInt := STDInt;
+
+ // new
+ SelectsS[S].Texture.TexX1 := 0;
+ SelectsS[S].Texture.TexY1 := 0;
+ SelectsS[S].Texture.TexX2 := 1;
+ SelectsS[S].Texture.TexY2 := 1;
+ SelectsS[S].TextureSBG.TexX1 := 0;
+ SelectsS[S].TextureSBG.TexY1 := 0;
+ SelectsS[S].TextureSBG.TexX2 := 1;
+ SelectsS[S].TextureSBG.TexY2 := 1;
+
+ // Sets Data to copy the value of selectops to global value;
+ SelectsS[S].PData := @Data;
+ // Configures Select options
+ {//SelectsS[S].TextOpt[0].Text := IntToStr(I+1);
+ SelectsS[S].TextOpt[0].Size := 10;
+ SelectsS[S].TextOpt[0].Align := 1;
+
+ SelectsS[S].TextOpt[0].ColR := SelectsS[S].STDColR;
+ SelectsS[S].TextOpt[0].ColG := SelectsS[S].STDColG;
+ SelectsS[S].TextOpt[0].ColB := SelectsS[S].STDColB;
+ SelectsS[S].TextOpt[0].Int := SelectsS[S].STDInt;
+ SelectsS[S].TextOpt[0].Visible := true; }
+
+ // Sets default value of selectopt from Data;
+ SelectsS[S].SelectedOption := Data;
+
+ // Disables default selection
+ SelectsS[S].SetSelect(false);
+
+ {// Configures 3 select options
+ for I := 0 to 2 do begin
+ SelectsS[S].TextOpt[I].X := SelectsS[S].TextureSBG.X + 20 + (50 + 20) + (150 - 20) * I;
+ SelectsS[S].TextOpt[I].Y := SelectsS[S].TextureSBG.Y + 20;
+ SelectsS[S].TextOpt[I].Text := IntToStr(I+1);
+ SelectsS[S].TextOpt[I].Size := 10;
+ SelectsS[S].TextOpt[I].Align := 1;
+
+
+ SelectsS[S].TextOpt[I].ColR := SelectsS[S].STDColR;
+ SelectsS[S].TextOpt[I].ColG := SelectsS[S].STDColG;
+ SelectsS[S].TextOpt[I].ColB := SelectsS[S].STDColB;
+ SelectsS[S].TextOpt[I].Int := SelectsS[S].STDInt;
+ SelectsS[S].TextOpt[I].Visible := true;
+ end;}
+
+
+ // adds interaction
+ AddInteraction(iSelectS, S);
+ Result := S;
+end;
+
+procedure TMenu.AddSelectSlideOption(const AddText: string);
+begin
+ AddSelectSlideOption(High(SelectsS), AddText);
+end;
+
+procedure TMenu.AddSelectSlideOption(SelectNo: Cardinal; const AddText: string);
+var
+ SO: integer;
+begin
+ SO := Length(SelectsS[SelectNo].TextOptT);
+
+ SetLength(SelectsS[SelectNo].TextOptT, SO + 1);
+ SelectsS[SelectNo].TextOptT[SO] := AddText;
+
+ //SelectsS[S].SelectedOption := SelectsS[S].SelectOptInt; // refresh
+
+ //if SO = Selects[S].PData^ then Selects[S].SelectedOption := SO;
+end;
+
+procedure TMenu.UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
+var
+ SO: integer;
+begin
+ SetLength(SelectsS[SelectNum].TextOptT, 0);
+ for SO := 0 to High(Values) do
+ AddSelectSlideOption(SelectNum, Values[SO]);
+
+ SelectsS[SelectNum].GenLines;
+
+// SelectsS[SelectNum].SelectedOption := SelectsS[SelectNum].SelectOptInt; // refresh
+// SelectS[SelectNum].SetSelectOpt(Data);
+// SelectS[SelectNum].SelectedOption := 0;//Data;
+
+// Log.LogError(IntToStr(High(SelectsS[SelectNum].TextOptT)));
+// if 0 <= High(SelectsS[SelectNum].TextOptT) then
+
+ SelectsS[SelectNum].PData := @Data;
+ SelectsS[SelectNum].SelectedOption := Data;
+end;
+
+procedure TMenu.InteractInc;
+var
+ Num: integer;
+ Value: integer;
+begin
+ case Interactions[Interaction].Typ of
+ iSelectS: begin
+ Num := Interactions[Interaction].Num;
+ Value := SelectsS[Num].SelectedOption;
+// Value := (Value + 1) Mod (Length(SelectsS[Num].TextOptT));
+
+ // limit
+ Value := Value + 1;
+ if Value <= High(SelectsS[Num].TextOptT) then
+ SelectsS[Num].SelectedOption := Value;
+ end;
+ //Button Collection Mod
+ iBCollectionChild:
+ begin
+
+ //Select Next Button in Collection
+ For Num := 1 to High(Button) do
+ begin
+ Value := (Interaction + Num) Mod Length(Button);
+ if Value = 0 then
+ begin
+ InteractNext;
+ Break;
+ end;
+ if (Button[Value].Parent = Button[Interaction].Parent) then
+ begin
+ Interaction := Value;
+ Break;
+ end;
+ end;
+ end;
+ //interact Next if there is Nothing to Change
+ else InteractNext;
+ end;
+end;
+
+procedure TMenu.InteractDec;
+var
+ Num: integer;
+ Value: integer;
+begin
+ case Interactions[Interaction].Typ of
+ iSelectS: begin
+ Num := Interactions[Interaction].Num;
+ Value := SelectsS[Num].SelectedOption;
+ Value := Value - 1;
+// if Value = -1 then
+// Value := High(SelectsS[Num].TextOptT);
+
+ if Value >= 0 then
+ SelectsS[Num].SelectedOption := Value;
+ end;
+ //Button Collection Mod
+ iBCollectionChild:
+ begin
+ //Select Prev Button in Collection
+ For Num := High(Button) downto 1 do
+ begin
+ Value := (Interaction + Num) Mod Length(Button);
+ if Value = High(Button) then
+ begin
+ InteractPrev;
+ Break;
+ end;
+ if (Button[Value].Parent = Button[Interaction].Parent) then
+ begin
+ Interaction := Value;
+ Break;
+ end;
+ end;
+ end;
+ //interact Prev if there is Nothing to Change
+ else
+ begin
+ InteractPrev;
+ //If ButtonCollection with more than 1 Entry then Select Last Entry
+ if (Button[Interactions[Interaction].Num].Parent <> 0) AND (ButtonCollection[Button[Interactions[Interaction].Num].Parent-1].CountChilds > 1) then
+ begin
+ //Select Last Child
+ For Num := High(Button) downto 1 do
+ begin
+ Value := (Interaction + Num) Mod Length(Button);
+ if (Button[Value].Parent = Button[Interaction].Parent) then
+ begin
+ Interaction := Value;
+ Break;
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TMenu.AddBox(X, Y, W, H: real);
+begin
+ AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+end;
+
+procedure TMenu.onShow;
+begin
+ // FIXME: this needs some work. First, there should be a variable like
+ // VideoBackground so we can check whether a video-background is enabled or not.
+ // Second, a video should be stopped if the screen is hidden, but the Video.Stop()
+ // method is not implemented by now. This is necessary for theme-switching too.
+ // At the moment videos cannot be turned off without restarting USDX.
+
+ // check if a background texture was found
+ if (BackImg.TexNum = 0) then
+ begin
+ // try to open an animated background
+ // Note: newer versions of ffmpeg are able to open images like jpeg
+ // so do not pass an image's filename to VideoPlayback.Open()
+ if fileexists( fFileName ) then
+ begin
+ if VideoPlayback.Open( fFileName ) then
+ begin
+ VideoBGTimer.SetTime(0);
+ VideoPlayback.Play;
+ end;
+ end;
+ end;
+end;
+
+procedure TMenu.onShowFinish;
+begin
+ // nothing
+end;
+
+(*
+ * Wrapper for WideUpperCase. Needed because some plattforms have problems with
+ * unicode support.
+ *)
+function TMenu.WideCharUpperCase(wchar: WideChar) : WideString;
+begin
+ // On Linux and MacOSX the cwstring unit is necessary for Unicode function-calls.
+ // Otherwise you will get an EIntOverflow exception (thrown by unimplementedwidestring()).
+ // The Unicode manager cwstring does not work with MacOSX at the moment because
+ // of missing references to iconv. So we have to use Ansi... for the moment.
+
+ {$IFNDEF DARWIN}
+ // The FPC implementation of WideUpperCase returns nil if wchar is #0 (e.g. if an arrow key is pressed)
+ if (wchar <> #0) then
+ Result := WideUpperCase(wchar)
+ else
+ Result := #0;
+ {$ELSE}
+ Result := AnsiUpperCase(wchar)
+ {$ENDIF}
+end;
+
+(*
+ * Wrapper for WideUpperCase. Needed because some plattforms have problems with
+ * unicode support.
+ *)
+function TMenu.WideStringUpperCase(wstring: WideString) : WideString;
+begin
+ {$IFNDEF DARWIN}
+ Result := WideUpperCase(wstring)
+ {$ELSE}
+ Result := AnsiUpperCase(wstring);
+ {$ENDIF}
+end;
+
+procedure TMenu.onHide;
+begin
+ // nothing
+end;
+
+function TMenu.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ // nothing
+ Result := true;
+end;
+
+procedure TMenu.SetAnimationProgress(Progress: real);
+begin
+ // nothing
+end;
+
+end.
+
diff --git a/src/Menu/UMenuButton.pas b/src/Menu/UMenuButton.pas
new file mode 100644
index 00000000..60b92b9f
--- /dev/null
+++ b/src/Menu/UMenuButton.pas
@@ -0,0 +1,564 @@
+unit UMenuButton;
+
+interface
+
+{$I switches.inc}
+
+uses TextGL, UTexture, gl, UMenuText,SDL;
+
+type
+ CButton = class of TButton;
+
+ TButton = class
+ protected
+ SelectBool: Boolean;
+
+ FadeProgress: Real;
+ FadeLastTick: Cardinal;
+
+ DeSelectW,
+ DeSelectH,
+ PosX,
+ PosY: Real;
+
+ constructor Create(); overload;
+
+ public
+ Text: Array of TText;
+ Texture: TTexture; // Button Screen position and size
+ Texture2: TTexture; // second texture only used for fading full resolution covers
+
+ Colorized: Boolean;
+ DeSelectTexture: TTexture; // texture for colorized hack
+
+ FadeTex: TTexture; //Texture for beautiful fading
+ FadeTexPos: byte; //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right)
+
+ DeselectType: integer; // not used yet
+ Visible: boolean;
+
+ Reflection: boolean;
+ Reflectionspacing,
+ DeSelectReflectionspacing: Real;
+
+ Fade,
+ FadeText: Boolean;
+
+ Selectable: boolean;
+
+ //Number of the Parent Collection, 0 if in no Collection
+ Parent: Byte;
+
+ SelectColR,
+ SelectColG,
+ SelectColB,
+ SelectInt,
+ SelectTInt: real;
+ //Fade Mod
+ SelectW: real;
+ SelectH: real;
+
+ DeselectColR,
+ DeselectColG,
+ DeselectColB,
+ DeselectInt,
+ DeselectTInt: real;
+
+ procedure SetY(Value: real);
+ procedure SetX(Value: real);
+ procedure SetW(Value: real);
+ procedure SetH(Value: real);
+
+ procedure SetSelect(Value: Boolean); virtual;
+ property X: real read PosX write SetX;
+ property Y: real read PosY write SetY;
+ property Z: real read Texture.z write Texture.z;
+ property W: real read DeSelectW write SetW;
+ property H: real read DeSelectH write SetH;
+ property Selected: Boolean read SelectBool write SetSelect;
+
+ procedure Draw; virtual;
+
+ constructor Create(Textura: TTexture); overload;
+ constructor Create(Textura, DSTexture: TTexture); overload;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses SysUtils,
+ UDrawTexture;
+
+procedure TButton.SetX(Value: real);
+{var
+ dx: real;
+ T: integer; // text}
+begin
+ {dY := Value - Texture.y;
+
+ Texture.X := Value;
+
+ for T := 0 to High(Text) do
+ Text[T].X := Text[T].X + dY;}
+
+ PosX := Value;
+ if (FadeTex.TexNum = 0) then
+ Texture.X := Value;
+
+end;
+
+procedure TButton.SetY(Value: real);
+{var
+ dY: real;
+ T: integer; // text}
+begin
+ {dY := Value - PosY;
+
+
+ for T := 0 to High(Text) do
+ Text[T].Y := Text[T].Y + dY;}
+
+ PosY := Value;
+ if (FadeTex.TexNum = 0) then
+ Texture.y := Value;
+end;
+
+procedure TButton.SetW(Value: real);
+begin
+ if SelectW = DeSelectW then
+ SelectW := Value;
+
+ DeSelectW := Value;
+
+ if Not Fade then
+ begin
+ if SelectBool then
+ Texture.W := SelectW
+ else
+ Texture.W := DeSelectW;
+ end;
+end;
+
+procedure TButton.SetH(Value: real);
+begin
+ if SelectH = DeSelectH then
+ SelectH := Value;
+
+ DeSelectH := Value;
+
+ if Not Fade then
+ begin
+ if SelectBool then
+ Texture.H := SelectH
+ else
+ Texture.H := DeSelectH;
+ end;
+end;
+
+procedure TButton.SetSelect(Value : Boolean);
+var
+ T: integer;
+begin
+ SelectBool := Value;
+
+ if (Value) then
+ begin
+ Texture.ColR := SelectColR;
+ Texture.ColG := SelectColG;
+ Texture.ColB := SelectColB;
+ Texture.Int := SelectInt;
+
+ Texture2.ColR := SelectColR;
+ Texture2.ColG := SelectColG;
+ Texture2.ColB := SelectColB;
+ Texture2.Int := SelectInt;
+
+ for T := 0 to High(Text) do
+ Text[T].Int := SelectTInt;
+
+ //Fade Mod
+ if Fade then
+ begin
+ if (FadeProgress <= 0) then
+ FadeProgress := 0.125;
+ end
+ else
+ begin
+ Texture.W := SelectW;
+ Texture.H := SelectH;
+ end;
+ end
+ else
+ begin
+ Texture.ColR := DeselectColR;
+ Texture.ColG := DeselectColG;
+ Texture.ColB := DeselectColB;
+ Texture.Int := DeselectInt;
+
+ Texture2.ColR := DeselectColR;
+ Texture2.ColG := DeselectColG;
+ Texture2.ColB := DeselectColB;
+ Texture2.Int := DeselectInt;
+
+ for T := 0 to High(Text) do
+ Text[T].Int := DeselectTInt;
+
+ //Fade Mod
+ if Fade then
+ begin
+ if (FadeProgress >= 1) then
+ FadeProgress := 0.875;
+ end
+ else
+ begin
+ Texture.W := DeSelectW;
+ Texture.H := DeSelectH;
+ end;
+ end;
+end;
+
+constructor TButton.Create();
+begin
+ inherited Create;
+ // We initialize all to 0, nil or false
+ Visible := true;
+ SelectBool := false;
+ DeselectType := 0;
+ Selectable := true;
+ Reflection := false;
+ Colorized := false;
+
+ SelectColR := 1;
+ SelectColG := 1;
+ SelectColB := 1;
+ SelectInt := 1;
+ SelectTInt := 1;
+
+ DeselectColR := 1;
+ DeselectColG := 1;
+ DeselectColB := 1;
+ DeselectInt := 0.5;
+ DeselectTInt := 1;
+
+ Fade := false;
+ FadeTex.TexNum := 0;
+ FadeProgress := 0;
+ FadeText := false;
+ SelectW := DeSelectW;
+ SelectH := DeSelectH;
+
+ PosX := 0;
+ PosY := 0;
+
+ Parent := 0;
+end;
+
+// ***** Public methods ****** //
+
+procedure TButton.Draw;
+var
+ T: integer;
+ Tick: Cardinal;
+ Spacing: Real;
+begin
+ if Visible then
+ begin
+ //Fade Mod
+ T:=0;
+ if Fade then
+ begin
+ if (FadeProgress < 1) and (FadeProgress > 0) then
+ begin
+ Tick := SDL_GetTicks() div 16;
+ if (Tick <> FadeLastTick) then
+ begin
+ FadeLastTick := Tick;
+
+ if SelectBool then
+ FadeProgress := FadeProgress + 0.125
+ else
+ FadeProgress := FadeProgress - 0.125;
+
+ if (FadeText) then
+ begin
+ For T := 0 to high(Text) do
+ begin
+ Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress;
+ Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress;
+ end;
+ end;
+
+ end;
+ end;
+
+ //Method without Fade Texture
+ if (FadeTex.TexNum = 0) then
+ begin
+ Texture.W := DeSelectW + (SelectW - DeSelectW) * FadeProgress;
+ Texture.H := DeSelectH + (SelectH - DeSelectH) * FadeProgress;
+ DeSelectTexture.W := Texture.W;
+ DeSelectTexture.H := Texture.H;
+ end
+ else //method with Fade Texture
+ begin
+ Texture.W := DeSelectW;
+ Texture.H := DeSelectH;
+ DeSelectTexture.W := Texture.W;
+ DeSelectTexture.H := Texture.H;
+
+ FadeTex.ColR := Texture.ColR;
+ FadeTex.ColG := Texture.ColG;
+ FadeTex.ColB := Texture.ColB;
+ FadeTex.Int := Texture.Int;
+
+ FadeTex.Z := Texture.Z;
+
+ FadeTex.Alpha := Texture.Alpha;
+ FadeTex.TexX1 := 0;
+ FadeTex.TexX2 := 1;
+ FadeTex.TexY1 := 0;
+ FadeTex.TexY2 := 1;
+
+ Case FadeTexPos of
+ 0: //FadeTex on Top
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress;
+ DeSelectTexture.X := Texture.X;
+ DeSelectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY;
+ FadeTex.W := Texture.W;
+ FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
+ FadeTex.ScaleW := Texture.ScaleW;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexY2 := 0.9;
+ end;
+ 1: //FadeTex on Left
+ begin
+ //Standard Texture
+ Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress;
+ Texture.Y := PosY;
+ DeSelectTexture.X := Texture.X;
+ DeSelectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY;
+ FadeTex.H := Texture.H;
+ FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.ScaleH := Texture.ScaleH;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexX2 := 0.9;
+ end;
+ 2: //FadeTex on Bottom
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY;
+ DeSelectTexture.X := Texture.X;
+ DeSelectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY + (SelectH - DeSelectH) * FadeProgress;;
+ FadeTex.W := Texture.W;
+ FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
+ FadeTex.ScaleW := Texture.ScaleW;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexY1 := 0.1;
+ end;
+ 3: //FadeTex on Right
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY;
+ DeSelectTexture.X := Texture.X;
+ DeSelectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.Y := PosY;
+ FadeTex.H := Texture.H;
+ FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.ScaleH := Texture.ScaleH;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexX1 := 0.1;
+ end;
+ end;
+ end;
+ end
+ else if (FadeText) then
+ begin
+ Text[T].MoveX := (SelectW - DeSelectW);
+ Text[T].MoveY := (SelectH - DeSelectH);
+ end;
+
+ if SelectBool or (FadeProgress > 0) or not Colorized then
+ DrawTexture(Texture)
+ else
+ begin
+ DeSelectTexture.X := Texture.X;
+ DeSelectTexture.Y := Texture.Y;
+ DeSelectTexture.H := Texture.H;
+ DeSelectTexture.W := Texture.W;
+ DrawTexture(DeSelectTexture);
+ end;
+
+ //Draw FadeTex
+ if (FadeTex.TexNum > 0) then
+ DrawTexture(FadeTex);
+
+ if Texture2.Alpha > 0 then
+ begin
+ Texture2.ScaleW := Texture.ScaleW;
+ Texture2.ScaleH := Texture.ScaleH;
+
+ Texture2.X := Texture.X;
+ Texture2.Y := Texture.Y;
+ Texture2.W := Texture.W;
+ Texture2.H := Texture.H;
+
+ Texture2.ColR := Texture.ColR;
+ Texture2.ColG := Texture.ColG;
+ Texture2.ColB := Texture.ColB;
+ Texture2.Int := Texture.Int;
+
+ Texture2.Z := Texture.Z;
+
+ DrawTexture(Texture2);
+ end;
+
+ //Reflection Mod
+ if (Reflection) then // Draw Reflections
+ begin
+ if (FadeProgress <> 0) AND (FadeProgress <> 1) then
+ begin
+ Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress;
+ end
+ else if SelectBool then
+ Spacing := Reflectionspacing
+ else
+ Spacing := DeSelectReflectionspacing;
+
+ if SelectBool or not Colorized then
+ with Texture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ //Draw
+ glBegin(GL_QUADS);//Top Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH);
+ glVertex3f(x, y+h*scaleH+ Spacing, z);
+
+ //Bottom Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
+ glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+
+ //Bottom Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
+ glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+ //Top Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH);
+ glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ end else
+ with DeSelectTexture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ //Draw
+ glBegin(GL_QUADS);//Top Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH);
+ glVertex3f(x, y+h*scaleH+ Spacing, z);
+
+ //Bottom Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
+ glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+ //Bottom Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
+ glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+ //Top Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH);
+ glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ end;
+ end;
+
+ for T := 0 to High(Text) do begin
+ Text[T].Draw;
+ end;
+ end;
+end;
+
+
+destructor TButton.Destroy;
+begin
+ inherited;
+end;
+
+constructor TButton.Create(Textura: TTexture);
+begin
+ Create();
+ Texture := Textura;
+ DeSelectTexture := Textura;
+ Texture.ColR := 0;
+ Texture.ColG := 0.5;
+ Texture.ColB := 0;
+ Texture.Int := 1;
+ Colorized := False;
+end;
+
+// Button has the texture-type "colorized"
+// Two textures are generated, one with Col the other one with DCol
+// Check UMenu.pas line 680 to see the call ( AddButton() )
+constructor TButton.Create(Textura, DSTexture: TTexture);
+begin
+ Create();
+ Texture := Textura;
+ DeSelectTexture := DSTexture;
+ Texture.ColR := 1;
+ Texture.ColG := 1;
+ Texture.ColB := 1;
+ Texture.Int := 1;
+ Colorized := True;
+end;
+
+end.
diff --git a/src/Menu/UMenuButtonCollection.pas b/src/Menu/UMenuButtonCollection.pas
new file mode 100644
index 00000000..c700c812
--- /dev/null
+++ b/src/Menu/UMenuButtonCollection.pas
@@ -0,0 +1,71 @@
+unit UMenuButtonCollection;
+
+interface
+
+{$I switches.inc}
+
+uses UMenuButton;
+
+type
+ //----------------
+ //TButtonCollection
+ //No Extra Attributes or Functions ATM
+ //----------------
+ AButton = Array of TButton;
+ PAButton = ^AButton;
+ TButtonCollection = class(TButton)
+ //num of the First Button, that can be Selected
+ FirstChild: Byte;
+ CountChilds: Byte;
+
+ ScreenButton: PAButton;
+
+ procedure SetSelect(Value : Boolean); override;
+ procedure Draw; override;
+ end;
+
+implementation
+
+procedure TButtonCollection.SetSelect(Value : Boolean);
+var I: Integer;
+begin
+ inherited;
+
+ //Set Visible for Every Button that is a Child of this ButtonCollection
+ if (Not Fade) then
+ For I := 0 to High(ScreenButton^) do
+ if (ScreenButton^[I].Parent = Parent) then
+ ScreenButton^[I].Visible := Value;
+end;
+
+procedure TButtonCollection.Draw;
+var I, J: Integer;
+begin
+ inherited;
+ //If fading is activated, Fade Child Buttons
+ if (Fade) then
+ begin
+ For I := 0 to High(ScreenButton^) do
+ if (ScreenButton^[I].Parent = Parent) then
+ begin
+ if (FadeProgress < 0.5) then
+ begin
+ ScreenButton^[I].Visible := SelectBool;
+
+ For J := 0 to High(ScreenButton^[I].Text) do
+ ScreenButton^[I].Text[J].Visible := SelectBool;
+ end
+ else
+ begin
+ ScreenButton^[I].Texture.Alpha := (FadeProgress-0.666)*3;
+
+ For J := 0 to High(ScreenButton^[I].Text) do
+ ScreenButton^[I].Text[J].Alpha := (FadeProgress-0.666)*3;
+ end;
+ end;
+ end;
+end;
+
+
+
+end.
diff --git a/src/Menu/UMenuInteract.pas b/src/Menu/UMenuInteract.pas
new file mode 100644
index 00000000..e0b4fa11
--- /dev/null
+++ b/src/Menu/UMenuInteract.pas
@@ -0,0 +1,16 @@
+unit UMenuInteract;
+
+interface
+
+{$I switches.inc}
+
+type
+ TInteract = record // for moving thru menu
+ Typ: integer; // 0 - button, 1 - select, 2 - Text, 3 - Select SLide, 5 - ButtonCollection Child
+ Num: integer; // number of this item in proper list like buttons, selects
+ end;
+
+implementation
+
+end.
+
\ No newline at end of file
diff --git a/src/Menu/UMenuSelectSlide.pas b/src/Menu/UMenuSelectSlide.pas
new file mode 100644
index 00000000..76299e80
--- /dev/null
+++ b/src/Menu/UMenuSelectSlide.pas
@@ -0,0 +1,355 @@
+unit UMenuSelectSlide;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses TextGL,
+ UTexture,
+ gl,
+ UMenuText;
+
+type
+ PSelectSlide = ^TSelectSlide;
+ TSelectSlide = class
+ private
+ SelectBool: boolean;
+ public
+ // objects
+ Text: TText; // Main text describing option
+ TextOpt: array of TText; // 3 texts in the position of possible options
+ TextOptT: array of string; // array of names for possible options
+
+ Texture: TTexture; // Select Texture
+ TextureSBG: TTexture; // Background Selections Texture
+// TextureS: array of TTexture; // Selections Texture (not used)
+
+// TextureArrowL: TTexture; // Texture for left arrow (not used yet)
+// TextureArrowR: TTexture; // Texture for right arrow (not used yet)
+
+ SelectOptInt: integer;
+ PData: ^integer;
+
+ //For automatically Setting LineCount
+ Lines: Byte;
+
+ //Visibility
+ Visible: Boolean;
+
+ // for selection and deselection
+ // main static
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Int: real;
+ DColR: real;
+ DColG: real;
+ DColB: real;
+ DInt: real;
+
+ // main text
+ TColR: real;
+ TColG: real;
+ TColB: real;
+ TInt: real;
+ TDColR: real;
+ TDColG: real;
+ TDColB: real;
+ TDInt: real;
+
+ // selection background static
+ SBGColR: real;
+ SBGColG: real;
+ SBGColB: real;
+ SBGInt: real;
+ SBGDColR: real;
+ SBGDColG: real;
+ SBGDColB: real;
+ SBGDInt: real;
+
+ // selection text
+ STColR: real;
+ STColG: real;
+ STColB: real;
+ STInt: real;
+ STDColR: real;
+ STDColG: real;
+ STDColB: real;
+ STDInt: real;
+
+ // position and size
+ property X: real read Texture.x write Texture.x;
+ property Y: real read Texture.y write Texture.y;
+ property W: real read Texture.w write Texture.w;
+ property H: real read Texture.h write Texture.h;
+// property X2: real read Texture2.x write Texture2.x;
+// property Y2: real read Texture2.y write Texture2.y;
+// property W2: real read Texture2.w write Texture2.w;
+// property H2: real read Texture2.h write Texture2.h;
+
+ property SBGW: real read TextureSBG.w write TextureSBG.w;
+
+ // procedures
+ procedure SetSelect(Value: boolean);
+ property Selected: Boolean read SelectBool write SetSelect;
+ procedure SetSelectOpt(Value: integer);
+ property SelectedOption: integer read SelectOptInt write SetSelectOpt;
+ procedure Draw;
+ constructor Create;
+
+ //Automatically Generate Lines (Texts)
+ procedure genLines;
+ end;
+
+implementation
+uses UDrawTexture, math, ULog, SysUtils;
+
+// ------------ Select
+constructor TSelectSlide.Create;
+begin
+ inherited Create;
+ Text := TText.Create;
+ SetLength(TextOpt, 1);
+ TextOpt[0] := TText.Create;
+
+ //Set Standard Width for Selections Background
+ SBGW := 450;
+
+ Visible := True;
+ {SetLength(TextOpt, 3);
+ TextOpt[0] := TText.Create;
+ TextOpt[1] := TText.Create;
+ TextOpt[2] := TText.Create;}
+end;
+
+procedure TSelectSlide.SetSelect(Value: boolean);
+{var
+ SO: integer;
+ I: integer;}
+begin
+ SelectBool := Value;
+ if Value then begin
+ Texture.ColR := ColR;
+ Texture.ColG := ColG;
+ Texture.ColB := ColB;
+ Texture.Int := Int;
+
+ Text.ColR := TColR;
+ Text.ColG := TColG;
+ Text.ColB := TColB;
+ Text.Int := TInt;
+
+ TextureSBG.ColR := SBGColR;
+ TextureSBG.ColG := SBGColG;
+ TextureSBG.ColB := SBGColB;
+ TextureSBG.Int := SBGInt;
+
+{ for I := 0 to High(TextOpt) do begin
+ TextOpt[I].ColR := STColR;
+ TextOpt[I].ColG := STColG;
+ TextOpt[I].ColB := STColB;
+ TextOpt[I].Int := STInt;
+ end;}
+
+ end else begin
+ Texture.ColR := DColR;
+ Texture.ColG := DColG;
+ Texture.ColB := DColB;
+ Texture.Int := DInt;
+
+ Text.ColR := TDColR;
+ Text.ColG := TDColG;
+ Text.ColB := TDColB;
+ Text.Int := TDInt;
+
+ TextureSBG.ColR := SBGDColR;
+ TextureSBG.ColG := SBGDColG;
+ TextureSBG.ColB := SBGDColB;
+ TextureSBG.Int := SBGDInt;
+
+{ for I := 0 to High(TextOpt) do begin
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+ end;}
+ end;
+end;
+
+procedure TSelectSlide.SetSelectOpt(Value: integer);
+var
+ SO: integer;
+ Sel: integer;
+ HalfL: integer;
+ HalfR: integer;
+
+procedure DoSelection(Sel: Cardinal);
+ var I: Integer;
+ begin
+ for I := low(TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+ end;
+ if (integer(Sel) <= high(TextOpt)) then
+ begin
+ TextOpt[Sel].ColR := STColR;
+ TextOpt[Sel].ColG := STColG;
+ TextOpt[Sel].ColB := STColB;
+ TextOpt[Sel].Int := STInt;
+ end;
+ end;
+begin
+ SelectOptInt := Value;
+ PData^ := Value;
+// SetSelect(true); // reset all colors
+
+ if (Length(TextOpt)>0) AND (Length(TextOptT)>0) then
+ begin
+
+ if (Value <= 0) then
+ begin //First Option Selected
+ Value := 0;
+
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[SO];
+ end;
+
+ DoSelection(0);
+ end
+ else if (Value >= high(TextOptT)) then
+ begin //Last Option Selected
+ Value := high(TextOptT);
+
+ for SO := high(TextOpt) downto low (TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
+ end;
+ DoSelection(Lines-1);
+ end
+ else
+ begin
+ HalfL := Ceil((Lines-1)/2);
+ HalfR := Lines-1-HalfL;
+
+ if (Value <= HalfL) then
+ begin //Selected Option is near to the left side
+ {HalfL := Value;
+ HalfR := Lines-1-HalfL;}
+ //Change Texts
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[SO];
+ end;
+
+ DoSelection(Value);
+ end
+ else if (Value > High(TextOptT)-HalfR) then
+ begin //Selected is too near to the right border
+ HalfR := high(TextOptT) - Value;
+ HalfL := Lines-1-HalfR;
+ //Change Texts
+ for SO := high(TextOpt) downto low (TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
+ end;
+
+ DoSelection (HalfL);
+ end
+ else
+ begin
+ //Change Texts
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[Value - HalfL + SO];
+ end;
+
+ DoSelection(HalfL);
+ end;
+
+ end;
+
+ end;
+
+end;
+
+procedure TSelectSlide.Draw;
+var
+ SO: integer;
+begin
+ if Visible then
+ begin
+ DrawTexture(Texture);
+ DrawTexture(TextureSBG);
+
+ Text.Draw;
+
+ for SO := low(TextOpt) to high(TextOpt) do
+ TextOpt[SO].Draw;
+ end;
+end;
+
+procedure TSelectSlide.GenLines;
+var
+maxlength: Real;
+I: Integer;
+begin
+ SetFontStyle(0{Text.Style});
+ SetFontSize(Text.Size);
+ maxlength := 0;
+
+ for I := low(TextOptT) to high (TextOptT) do
+ begin
+ if (glTextWidth(PChar(TextOptT[I])) > maxlength) then
+ maxlength := glTextWidth(PChar(TextOptT[I]));
+ end;
+
+ Lines := floor((TextureSBG.W-40) / (maxlength+7));
+ if (Lines > Length(TextOptT)) then
+ Lines := Length(TextOptT);
+
+ if (Lines <= 0) then
+ Lines := 1;
+
+ //Free old Space used by Texts
+ For I := low(TextOpt) to high(TextOpt) do
+ TextOpt[I].Free;
+
+ setLength (TextOpt, Lines);
+
+ for I := low(TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[I] := TText.Create;
+ TextOpt[I].Size := Text.Size;
+ //TextOpt[I].Align := 1;
+ TextOpt[I].Align := 0;
+ TextOpt[I].Visible := True;
+
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+
+ //Generate Positions
+ //TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * (I + 0.5);
+ if (I <> High(TextOpt)) OR (High(TextOpt) = 0) OR (Length(TextOptT) = Lines) then
+ TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * I
+ else
+ TextOpt[I].X := TextureSBG.X + TextureSBG.W - maxlength;
+
+ TextOpt[I].Y := TextureSBG.Y + (TextureSBG.H / 2) - 1.5 * Text.Size{20};
+
+ //Better Look with 2 Options
+ if (Lines=2) AND (Length(TextOptT)= 2) then
+ TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W -40 - glTextWidth(PChar(TextOptT[1]))) * I;
+ end;
+end;
+
+end.
diff --git a/src/Menu/UMenuStatic.pas b/src/Menu/UMenuStatic.pas
new file mode 100644
index 00000000..ac8fa2dc
--- /dev/null
+++ b/src/Menu/UMenuStatic.pas
@@ -0,0 +1,85 @@
+unit UMenuStatic;
+
+interface
+
+{$I switches.inc}
+
+uses UTexture, gl;
+
+type
+ TStatic = class
+ public
+ Texture: TTexture; // Button Screen position and size
+ Visible: boolean;
+
+ //Reflection Mod
+ Reflection: boolean;
+ Reflectionspacing: Real;
+
+ procedure Draw;
+ constructor Create(Textura: TTexture); overload;
+ end;
+
+implementation
+uses UDrawTexture;
+
+procedure TStatic.Draw;
+begin
+ if Visible then
+ begin
+ DrawTexture(Texture);
+
+ //Reflection Mod
+ if (Reflection) then // Draw Reflections
+ begin
+ with Texture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ //Draw
+ glBegin(GL_QUADS);//Top Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH);
+ glVertex3f(x, y+h*scaleH+ Reflectionspacing, z);
+
+ //Bottom Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX1*TexW, 0.5*TexH+TexY1);
+ glVertex3f(x, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z);
+
+
+ //Bottom Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX2*TexW, 0.5*TexH+TexY1);
+ glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z);
+
+ //Top Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH);
+ glVertex3f(x+w*scaleW, y+h*scaleH + Reflectionspacing, z);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ end;
+ end;
+ end;
+end;
+
+constructor TStatic.Create(Textura: TTexture);
+begin
+ inherited Create;
+ Texture := Textura;
+end;
+
+end.
diff --git a/src/Menu/UMenuText.pas b/src/Menu/UMenuText.pas
new file mode 100644
index 00000000..fecf936e
--- /dev/null
+++ b/src/Menu/UMenuText.pas
@@ -0,0 +1,350 @@
+unit UMenuText;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses TextGL,
+ UTexture,
+ gl,
+ math,
+ SysUtils,
+ SDL;
+
+type
+ TText = class
+ private
+ SelectBool: boolean;
+ TextString: string;
+ TextTiles: array of string;
+
+ STicks: Cardinal;
+ SelectBlink: boolean;
+ public
+ X: real;
+ Y: real;
+ Z: real;
+ MoveX: real; //Some Modifier for X - Position that don't affect the real Y
+ MoveY: real; //Some Modifier for Y - Position that don't affect the real Y
+ W: real; //text wider than W is broken
+// H: real;
+ Size: real;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Alpha: real;
+ Int: real;
+ Style: integer;
+ Visible: boolean;
+ Align: integer; // 0 = left, 1 = center, 2 = right
+
+ //Reflection
+ Reflection: boolean;
+ ReflectionSpacing: real;
+
+ procedure SetSelect(Value: boolean);
+ property Selected: boolean read SelectBool write SetSelect;
+
+ procedure SetText(Value: string);
+ property Text: string read TextString write SetText;
+
+ procedure DeleteLastL; //Procedure to Delete Last Letter
+
+ procedure Draw;
+ constructor Create; overload;
+ constructor Create(X, Y: real; Tekst: string); overload;
+ constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ: real); overload;
+ end;
+
+implementation
+
+uses UGraphic,
+ StrUtils;
+
+procedure TText.SetSelect(Value: boolean);
+begin
+ SelectBool := Value;
+
+ //Set Cursor Visible
+ SelectBlink := True;
+ STicks := SDL_GetTicks() div 550;
+end;
+
+procedure TText.SetText(Value: string);
+var
+ NextPos: Cardinal; //NextPos of a Space etc.
+ LastPos: Cardinal; //LastPos "
+ LastBreak: Cardinal; //Last Break
+ isBreak: boolean; //True if the Break is not Caused because the Text is out of the area
+ FirstWord: Word; //Is First Word after Break?
+ Len: Word; //Length of the Tiles Array
+
+ function GetNextPos: boolean;
+ var
+ T1, T2, T3: Cardinal;
+ begin
+ LastPos := NextPos;
+
+ //Next Space (If Width is given)
+ if (W > 0) then
+ T1 := PosEx(' ', Value, LastPos + 1)
+ else T1 := Length(Value);
+
+ {//Next -
+ T2 := PosEx('-', Value, LastPos + 1);}
+
+ //Next Break
+ T3 := PosEx('\n', Value, LastPos + 1);
+
+ if T1 = 0 then
+ T1 := Length(Value);
+ {if T2 = 0 then
+ T2 := Length(Value); }
+ if T3 = 0 then
+ T3 := Length(Value);
+
+ //Get Nearest Pos
+ NextPos := min(T1, T3{min(T2, T3)});
+
+ if (LastPos = Length(Value)) then
+ NextPos := 0;
+
+ isBreak := (NextPos = T3) AND (NextPos <> Length(Value));
+ Result := (NextPos <> 0);
+ end;
+
+ procedure AddBreak(const From, bTo: Cardinal);
+ begin
+ if (isBreak) OR (bTo - From >= 1) then
+ begin
+ Inc(Len);
+ SetLength (TextTiles, Len);
+ TextTiles[Len-1] := Trim(Copy(Value, From, bTo - From));
+
+ if isBreak then
+ LastBreak := bTo + 2
+ else
+ LastBreak := bTo + 1;
+ FirstWord := 0;
+ end;
+ end;
+
+begin
+ //Set TExtstring
+ TextString := Value;
+
+ //Set Cursor Visible
+ SelectBlink := True;
+ STicks := SDL_GetTicks() div 550;
+
+ //Exit if there is no Need to Create Tiles
+ if (W <= 0) and (Pos('\n', Value) = 0) then
+ begin
+ SetLength (TextTiles, 1);
+ TextTiles[0] := Value;
+ Exit;
+ end;
+
+ //Create Tiles
+ //Reset Text Array
+ SetLength (TextTiles, 0);
+ Len := 0;
+
+ //Reset Counter Vars
+ LastPos := 1;
+ NextPos := 1;
+ LastBreak := 1;
+ FirstWord := 1;
+
+ if (W > 0) then
+ begin
+ //Set Font Properties
+ SetFontStyle(Style);
+ SetFontSize(Size);
+ end;
+
+ //go Through Text
+ while (GetNextPos) do
+ begin
+ //Break in Text
+ if isBreak then
+ begin
+ //Look for Break before the Break
+ if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) AND (NextPos-LastPos > 1) then
+ begin
+ isBreak := False;
+ //Not the First word after Break, so we don't have to break within a word
+ if (FirstWord > 1) then
+ begin
+ //Add Break before actual Position, because there the Text fits the Area
+ AddBreak(LastBreak, LastPos);
+ end
+ else //First Word after Break Break within the Word
+ begin
+ //ToDo
+ //AddBreak(LastBreak, LastBreak + 155);
+ end;
+ end;
+
+ isBreak := True;
+ //Add Break from Text
+ AddBreak(LastBreak, NextPos);
+ end
+ //Text comes out of the Text Area -> CreateBreak
+ else if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) then
+ begin
+ //Not the First word after Break, so we don't have to break within a word
+ if (FirstWord > 1) then
+ begin
+ //Add Break before actual Position, because there the Text fits the Area
+ AddBreak(LastBreak, LastPos);
+ end
+ else //First Word after Break -> Break within the Word
+ begin
+ //ToDo
+ //AddBreak(LastBreak, LastBreak + 155);
+ end;
+ end;
+ //end;
+ Inc(FirstWord)
+ end;
+ //Add Ending
+ AddBreak(LastBreak, Length(Value)+1);
+end;
+
+procedure TText.DeleteLastL;
+var
+ S: string;
+ L: integer;
+begin
+ S := TextString;
+ L := Length(S);
+ if (L > 0) then
+ SetLength(S, L-1);
+
+ SetText(S);
+end;
+
+procedure TText.Draw;
+var
+ X2, Y2: real;
+ Text2: string;
+ I: integer;
+begin
+ if Visible then
+ begin
+ SetFontStyle(Style);
+ SetFontSize(Size);
+ SetFontItalic(False);
+
+ glColor4f(ColR*Int, ColG*Int, ColB*Int, Alpha);
+
+ //Reflection
+ if Reflection = true then
+ SetFontReflection(true, ReflectionSpacing)
+ else
+ SetFontReflection(false,0);
+
+ //if selected set blink...
+ if SelectBool then
+ begin
+ I := SDL_GetTicks() div 550;
+ if I <> STicks then
+ begin //Change Visability
+ STicks := I;
+ SelectBlink := Not SelectBlink;
+ end;
+ end;
+
+ {if (False) then //no width set draw as one long string
+ begin
+ if not (SelectBool AND SelectBlink) then
+ Text2 := Text
+ else
+ Text2 := Text + '|';
+
+ case Align of
+ 0: X2 := X;
+ 1: X2 := X - glTextWidth(pchar(Text2))/2;
+ 2: X2 := X - glTextWidth(pchar(Text2));
+ end;
+
+ SetFontPos(X2, Y);
+ glPrint(PChar(Text2));
+ SetFontStyle(0); // reset to default
+ end
+ else
+ begin}
+ //now use allways:
+ //draw text as many strings
+ Y2 := Y + MoveY;
+ for I := 0 to high(TextTiles) do
+ begin
+ if (not (SelectBool and SelectBlink)) or (I <> high(TextTiles)) then
+ Text2 := TextTiles[I]
+ else
+ Text2 := TextTiles[I] + '|';
+
+ case Align of
+ 0: X2 := X + MoveX;
+ 1: X2 := X + MoveX - glTextWidth(pchar(Text2))/2;
+ 2: X2 := X + MoveX - glTextWidth(pchar(Text2));
+ end;
+
+ SetFontPos(X2, Y2);
+
+ SetFontZ(Z);
+
+ glPrint(PChar(Text2));
+
+ {if Size >= 10 then
+ Y2 := Y2 + Size * 2.8
+ else}
+ if (Style = 1) then
+ Y2 := Y2 + Size * 2.8
+ else
+ Y2 := Y2 + Size * 2.15;
+ end;
+ SetFontStyle(0); // reset to default
+
+ //end;
+ end;
+end;
+
+constructor TText.Create;
+begin
+ Create(0, 0, '');
+end;
+
+constructor TText.Create(X, Y: real; Tekst: string);
+begin
+ Create(X, Y, 0, 0, 10, 0, 0, 0, 0, Tekst, false, 0, 0);
+end;
+
+constructor TText.Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ:real);
+begin
+ inherited Create;
+ Alpha := 1;
+ X := ParX;
+ Y := ParY;
+ W := ParW;
+ Z := ParZ;
+ Style := ParStyle;
+ Size := ParSize;
+ Text := ParTekst;
+ ColR := ParColR;
+ ColG := ParColG;
+ ColB := ParColB;
+ Int := 1;
+ Align := ParAlign;
+ SelectBool := false;
+ Visible := true;
+ Reflection:= ParReflection;
+ ReflectionSpacing:= ParReflectionSpacing;
+end;
+
+end.
diff --git a/src/Screens/UScreenCredits.pas b/src/Screens/UScreenCredits.pas
new file mode 100644
index 00000000..f7f1fca7
--- /dev/null
+++ b/src/Screens/UScreenCredits.pas
@@ -0,0 +1,1398 @@
+unit UScreenCredits;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ UMenu,
+ SDL,
+ SDL_Image,
+ UDisplay,
+ UTexture,
+ gl,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes,
+ //ULCD,
+ //ULight,
+ UGraphicClasses;
+
+type
+ TCreditsStages=(InitialDelay,Intro,MainPart,Outro);
+
+ TScreenCredits = class(TMenu)
+ public
+
+ Credits_X: Real;
+ Credits_Time: Cardinal;
+ Credits_Alpha: Cardinal;
+ CTime: Cardinal;
+ CTime_hold: Cardinal;
+ ESC_Alpha: Integer;
+
+ credits_entry_tex: TTexture;
+ credits_entry_dx_tex: TTexture;
+ credits_bg_tex: TTexture;
+ credits_bg_ovl: TTexture;
+// credits_bg_logo: TTexture;
+ credits_bg_scrollbox_left: TTexture;
+ credits_blindguard: TTexture;
+ credits_blindy: TTexture;
+ credits_canni: TTexture;
+ credits_commandio: TTexture;
+ credits_lazyjoker: TTexture;
+ credits_mog: TTexture;
+ credits_mota: TTexture;
+ credits_skillmaster: TTexture;
+ credits_whiteshark: TTexture;
+ intro_layer01: TTexture;
+ intro_layer02: TTexture;
+ intro_layer03: TTexture;
+ intro_layer04: TTexture;
+ intro_layer05: TTexture;
+ intro_layer06: TTexture;
+ intro_layer07: TTexture;
+ intro_layer08: TTexture;
+ intro_layer09: TTexture;
+ outro_bg: TTexture;
+ outro_esc: TTexture;
+ outro_exd: TTexture;
+
+ deluxe_slidein: cardinal;
+
+ CurrentScrollText: String;
+ NextScrollUpdate: Real;
+ EndofLastScrollingPart: Cardinal;
+ CurrentScrollStart, CurrentScrollEnd: Integer;
+
+ CRDTS_Stage: TCreditsStages;
+
+ myTex: glUint;
+ mysdlimage,myconvertedsdlimage: PSDL_Surface;
+
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure DrawCredits;
+ procedure Draw_FunkyText;
+ end;
+
+const
+ Funky_Text: AnsiString =
+ 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+
+ 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+
+ 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+
+ 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..';
+
+
+ Timings: array[0..21] of Cardinal=(
+ 20, // 0 Delay vor Start
+
+ 149, // 1 Ende erster Intro Zoom
+ 155, // 2 Start 2. Action im Intro
+ 170, // 3 Ende Separation im Intro
+ 271, // 4 Anfang Zoomout im Intro
+ 0, // 5 unused
+ 261, // 6 Start fade-to-white im Intro
+
+ 271, // 7 Start Main Part
+ 280, // 8 Start On-Beat-Sternchen Main Part
+
+ 396, // 9 Start BlindGuard
+ 666, // 10 Start blindy
+ 936, // 11 Start Canni
+ 1206, // 12 Start Commandio
+ 1476, // 13 Start LazyJoker
+ 1746, // 14 Start Mog
+ 2016, // 15 Start Mota
+ 2286, // 16 Start SkillMaster
+ 2556, // 17 Start WhiteShark
+ 2826, // 18 Ende Whiteshark
+ 3096, // 19 Start FadeOut Mainscreen
+ 3366, // 20 Ende Credits Tune
+ 60); // 21 start flare im intro
+
+
+ sdl32bpprgba: TSDL_Pixelformat=(palette: nil;
+ BitsPerPixel: 32;
+ BytesPerPixel: 4;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 0;
+ Gshift: 8;
+ Bshift: 16;
+ Ashift: 24;
+ Rmask: $000000ff;
+ Gmask: $0000ff00;
+ Bmask: $00ff0000;
+ Amask: $ff000000;
+ colorkey: 0;
+ alpha: 255 );
+
+
+implementation
+
+uses
+ ULog,
+ UGraphic,
+ UMain,
+ UIni,
+ USongs,
+ Textgl,
+ ULanguage,
+ UCommon,
+ Math;
+
+
+function TScreenCredits.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ FadeTo(@ScreenMain);
+ AudioPlayback.PlaySound(SoundLib.Back);
+ end;
+{ SDLK_SPACE:
+ begin
+ setlength(CTime_hold,length(CTime_hold)+1);
+ CTime_hold[high(CTime_hold)]:=CTime;
+ end;
+}
+ end;//esac
+ end; //fi
+end;
+
+constructor TScreenCredits.Create;
+begin
+ inherited Create;
+
+ credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', TEXTURE_TYPE_PLAIN, 0);
+ credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', TEXTURE_TYPE_TRANSPARENT, 0);
+
+ credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', TEXTURE_TYPE_TRANSPARENT, 0);
+ credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', TEXTURE_TYPE_TRANSPARENT, 0);
+
+ intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', TEXTURE_TYPE_TRANSPARENT, 0);
+ intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', TEXTURE_TYPE_TRANSPARENT, 0);
+
+ outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', TEXTURE_TYPE_PLAIN, 0);
+ outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', TEXTURE_TYPE_TRANSPARENT, 0);
+ outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', TEXTURE_TYPE_TRANSPARENT, 0);
+
+ CRDTS_Stage:=InitialDelay;
+end;
+
+function TScreenCredits.Draw: boolean;
+begin
+ DrawCredits;
+ Draw:=true;
+end;
+
+function pixfmt_eq(fmt1,fmt2: TSDL_Pixelformat): boolean;
+begin
+ if (fmt1.BitsPerPixel = fmt2.BitsPerPixel) and
+ (fmt1.BytesPerPixel = fmt2.BytesPerPixel) and
+ (fmt1.Rloss = fmt2.Rloss) and
+ (fmt1.Gloss = fmt2.Gloss) and
+ (fmt1.Bloss = fmt2.Bloss) and
+ (fmt1.Rmask = fmt2.Rmask) and
+ (fmt1.Gmask = fmt2.Gmask) and
+ (fmt1.Bmask = fmt2.Bmask) and
+ (fmt1.Rshift = fmt2.Rshift) and
+ (fmt1.Gshift = fmt2.Gshift) and
+ (fmt1.Bshift = fmt2.Bshift)
+ then
+ pixfmt_eq:=True
+ else
+ pixfmt_eq:=False;
+end;
+
+function inttohexstr(i: cardinal):pchar;
+var helper, i2, c:cardinal;
+ tmpstr: string;
+begin
+ helper:=0;
+ i2:=i;
+ tmpstr:='';
+ for c:=1 to 8 do
+ begin
+ helper:=(helper shl 4) or (i2 and $f);
+ i2:=i2 shr 4;
+ end;
+ for c:=1 to 8 do
+ begin
+ i2:=helper and $f;
+ helper := helper shr 4;
+ case i2 of
+ 0: tmpstr:=tmpstr+'0';
+ 1: tmpstr:=tmpstr+'1';
+ 2: tmpstr:=tmpstr+'2';
+ 3: tmpstr:=tmpstr+'3';
+ 4: tmpstr:=tmpstr+'4';
+ 5: tmpstr:=tmpstr+'5';
+ 6: tmpstr:=tmpstr+'6';
+ 7: tmpstr:=tmpstr+'7';
+ 8: tmpstr:=tmpstr+'8';
+ 9: tmpstr:=tmpstr+'9';
+ 10: tmpstr:=tmpstr+'a';
+ 11: tmpstr:=tmpstr+'b';
+ 12: tmpstr:=tmpstr+'c';
+ 13: tmpstr:=tmpstr+'d';
+ 14: tmpstr:=tmpstr+'e';
+ 15: tmpstr:=tmpstr+'f';
+ end;
+ end;
+ inttohexstr:=pchar(tmpstr);
+end;
+
+procedure TScreenCredits.onShow;
+begin
+ inherited;
+
+ CRDTS_Stage:=InitialDelay;
+ Credits_X := 580;
+ deluxe_slidein := 0;
+ Credits_Alpha := 0;
+ //Music.SetLoop(true); Loop looped ned, so ne scheisse - loop loops not, shit
+ AudioPlayback.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!! - thank you wetü
+// Music.Play;
+ CTime:=0;
+// setlength(CTime_hold,0);
+
+ mysdlimage:=IMG_Load('test.png');
+ if assigned(mysdlimage) then
+ begin
+ showmessage('opened image via SDL_Image'+#13#10+
+ 'Width: '+inttostr(mysdlimage^.w)+#13#10+
+ 'Height: '+inttostr(mysdlimage^.h)+#13#10+
+ 'BitsPP: '+inttostr(mysdlimage^.format.BitsPerPixel)+#13#10+
+ 'BytesPP: '+inttostr(mysdlimage^.format.BytesPerPixel)+#13#10+
+ 'Rloss: '+inttostr(mysdlimage^.format.Rloss)+#13#10+
+ 'Gloss: '+inttostr(mysdlimage^.format.Gloss)+#13#10+
+ 'Bloss: '+inttostr(mysdlimage^.format.Bloss)+#13#10+
+ 'Aloss: '+inttostr(mysdlimage^.format.Aloss)+#13#10+
+ 'Rshift: '+inttostr(mysdlimage^.format.Rshift)+#13#10+
+ 'Gshift: '+inttostr(mysdlimage^.format.Gshift)+#13#10+
+ 'Bshift: '+inttostr(mysdlimage^.format.Bshift)+#13#10+
+ 'Ashift: '+inttostr(mysdlimage^.format.Ashift)+#13#10+
+ 'Rmask: '+inttohexstr(mysdlimage^.format.Rmask)+#13#10+
+ 'Gmask: '+inttohexstr(mysdlimage^.format.Gmask)+#13#10+
+ 'Bmask: '+inttohexstr(mysdlimage^.format.Bmask)+#13#10+
+ 'Amask: '+inttohexstr(mysdlimage^.format.Amask)+#13#10+
+ 'ColKey: '+inttostr(mysdlimage^.format.Colorkey)+#13#10+
+ 'Alpha: '+inttostr(mysdlimage^.format.Alpha));
+
+ if pixfmt_eq(mysdlimage^.format^,sdl32bpprgba) then
+ showmessage('equal pixelformats')
+ else
+ showmessage('different pixelformats');
+
+ myconvertedsdlimage:=SDL_ConvertSurface(mysdlimage,@sdl32bpprgba,SDL_SWSURFACE);
+ glGenTextures(1,@myTex);
+ glBindTexture(GL_TEXTURE_2D, myTex);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexImage2D( GL_TEXTURE_2D, 0, 4, myconvertedsdlimage^.w, myconvertedsdlimage^.h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, myconvertedsdlimage^.pixels );
+ SDL_FreeSurface(mysdlimage);
+ SDL_FreeSurface(myconvertedsdlimage);
+ end
+ else
+ showmessage('could not open file - test.png');
+
+end;
+
+procedure TScreenCredits.onHide;
+begin
+ AudioPlayback.Stop;
+end;
+
+Procedure TScreenCredits.Draw_FunkyText;
+var
+ S: Integer;
+ X,Y,A: Real;
+ visibleText: PChar;
+begin
+ SetFontSize(10);
+ //Init ScrollingText
+ if (CTime = Timings[7]) then
+ begin
+ //Set Position of Text
+ Credits_X := 600;
+ CurrentScrollStart:=1;
+ CurrentScrollEnd:=1;
+ end;
+
+ if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then
+ begin
+ X:=0;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ for S := 0 to length(visibleText)-1 do begin
+ Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi));
+ SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000);
+ A:=0;
+ if (Credits_X+X < 15) then A:=0;
+ if (Credits_X+X >=15) then A:=Credits_X+X-15;
+ if Credits_X+X > 32 then A:=17;
+ glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17);
+ glPrintLetter(visibleText[S]);
+ X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ end;
+ if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin
+ Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ inc(CurrentScrollStart);
+ end;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin
+ inc(CurrentScrollEnd);
+ end;
+ end;
+{ // timing hack
+ X:=5;
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ glColor4f(1, 1, 1, 1);
+ for S:=0 to high(CTime_hold) do begin
+ visibleText:=pchar(inttostr(CTime_hold[S]));
+ SetFontPos (500, X);
+ glPrint (Addr(visibleText[0]));
+ X:=X+20;
+ end;}
+end;
+
+procedure Start3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix;
+ glLoadIdentity;
+ glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity;
+end;
+procedure End3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix;
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure TScreenCredits.DrawCredits;
+var
+T{*, I*}: Cardinal; // Auto Removed, Unused Variable (I) // Auto Removed, Unused Variable (I)
+// X: Real; // Auto Removed, Unused Variable
+// Ver: PChar; // Auto Removed, Unused Variable
+// RuntimeStr: AnsiString; // Auto Removed, Unused Variable
+ Data: TFFTData;
+ j,k,l:cardinal;
+f,g{*, h*}: Real; // Auto Removed, Unused Variable (h) // Auto Removed, Unused Variable (h)
+ STime:cardinal;
+ Delay:cardinal;
+
+// myPixel: longword; // Auto Removed, Unused Variable
+// myColor: Cardinal; // Auto Removed, Unused Variable
+ myScale: Real;
+ myAngle: Real;
+
+
+const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24),
+ (154,31),(156,58),(168,32),(203,36),
+ (258,34),(251,50),(274,93),(294,84),
+ (232,54),(278,62),(319,34),(336,92),
+ (347,23),(374,32),(377,58),(361,83),
+ (385,91),(405,91),(429,35),(423,51),
+ (450,32),(485,34),(444,91),(486,93));
+
+begin
+ //dis does teh muiwk y0r
+ AudioPlayback.GetFFTData(Data);
+
+ Log.LogStatus('',' JB-1');
+
+ T := SDL_GetTicks() div 33;
+ if T <> Credits_Time then
+ begin
+ Credits_Time := T;
+ inc(CTime);
+ inc(CTime_hold);
+ Credits_X := Credits_X-2;
+
+ Log.LogStatus('',' JB-2');
+ if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then
+ begin
+// CTime:=Timings[20];
+// CRDTS_Stage:=Outro;
+
+ CRDTS_Stage:=Intro;
+ CTime:=0;
+ AudioPlayback.Play;
+
+ end;
+ if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then
+ begin
+ CRDTS_Stage:=MainPart;
+ end;
+ if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then
+ begin
+ CRDTS_Stage:=Outro;
+ end;
+ end;
+
+ Log.LogStatus('',' JB-3');
+
+ //draw background
+ if CRDTS_Stage=InitialDelay then
+ begin
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end
+ else
+ if CRDTS_Stage=Intro then
+ begin
+ Start3D;
+ glPushMatrix;
+
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ if CTime < Timings[1] then begin
+ myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together
+ myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera
+ end else begin // this is the part when the logo stands still
+ myScale:=0.5;
+ myAngle:=0;
+ end;
+ if CTime > Timings[2] then begin
+ myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers
+ myAngle:=0;
+ end;
+// if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ glTranslatef(0,0,-5+0.5*myScale);
+ if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ if CTime > Timings[3] then begin // make logo rotate left and grow
+// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]);
+ glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1);
+ glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1);
+ end;
+ if CTime < Timings[2] then
+ glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0);
+// glScalef(0.5,0.5,0.5);
+ glScalef(4/3,-1,1);
+ glColor4f(1, 1, 1, 1);
+
+ glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale);
+ glEnd;
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ glPopMatrix;
+ End3D;
+
+ // do some sparkling effects
+ if (CTime < Timings[1]) and (CTime > Timings[21]) then
+ begin
+ for k:=1 to 3 do begin
+ l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5);
+ j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301);
+ GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0);
+ end;
+ end;
+
+ // fade to white at end
+ if Ctime > Timings[6] then
+ begin
+ glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
+ end;
+ if (CRDTS_Stage=MainPart) then
+ // main credits screen background, scroller, logo and girl
+ begin
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // draw scroller
+ Draw_FunkyText;
+
+//#########################################################################
+// draw credits names
+
+
+Log.LogStatus('',' JB-4');
+
+// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen) - (rotate in from upper left, rotate out to lower right)
+ STime:=Timings[9]-10;
+ Delay:=Timings[10]-Timings[9];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(0,329,0);
+ if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end;
+ gltranslatef(223,0,0);
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ gltranslatef(223,0,0);
+ glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben) - (zoom from 0 to full size and rotation, zoom zo doubble size and shift to upper right)
+ STime:=Timings[10]-10;
+ Delay:=Timings[11]-Timings[10]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+20) and (CTime<=STime+22) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+20 then begin
+ j:=CTime-Stime;
+ glscalef(j*j/400,j*j/400,j*j/400);
+ glrotatef(j*18.0,0,0,1);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(f*3,-f,0);
+ glscalef(1+j/10,1+j/10,1+j/10);
+ glrotatef(j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Canni (von links reinschieben, nach rechts oben rausschieben) - (shift in from left, shift out to upper right)
+ STime:=Timings[11]-10;
+ Delay:=Timings[12]-Timings[11]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(((CTime-STime)*21.0)-210,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=(CTime-(STime+Delay-10))*21;
+ gltranslatef(j,-j/2,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Commandio (von unten reinklappen, nach rechts oben rausklappen) - (flip in from down, flip out to upper right)
+ STime:=Timings[12]-10;
+ Delay:=Timings[13]-Timings[12];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=258.0-25.8*(CTime-STime)
+ else
+ f:=0;
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326));
+ glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4);
+ glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing)
+ STime:=Timings[13]-35;
+ Delay:=Timings[14]-Timings[13]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20;
+ ESC_Alpha:=10;
+ f:=CTime-STime;
+ if CTime <=STime+40 then j:=CTime-STime else j:=40;
+ if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600);
+
+ glPushMatrix;
+ gltranslatef(180+(f-70),329,0);
+ glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mog (von links reinklappen, nach rechts unten rausklappen) - (flip in from right, flip out to lower right)
+ STime:=Timings[14]-10;
+ Delay:=Timings[15]-Timings[14]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g);
+ glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen) - (rotate in from upper right, shift out to lower left while shrinking and rotateing)
+ STime:=Timings[15]-10;
+ Delay:=Timings[16]-Timings[15]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(223,0,0);
+ glrotatef((10-(CTime-STime))*9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(-f*2,-f,0);
+ glscalef(1-j/10,1-j/10,1-j/10);
+ glrotatef(-j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen) - (shift in from lower right, rotate out to upper right)
+ STime:=Timings[16]-10;
+ Delay:=Timings[17]-Timings[16]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ j:=STime+10-CTime;
+ f:=j*10.0;
+ gltranslatef(+f*2,+f/2,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ gltranslatef(0,-223,0);
+ glrotatef(integer(j)*-9,0,0,1);
+ gltranslatef(0,223,0);
+ glrotatef(j*9,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen) - (flip in from lower left, flip out to upper right)
+ STime:=Timings[17]-10;
+ Delay:=Timings[18]-Timings[17];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ if (CTime >= STime+Delay-10) and (CTime <= STime+Delay) then
+ begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end
+ else
+ begin
+ g:=0;
+ end;
+
+ glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4);
+ glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+
+ Log.LogStatus('',' JB-103');
+
+// ####################################################################
+// do some twinkle stuff (kinda on beat)
+ if (CTime > Timings[8] ) and
+ (CTime < Timings[19] ) then
+ begin
+ k := 0;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+ if Data[k]>0.2 then
+ begin
+ l := RandomRange(6,16);
+ j := RandomRange(0,27);
+
+ GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0);
+ end;
+ end;
+
+//#################################################
+// draw the rest of the main screen (girl and logo
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-393, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(800-393, 600);
+ glTexCoord2f(393/512,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(393/512,0);glVertex2f(800, 0);
+ glEnd;
+{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,112/128);glVertex2f(0, 112);
+ glTexCoord2f(497/512,112/128); glVertex2f(497, 112);
+ glTexCoord2f(497/512,0);glVertex2f(497, 0);
+ glEnd;
+}
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ // fade out at end of main part
+ if Ctime > Timings[19] then
+ begin
+ glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ end
+ else
+ if (CRDTS_Stage=Outro) then
+ begin
+ if CTime=Timings[20] then begin
+ CTime_hold:=0;
+ AudioPlayback.Stop;
+ AudioPlayback.Open(soundpath + 'credits-outro-tune.mp3');
+ AudioPlayback.SetVolume(0.2);
+ AudioPlayback.SetLoop(True);
+ AudioPlayback.Play;
+ end;
+ if CTime_hold > 231 then begin
+ AudioPlayback.Play;
+ Ctime_hold:=0;
+ end;
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ // do something useful
+ // outro background
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+
+ //outro overlays
+ glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3);
+ glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,223/256);glVertex2f(0, 223);
+ glTexCoord2f(487/512,223/256); glVertex2f(487, 223);
+ glTexCoord2f(487/512,0);glVertex2f(487, 0);
+ glEnd;
+
+ ESC_Alpha:=20;
+ if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then
+ ESC_Alpha:=0
+ else inc(ESC_Alpha);
+ if ESC_Alpha > 20 then ESC_Alpha:=20;
+ glColor4f(1, 1, 1, ESC_Alpha/20);
+ glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-310, 600-247);
+ glTexCoord2f(0,247/256);glVertex2f(800-310, 600);
+ glTexCoord2f(310/512,247/256); glVertex2f(800, 600);
+ glTexCoord2f(310/512,0);glVertex2f(800, 600-247);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // outro scrollers?
+ // ...
+ end;
+
+{ // draw credits runtime counter
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (5, 5);
+ glColor4f(1, 1, 1, 1);
+// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10);
+ RuntimeStr:='CTime: '+inttostr(CTime);
+ glPrint (Addr(RuntimeStr[1]));
+}
+
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, myTex);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(100, 100);
+ glTexCoord2f(0,1);glVertex2f(100, 200);
+ glTexCoord2f(1,1); glVertex2f(200, 200);
+ glTexCoord2f(1,0);glVertex2f(200, 100);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+
+ // make the stars shine
+ GoldenRec.Draw;
+end;
+
+end.
diff --git a/src/Screens/UScreenEdit.pas b/src/Screens/UScreenEdit.pas
new file mode 100644
index 00000000..bf664eb1
--- /dev/null
+++ b/src/Screens/UScreenEdit.pas
@@ -0,0 +1,121 @@
+unit UScreenEdit;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu, SDL, UThemes;
+
+type
+ TScreenEdit = class(TMenu)
+ public
+{ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ FileName: string;}
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, USkins, SysUtils;
+
+function TScreenEdit.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+// Result := false;
+ end;
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenEditConvert);
+ end;
+// if Interaction = 1 then begin
+// Music.PlayStart;
+// FadeTo(@ScreenEditHeader);
+// end;
+
+ if Interaction = 1 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEdit.Create;
+begin
+ inherited Create;
+ AddButton(400-200, 100 + 0*70, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Convert Midi to Txt');
+// Button[High(Button)].Text[0].Size := 11;
+
+// AddButton(400-200, 100 + 1*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Edit Headers');
+
+// AddButton(400-200, 100 + 2*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Set GAP');
+
+ AddButton(400-200, 100 + 3*60, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Exit');
+
+end;
+
+procedure TScreenEdit.onShow;
+begin
+ inherited;
+
+// Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+end;
+
+procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/src/Screens/UScreenEditConvert.pas b/src/Screens/UScreenEditConvert.pas
new file mode 100644
index 00000000..dfde696e
--- /dev/null
+++ b/src/Screens/UScreenEditConvert.pas
@@ -0,0 +1,584 @@
+unit UScreenEditConvert;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses UMenu,
+ SDL,
+ {$IFDEF UseMIDIPort}
+ MidiFile,
+ MidiOut,
+ {$ENDIF}
+ ULog,
+ USongs,
+ USong,
+ UMusic,
+ UThemes;
+
+type
+ TNote = record
+ Event: integer;
+ EventType: integer;
+ Channel: integer;
+ Start: real;
+ Len: real;
+ Data1: integer;
+ Data2: integer;
+ Str: string;
+ end;
+
+ TTrack = record
+ Note: array of TNote;
+ Name: string;
+ Hear: boolean;
+ Status: byte; // 0 - none, 1 - notes, 2 - lyrics, 3 - notes + lyrics
+ end;
+
+ TNuta = record
+ Start: integer;
+ Len: integer;
+ Tone: integer;
+ Lyric: string;
+ NewSentence: boolean;
+ end;
+
+ TArrayTrack = array of TTrack;
+
+ TScreenEditConvert = class(TMenu)
+ public
+ ATrack: TArrayTrack; // actual track
+// Track: TArrayTrack;
+ Channel: TArrayTrack;
+ ColR: array[0..100] of real;
+ ColG: array[0..100] of real;
+ ColB: array[0..100] of real;
+ Len: real;
+ Sel: integer;
+ Selected: boolean;
+// FileName: string;
+
+ {$IFDEF UseMIDIPort}
+ MidiFile: TMidiFile;
+ MidiTrack: TMidiTrack;
+ MidiEvent: pMidiEvent;
+ MidiOut: TMidiOutput;
+ {$ENDIF}
+
+ Song: TSong;
+ Lines: TLines;
+ BPM: real;
+ Ticks: real;
+ Note: array of TNuta;
+
+ procedure AddLyric(Start: integer; Text: string);
+ procedure Extract;
+
+ {$IFDEF UseMIDIPort}
+ procedure MidiFile1MidiEvent(event: PMidiEvent);
+ {$ENDIF}
+
+ function SelectedNumber: integer;
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onHide; override;
+ end;
+
+implementation
+uses UGraphic,
+ SysUtils,
+ UDrawTexture,
+ TextGL,
+ UFiles,
+ UMain,
+ UIni,
+ gl,
+ USkins;
+
+function TScreenEditConvert.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ T: integer;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ {$IFDEF UseMIDIPort}
+ MidiFile.StopPlaying;
+ {$ENDIF}
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenEdit);
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ ScreenOpen.BackScreen := @ScreenEditConvert;
+ FadeTo(@ScreenOpen);
+ end;
+
+ if Interaction = 1 then
+ begin
+ Selected := false;
+ {$IFDEF UseMIDIPort}
+ MidiFile.OnMidiEvent := MidiFile1MidiEvent;
+// MidiFile.GoToTime(MidiFile.GetTrackLength div 2);
+ MidiFile.StartPlaying;
+ {$ENDIF}
+ end;
+
+ if Interaction = 2 then begin
+ Selected := true;
+ {$IFDEF UseMIDIPort}
+ MidiFile.OnMidiEvent := nil;
+ {$ENDIF}
+ {for T := 0 to High(ATrack) do begin
+ if ATrack[T].Hear then begin
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+ end;
+ end;
+ MidiFile.StartPlaying;//}
+ end;
+
+ if Interaction = 3 then begin
+ if SelectedNumber > 0 then begin
+ Extract;
+ SaveSong(Song, Lines, ChangeFileExt(ConversionFileName, '.txt'), false);
+ end;
+ end;
+
+ end;
+
+ SDLK_SPACE:
+ begin
+// ATrack[Sel].Hear := not ATrack[Sel].Hear;
+ ATrack[Sel].Status := (ATrack[Sel].Status + 1) mod 4;
+
+{ if Selected then begin
+ MidiTrack := MidiFile.GetTrack(Sel);
+ if Track[Sel].Hear then
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent
+ else
+ MidiTrack.OnMidiEvent := nil;
+ end;}
+ end;
+
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+
+ SDLK_DOWN:
+ begin
+ Inc(Sel);
+ if Sel > High(ATrack) then Sel := 0;
+ end;
+ SDLK_UP:
+ begin
+ Dec(Sel);
+ if Sel < 0 then Sel := High(ATrack);
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenEditConvert.AddLyric(Start: integer; Text: string);
+var
+ N: integer;
+begin
+ for N := 0 to High(Note) do begin
+ if Note[N].Start = Start then begin
+ // check for new sentece
+ if Copy(Text, 1, 1) = '\' then Delete(Text, 1, 1);
+ if Copy(Text, 1, 1) = '/' then begin
+ Delete(Text, 1, 1);
+ Note[N].NewSentence := true;
+ end;
+
+ // overwrite lyric od append
+ if Note[N].Lyric = '-' then
+ Note[N].Lyric := Text
+ else
+ Note[N].Lyric := Note[N].Lyric + Text;
+ end;
+ end;
+end;
+
+procedure TScreenEditConvert.Extract;
+var
+ T: integer;
+ C: integer;
+ N: integer;
+ Nu: integer;
+ NoteTemp: TNuta;
+ Move: integer;
+ Max, Min: integer;
+begin
+ // song info
+ Song.Title := '';
+ Song.Artist := '';
+ Song.Mp3 := '';
+ Song.Resolution := 4;
+ SetLength(Song.BPM, 1);
+ Song.BPM[0].BPM := BPM*4;
+
+ SetLength(Note, 0);
+
+ // extract notes
+ for T := 0 to High(ATrack) do begin
+// if ATrack[T].Hear then begin
+ if ((ATrack[T].Status div 1) and 1) = 1 then begin
+ for N := 0 to High(ATrack[T].Note) do begin
+ if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then begin
+ Nu := Length(Note);
+ SetLength(Note, Nu + 1);
+ Note[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks);
+ Note[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks);
+ Note[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5;
+ Note[Nu].Lyric := '-';
+ end;
+ end;
+ end;
+ end;
+
+ // extract lyrics
+ for T := 0 to High(ATrack) do begin
+// if ATrack[T].Hear then begin
+ if ((ATrack[T].Status div 2) and 1) = 1 then begin
+ for N := 0 to High(ATrack[T].Note) do begin
+ if (ATrack[T].Note[N].EventType = 15) then begin
+// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI');
+ AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str);
+ end;
+ end;
+ end;
+ end;
+
+ // sort notes
+ for N := 0 to High(Note) do
+ for Nu := 0 to High(Note)-1 do
+ if Note[Nu].Start > Note[Nu+1].Start then begin
+ NoteTemp := Note[Nu];
+ Note[Nu] := Note[Nu+1];
+ Note[Nu+1] := NoteTemp;
+ end;
+
+ // move to 0 at beginning
+ Move := Note[0].Start;
+ for N := 0 to High(Note) do
+ Note[N].Start := Note[N].Start - Move;
+
+ // copy notes
+ SetLength(Lines.Line, 1);
+ Lines.Number := 1;
+ Lines.High := 0;
+
+ C := 0;
+ N := 0;
+ Lines.Line[C].HighNote := -1;
+
+ for Nu := 0 to High(Note) do begin
+ if Note[Nu].NewSentence then begin // nowa linijka
+ SetLength(Lines.Line, Length(Lines.Line)+1);
+ Lines.Number := Lines.Number + 1;
+ Lines.High := Lines.High + 1;
+ C := C + 1;
+ N := 0;
+ SetLength(Lines.Line[C].Note, 0);
+ Lines.Line[C].HighNote := -1;
+
+ //Calculate Start of the Last Sentence
+ if (C > 0) and (Nu > 0) then
+ begin
+ Max := Note[Nu].Start;
+ Min := Note[Nu-1].Start + Note[Nu-1].Len;
+
+ case (Max - Min) of
+ 0: Lines.Line[C].Start := Max;
+ 1: Lines.Line[C].Start := Max;
+ 2: Lines.Line[C].Start := Max - 1;
+ 3: Lines.Line[C].Start := Max - 2;
+ else
+ if ((Max - Min) > 4) then
+ Lines.Line[C].Start := Min + 2
+ else
+ Lines.Line[C].Start := Max;
+
+ end; // case
+
+ end;
+ end;
+
+ // tworzy miejsce na nowa nute
+ SetLength(Lines.Line[C].Note, Length(Lines.Line[C].Note)+1);
+
+ // dopisuje
+ Lines.Line[C].Note[N].Start := Note[Nu].Start;
+ Lines.Line[C].Note[N].Length := Note[Nu].Len;
+ Lines.Line[C].Note[N].Tone := Note[Nu].Tone;
+ Lines.Line[C].Note[N].Text := Note[Nu].Lyric;
+ //All Notes are Freestyle when Converted Fix:
+ Lines.Line[C].Note[N].NoteType := ntNormal;
+ Inc(N);
+ end;
+end;
+
+function TScreenEditConvert.SelectedNumber: integer;
+var
+ T: integer; // track
+begin
+ Result := 0;
+ for T := 0 to High(ATrack) do
+// if ATrack[T].Hear then Inc(Result);
+ if ((ATrack[T].Status div 1) and 1) = 1 then Inc(Result);
+end;
+
+{$IFDEF UseMIDIPort}
+procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent);
+begin
+// Log.LogStatus(IntToStr(event.event), 'MIDI');
+ MidiOut.PutShort(event.event, event.data1, event.data2);
+end;
+{$ENDIF}
+
+constructor TScreenEditConvert.Create;
+var
+ P: integer;
+begin
+ inherited Create;
+ AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(15, 5, 0, 0, 0, 'Open');
+// Button[High(Button)].Text[0].Size := 11;
+
+ AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(25, 5, 0, 0, 0, 'Play');
+
+ AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(25, 5, 0, 0, 0, 'Play Selected');
+
+ AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(20, 5, 0, 0, 0, 'Save');
+
+
+{ MidiOut := TMidiOutput.Create(nil);
+// MidiOut.Close;
+// MidiOut.DeviceID := 0;
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ Log.LogStatus(MidiOut.ProductName, 'MIDI');
+ MidiOut.Open;
+// MidiOut.SetVolume(100, 100); // temporary}
+
+ ConversionFileName := GamePath + 'file.mid';
+ {$IFDEF UseMIDIPort}
+ MidiFile := TMidiFile.Create(nil);
+ {$ENDIF}
+
+ for P := 0 to 100 do begin
+ ColR[P] := Random(10)/10;
+ ColG[P] := Random(10)/10;
+ ColB[P] := Random(10)/10;
+ end;
+
+end;
+
+procedure TScreenEditConvert.onShow;
+var
+ T: integer; // track
+ N: integer; // note
+ C: integer; // channel
+ CN: integer; // channel note
+begin
+ inherited;
+
+{$IFDEF UseMIDIPort}
+ MidiOut := TMidiOutput.Create(nil);
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ Log.LogStatus(MidiOut.ProductName, 'MIDI');
+ MidiOut.Open;
+
+
+ if FileExists(ConversionFileName) then
+ begin
+ MidiFile.Filename := ConversionFileName;
+ MidiFile.ReadFile;
+
+
+ Len := 0;
+ Sel := 0;
+ BPM := MidiFile.Bpm;
+ Ticks := MidiFile.TicksPerQuarter / 4;
+
+{ for T := 0 to MidiFile.NumberOfTracks-1 do begin
+ SetLength(Track, Length(Track)+1);
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+ Track[T].Name := MidiTrack.getName;
+
+ for N := 0 to MidiTrack.getEventCount-1 do begin
+ SetLength(Track[T].Note, Length(Track[T].Note)+1);
+ MidiEvent := MidiTrack.GetEvent(N);
+ Track[T].Note[N].Start := MidiEvent.time;
+ Track[T].Note[N].Len := MidiEvent.len;
+ Track[T].Note[N].Event := MidiEvent.event;
+ Track[T].Note[N].EventType := MidiEvent.event div 16;
+ Track[T].Note[N].Channel := MidiEvent.event and 15;
+ Track[T].Note[N].Data1 := MidiEvent.data1;
+ Track[T].Note[N].Data2 := MidiEvent.data2;
+ Track[T].Note[N].Str := MidiEvent.str;
+
+ if Track[T].Note[N].Start + Track[T].Note[N].Len > Len then
+ Len := Track[T].Note[N].Start + Track[T].Note[N].Len;
+ end;
+ end;}
+
+
+ SetLength(Channel, 16);
+ for T := 0 to 15 do
+ begin
+ Channel[T].Name := IntToStr(T+1);
+ SetLength(Channel[T].Note, 0);
+ Channel[T].Status := 0;
+ end;
+
+ for T := 0 to MidiFile.NumberOfTracks-1 do begin
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+
+ for N := 0 to MidiTrack.getEventCount-1 do begin
+ MidiEvent := MidiTrack.GetEvent(N);
+ C := MidiEvent.event and 15;
+
+ CN := Length(Channel[C].Note);
+ SetLength(Channel[C].Note, CN+1);
+
+ Channel[C].Note[CN].Start := MidiEvent.time;
+ Channel[C].Note[CN].Len := MidiEvent.len;
+ Channel[C].Note[CN].Event := MidiEvent.event;
+ Channel[C].Note[CN].EventType := MidiEvent.event div 16;
+ Channel[C].Note[CN].Channel := MidiEvent.event and 15;
+ Channel[C].Note[CN].Data1 := MidiEvent.data1;
+ Channel[C].Note[CN].Data2 := MidiEvent.data2;
+ Channel[C].Note[CN].Str := MidiEvent.str;
+
+ if Channel[C].Note[CN].Start + Channel[C].Note[CN].Len > Len then
+ Len := Channel[C].Note[CN].Start + Channel[C].Note[CN].Len;
+ end;
+ end;
+ ATrack := Channel;
+
+ end;
+
+ Interaction := 0;
+{$ENDIF}
+end;
+
+function TScreenEditConvert.Draw: boolean;
+var
+ Pet: integer;
+ Pet2: integer;
+ Bottom: real;
+ X: real;
+ Y: real;
+ H: real;
+ YSkip: real;
+begin
+ // draw static menu
+ inherited Draw;
+
+ Y := 100;
+
+ H := Length(ATrack)*40;
+ if H > 480 then H := 480;
+ Bottom := Y + H;
+
+ YSkip := H / Length(ATrack);
+
+ // select
+ DrawQuad(10, Y+Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8);
+
+ // selected - now me use Status System
+ for Pet := 0 to High(ATrack) do
+ if ATrack[Pet].Hear then
+ DrawQuad(10, Y+Pet*YSkip, 50, YSkip, 0.8, 0.3, 0.3);
+ glColor3f(0, 0, 0);
+ for Pet := 0 to High(ATrack) do begin
+ if ((ATrack[Pet].Status div 1) and 1) = 1 then begin
+ SetFontPos(25, Y + Pet*YSkip + 10);
+ SetFontSize(5);
+ glPrint('N');
+ end;
+ if ((ATrack[Pet].Status div 2) and 1) = 1 then begin
+ SetFontPos(40, Y + Pet*YSkip + 10);
+ SetFontSize(5);
+ glPrint('L');
+ end;
+ end;
+
+ DrawLine(10, Y, 10, Bottom, 0, 0, 0);
+ DrawLine(60, Y, 60, Bottom, 0, 0, 0);
+ DrawLine(790, Y, 790, Bottom, 0, 0, 0);
+
+ for Pet := 0 to Length(ATrack) do
+ DrawLine(10, Y+Pet*YSkip, 790, Y+Pet*YSkip, 0, 0, 0);
+
+ for Pet := 0 to High(ATrack) do begin
+ SetFontPos(11, Y + 10 + Pet*YSkip);
+ SetFontSize(5);
+ glPrint(pchar(ATrack[Pet].Name));
+ end;
+
+ for Pet := 0 to High(ATrack) do
+ for Pet2 := 0 to High(ATrack[Pet].Note) do begin
+ if ATrack[Pet].Note[Pet2].EventType = 9 then
+ DrawQuad(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + (Pet+1)*YSkip - ATrack[Pet].Note[Pet2].Data1*35/127, 3, 3, ColR[Pet], ColG[Pet], ColB[Pet]);
+ if ATrack[Pet].Note[Pet2].EventType = 15 then
+ DrawLine(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + 0.75 * YSkip + Pet*YSkip, 60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + YSkip + Pet*YSkip, ColR[Pet], ColG[Pet], ColB[Pet]);
+ end;
+
+ // playing line
+ {$IFDEF UseMIDIPort}
+ X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730;
+ {$ENDIF}
+ DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3);
+
+ Result := true;
+end;
+
+procedure TScreenEditConvert.onHide;
+begin
+{$IFDEF UseMIDIPort}
+ MidiOut.Close;
+ MidiOut.Free;
+{$ENDIF}
+end;
+
+end.
diff --git a/src/Screens/UScreenEditHeader.pas b/src/Screens/UScreenEditHeader.pas
new file mode 100644
index 00000000..28bf7682
--- /dev/null
+++ b/src/Screens/UScreenEditHeader.pas
@@ -0,0 +1,380 @@
+unit UScreenEditHeader;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu,
+ SDL,
+ USongs,
+ USong,
+ UThemes;
+
+type
+ TScreenEditHeader = class(TMenu)
+ public
+ CurrentSong: TSong;
+ TextTitle: integer;
+ TextArtist: integer;
+ TextMp3: integer;
+ TextBackground: integer;
+ TextVideo: integer;
+ TextVideoGAP: integer;
+ TextRelative: integer;
+ TextResolution: integer;
+ TextNotesGAP: integer;
+ TextStart: integer;
+ TextGAP: integer;
+ TextBPM: integer;
+ StaticTitle: integer;
+ StaticArtist: integer;
+ StaticMp3: integer;
+ StaticBackground: integer;
+ StaticVideo: integer;
+ StaticVideoGAP: integer;
+ StaticRelative: integer;
+ StaticResolution: integer;
+ StaticNotesGAP: integer;
+ StaticStart: integer;
+ StaticGAP: integer;
+ StaticBPM: integer;
+ Sel: array[0..11] of boolean;
+ procedure SetRoundButtons;
+
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, SysUtils, UFiles, USkins, UTexture;
+
+function TScreenEditHeader.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ T: integer;
+begin
+ Result := true;
+ If (PressedDown) Then begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+// Music.PlayBack;
+// FadeTo(@MainScreen);
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 1 then begin
+// Save;
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ case Interaction of
+ 0..0: InteractNext;
+ 1: Interaction := 0;
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ case Interaction of
+ 0: Interaction := 1;
+ 1..1: InteractPrev;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ case Interaction of
+ 0..1: Interaction := 2;
+ 2..12: InteractNext;
+ 13: Interaction := 0;
+ end;
+ end;
+
+ SDLK_UP:
+ begin
+ case Interaction of
+ 0..1: Interaction := 13;
+ 2: Interaction := 0;
+ 3..13: InteractPrev;
+ end;
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ T := Interaction - 2 + TextTitle;
+ if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin
+ Text[T].DeleteLastL;
+ SetRoundButtons;
+ end;
+ end;
+
+ end;
+ case CharCode of
+ #32..#255:
+ begin
+ if (Interaction >= 2) and (Interaction <= 13) then begin
+ Text[Interaction - 2 + TextTitle].Text :=
+ Text[Interaction - 2 + TextTitle].Text + CharCode;
+ SetRoundButtons;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEditHeader.Create;
+begin
+ inherited Create;
+
+ AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(15, 5, 'Open');
+
+ AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(20, 5, 'Save');
+
+ AddBox(80, 60, 640, 550);
+
+ AddText(160, 110 + 0*30, 0, 10, 0, 0, 0, 'Title:');
+ AddText(160, 110 + 1*30, 0, 10, 0, 0, 0, 'Artist:');
+ AddText(160, 110 + 2*30, 0, 10, 0, 0, 0, 'MP3:');
+
+ AddText(160, 110 + 4*30, 0, 10, 0, 0, 0, 'Background:');
+ AddText(160, 110 + 5*30, 0, 10, 0, 0, 0, 'Video:');
+ AddText(160, 110 + 6*30, 0, 10, 0, 0, 0, 'VideoGAP:');
+
+ AddText(160, 110 + 8*30, 0, 10, 0, 0, 0, 'Relative:');
+ AddText(160, 110 + 9*30, 0, 10, 0, 0, 0, 'Resolution:');
+ AddText(160, 110 + 10*30, 0, 10, 0, 0, 0, 'NotesGAP:');
+
+ AddText(160, 110 + 12*30, 0, 10, 0, 0, 0, 'Start:');
+ AddText(160, 110 + 13*30, 0, 10, 0, 0, 0, 'GAP:');
+ AddText(160, 110 + 14*30, 0, 10, 0, 0, 0, 'BPM:');
+
+ TextTitle := AddText(340, 110 + 0*30, 0, 10, 0, 0, 0, '');
+ TextArtist := AddText(340, 110 + 1*30, 0, 10, 0, 0, 0, '');
+ TextMp3 := AddText(340, 110 + 2*30, 0, 10, 0, 0, 0, '');
+
+ TextBackground := AddText(340, 110 + 4*30, 0, 10, 0, 0, 0, '');
+ TextVideo := AddText(340, 110 + 5*30, 0, 10, 0, 0, 0, '');
+ TextVideoGAP := AddText(340, 110 + 6*30, 0, 10, 0, 0, 0, '');
+
+ TextRelative := AddText(340, 110 + 8*30, 0, 10, 0, 0, 0, '');
+ TextResolution := AddText(340, 110 + 9*30, 0, 10, 0, 0, 0, '');
+ TextNotesGAP := AddText(340, 110 + 10*30, 0, 10, 0, 0, 0, '');
+
+ TextStart := AddText(340, 110 + 12*30, 0, 10, 0, 0, 0, '');
+ TextGAP := AddText(340, 110 + 13*30, 0, 10, 0, 0, 0, '');
+ TextBPM := AddText(340, 110 + 14*30, 0, 10, 0, 0, 0, '');
+
+ StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+
+ AddInteraction(iText, TextTitle);
+ AddInteraction(iText, TextArtist);
+ AddInteraction(iText, TextMp3);
+ AddInteraction(iText, TextBackground);
+ AddInteraction(iText, TextVideo);
+ AddInteraction(iText, TextVideoGAP);
+ AddInteraction(iText, TextRelative);
+ AddInteraction(iText, TextResolution);
+ AddInteraction(iText, TextNotesGAP);
+ AddInteraction(iText, TextStart);
+ AddInteraction(iText, TextGAP);
+ AddInteraction(iText, TextBPM);
+end;
+
+procedure TScreenEditHeader.onShow;
+begin
+ inherited;
+
+{ if FileExists(FileName) then begin // load file
+ CurrentSong.FileName := FileName;
+ SkanujPlik(CurrentSong);
+
+ SetLength(TrueBoolStrs, 1);
+ TrueBoolStrs[0] := 'yes';
+ SetLength(FalseBoolStrs, 1);
+ FalseBoolStrs[0] := 'no';
+
+ Text[TextTitle].Text := CurrentSong.Title;
+ Text[TextArtist].Text := CurrentSong.Artist;
+ Text[TextMP3].Text := CurrentSong.Mp3;
+ Text[TextBackground].Text := CurrentSong.Background;
+ Text[TextVideo].Text := CurrentSong.Video;
+ Text[TextVideoGAP].Text := FloatToStr(CurrentSong.VideoGAP);
+ Text[TextRelative].Text := BoolToStr(CurrentSong.Relative, true);
+ Text[TextResolution].Text := IntToStr(CurrentSong.Resolution);
+ Text[TextNotesGAP].Text := IntToStr(CurrentSong.NotesGAP);
+ Text[TextStart].Text := FloatToStr(CurrentSong.Start);
+ Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
+ Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM);
+ SetRoundButtons;
+ end;}
+
+ Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+{ glClearColor(1,1,1,1);
+
+ // control music
+ if PlaySentence then begin
+ // stop the music
+ if (Music.Position > PlayStopTime) then begin
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // click
+ if (Click) and (PlaySentence) then begin
+ AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
+ Text[TextDebug].Text := IntToStr(AktBeat);
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
+ Music.PlayClick;
+ LastClick := AktBeat;
+ end;
+ end;
+ end; // click
+ end; // if PlaySentence
+
+ Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
+ Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].LengthNote);
+
+ // Song info
+ Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
+ Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
+
+ // Note info
+ Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
+ Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+
+ // draw static menu
+ inherited Draw;
+
+ // draw notes
+ SingDrawNoteLines(20, 300, 780, 15);
+ SingDrawBeatDelimeters(40, 300, 760, 0);
+ SingDrawCzesc(40, 405, 760, 0);
+
+ // draw text
+ Lyric.Draw;}
+
+end;*)
+
+procedure TScreenEditHeader.SetRoundButtons;
+begin
+ if Length(Text[TextTitle].Text) > 0 then Static[StaticTitle].Visible := true
+ else Static[StaticTitle].Visible := false;
+
+ if Length(Text[TextArtist].Text) > 0 then Static[StaticArtist].Visible := true
+ else Static[StaticArtist].Visible := false;
+
+ if Length(Text[TextMp3].Text) > 0 then Static[StaticMp3].Visible := true
+ else Static[StaticMp3].Visible := false;
+
+ if Length(Text[TextBackground].Text) > 0 then Static[StaticBackground].Visible := true
+ else Static[StaticBackground].Visible := false;
+
+ if Length(Text[TextVideo].Text) > 0 then Static[StaticVideo].Visible := true
+ else Static[StaticVideo].Visible := false;
+
+ try
+ StrToFloat(Text[TextVideoGAP].Text);
+ if StrToFloat(Text[TextVideoGAP].Text)<> 0 then Static[StaticVideoGAP].Visible := true
+ else Static[StaticVideoGAP].Visible := false;
+ except
+ Static[StaticVideoGAP].Visible := false;
+ end;
+
+ if LowerCase(Text[TextRelative].Text) = 'yes' then Static[StaticRelative].Visible := true
+ else Static[StaticRelative].Visible := false;
+
+ try
+ StrToInt(Text[TextResolution].Text);
+ if (StrToInt(Text[TextResolution].Text) <> 0) and (StrToInt(Text[TextResolution].Text) >= 1)
+ then Static[StaticResolution].Visible := true
+ else Static[StaticResolution].Visible := false;
+ except
+ Static[StaticResolution].Visible := false;
+ end;
+
+ try
+ StrToInt(Text[TextNotesGAP].Text);
+ Static[StaticNotesGAP].Visible := true;
+ except
+ Static[StaticNotesGAP].Visible := false;
+ end;
+
+ // start
+ try
+ StrToFloat(Text[TextStart].Text);
+ if (StrToFloat(Text[TextStart].Text) > 0) then Static[StaticStart].Visible := true
+ else Static[StaticStart].Visible := false;
+ except
+ Static[StaticStart].Visible := false;
+ end;
+
+ // GAP
+ try
+ StrToFloat(Text[TextGAP].Text);
+ Static[StaticGAP].Visible := true;
+ except
+ Static[StaticGAP].Visible := false;
+ end;
+
+ // BPM
+ try
+ StrToFloat(Text[TextBPM].Text);
+ if (StrToFloat(Text[TextBPM].Text) > 0) then Static[StaticBPM].Visible := true
+ else Static[StaticBPM].Visible := false;
+ except
+ Static[StaticBPM].Visible := false;
+ end;
+
+end;
+
+(*procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/src/Screens/UScreenEditSub.pas b/src/Screens/UScreenEditSub.pas
new file mode 100644
index 00000000..2d98f6bc
--- /dev/null
+++ b/src/Screens/UScreenEditSub.pas
@@ -0,0 +1,1368 @@
+unit UScreenEditSub;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+{$I switches.inc}
+
+uses
+ UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ USong,
+ UIni,
+ ULog,
+ UTexture,
+ UMenuText,
+ UEditorLyrics,
+ Math,
+ gl,
+ {$IFDEF UseMIDIPort}
+ MidiOut,
+ {$ENDIF}
+ UThemes;
+
+type
+ TScreenEditSub = class(TMenu)
+ private
+ //Variable is True if no Song is loaded
+ Error: Boolean;
+
+ TextNote: integer;
+ TextSentence: integer;
+ TextTitle: integer;
+ TextArtist: integer;
+ TextMp3: integer;
+ TextBPM: integer;
+ TextGAP: integer;
+ TextDebug: integer;
+ TextNStart: integer;
+ TextNLength: integer;
+ TextNTon: integer;
+ TextNText: integer;
+ CurrentNote: integer;
+ PlaySentence: boolean;
+ PlaySentenceMidi: boolean;
+ PlayStopTime: real;
+ LastClick: integer;
+ Click: boolean;
+ CopySrc: integer;
+
+ {$IFDEF UseMIDIPort}
+ MidiOut: TMidiOutput;
+ {$endif}
+
+ MidiStart: real;
+ MidiStop: real;
+ MidiTime: real;
+ MidiPos: real;
+ MidiLastNote: integer;
+
+ TextEditMode: boolean;
+
+ Lyric: TEditorLyrics;
+
+ procedure NewBeat;
+ procedure DivideBPM;
+ procedure MultiplyBPM;
+ procedure LyricsCapitalize;
+ procedure LyricsCorrectSpaces;
+ procedure FixTimings;
+ procedure DivideSentence;
+ procedure JoinSentence;
+ procedure DivideNote;
+ procedure DeleteNote;
+ procedure TransposeNote(Transpose: integer);
+ procedure ChangeWholeTone(Tone: integer);
+ procedure MoveAllToEnd(Move: integer);
+ procedure MoveTextToRight;
+ procedure MarkSrc;
+ procedure PasteText;
+ procedure CopySentence(Src, Dst: integer);
+ procedure CopySentences(Src, Dst, Num: integer);
+ //Note Name Mod
+ function GetNoteName(Note: Integer): String;
+ public
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function ParseInputEditText(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+ function Draw: boolean; override;
+ procedure onHide; override;
+ end;
+
+implementation
+
+uses
+ UGraphic,
+ UDraw,
+ UMain,
+ USkins,
+ ULanguage;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenEditSub.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ SDL_ModState: Word;
+ R: real;
+begin
+ Result := true;
+
+ if TextEditMode then begin
+ Result := ParseInputEditText(PressedKey, CharCode, PressedDown);
+ end else begin
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
+
+ If (PressedDown) then begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ 'S':
+ begin
+ // Save Song
+ if SDL_ModState = KMOD_LSHIFT then
+ SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, true)
+ else
+ SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, false);
+
+ {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
+ // Save Song
+ SaveSongDebug(CurrentSong, Lines[0], 'C:\song.asm', false);}
+
+ Exit;
+ end;
+ 'D':
+ begin
+ // Divide lengths by 2
+ DivideBPM;
+ Exit;
+ end;
+ 'M':
+ begin
+ // Multiply lengths by 2
+ MultiplyBPM;
+ Exit;
+ end;
+ 'C':
+ begin
+ // Capitalize letter at the beginning of line
+ if SDL_ModState = 0 then
+ LyricsCapitalize;
+
+ // Correct spaces
+ if SDL_ModState = KMOD_LSHIFT then
+ LyricsCorrectSpaces;
+
+ // Copy sentence
+ if SDL_ModState = KMOD_LCTRL then
+ MarkSrc;
+
+ Exit;
+ end;
+ 'V':
+ begin
+ // Paste text
+ if SDL_ModState = KMOD_LCTRL then begin
+ if Lines[0].Line[Lines[0].Current].HighNote >= Lines[0].Line[CopySrc].HighNote then
+ PasteText
+ else
+ Log.LogStatus('PasteText: invalid range', 'TScreenEditSub.ParseInput');
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Lines[0].Current);
+ end;
+ end;
+ 'T':
+ begin
+ // Fixes timings between sentences
+ FixTimings;
+ Exit;
+ end;
+ 'P':
+ begin
+ if SDL_ModState = 0 then
+ begin
+ // Play Sentence
+ Click := true;
+ AudioPlayback.Stop;
+ R := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
+ if R <= AudioPlayback.Length then
+ begin
+ AudioPlayback.Position := R;
+ PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
+ PlaySentence := true;
+ AudioPlayback.Play;
+ LastClick := -100;
+ end;
+ end
+ else if SDL_ModState = KMOD_LSHIFT then
+ begin
+ PlaySentenceMidi := true;
+
+ MidiTime := USTime.GetTime;
+ MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
+ MidiStop := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
+
+ LastClick := -100;
+ end
+ else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then
+ begin
+ PlaySentenceMidi := true;
+ MidiTime := USTime.GetTime;
+ MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
+ MidiStop := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
+ LastClick := -100;
+
+ PlaySentence := true;
+ Click := true;
+ AudioPlayback.Stop;
+ AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start)+0{-0.10};
+ PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_)+0;
+ AudioPlayback.Play;
+ LastClick := -100;
+ end;
+ Exit;
+ end;
+
+ // Golden Note Patch
+ 'G':
+ begin
+ if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntGolden) then
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
+ else
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntGolden;
+
+ Exit;
+ end;
+
+ // Freestyle Note Patch
+ 'F':
+ begin
+ if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntFreestyle) then
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
+ else
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntFreestyle;
+
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ FadeTo(@ScreenSong);
+ end;
+
+ SDLK_BACKQUOTE:
+ begin
+ // Increase Note Length (same as Alt + Right)
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
+ Inc(Lines[0].Line[Lines[0].Current].End_);
+ end;
+
+ SDLK_EQUALS:
+ begin
+ // Increase BPM
+ if SDL_ModState = 0 then
+ CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
+ if SDL_ModState = KMOD_LSHIFT then
+ CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM + 4; // (1/1)
+ if SDL_ModState = KMOD_LCTRL then
+ CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
+ end;
+
+ SDLK_MINUS:
+ begin
+ // Decrease BPM
+ if SDL_ModState = 0 then
+ CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) - 1) / 5;
+ if SDL_ModState = KMOD_LSHIFT then
+ CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM - 4;
+ if SDL_ModState = KMOD_LCTRL then
+ CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) - 1) / 25;
+ end;
+
+ SDLK_4:
+ begin
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Lines[0].Current);
+ CopySentence(CopySrc+1, Lines[0].Current+1);
+ CopySentence(CopySrc+2, Lines[0].Current+2);
+ CopySentence(CopySrc+3, Lines[0].Current+3);
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
+ CopySentences(CopySrc, Lines[0].Current, 4);
+ end;
+ end;
+ SDLK_5:
+ begin
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Lines[0].Current);
+ CopySentence(CopySrc+1, Lines[0].Current+1);
+ CopySentence(CopySrc+2, Lines[0].Current+2);
+ CopySentence(CopySrc+3, Lines[0].Current+3);
+ CopySentence(CopySrc+4, Lines[0].Current+4);
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
+ CopySentences(CopySrc, Lines[0].Current, 5);
+ end;
+ end;
+
+ SDLK_9:
+ begin
+ // Decrease GAP
+ if SDL_ModState = 0 then
+ CurrentSong.GAP := CurrentSong.GAP - 10;
+ if SDL_ModState = KMOD_LSHIFT then
+ CurrentSong.GAP := CurrentSong.GAP - 1000;
+ end;
+ SDLK_0:
+ begin
+ // Increase GAP
+ if SDL_ModState = 0 then
+ CurrentSong.GAP := CurrentSong.GAP + 10;
+ if SDL_ModState = KMOD_LSHIFT then
+ CurrentSong.GAP := CurrentSong.GAP + 1000;
+ end;
+
+ SDLK_KP_PLUS:
+ begin
+ // Increase tone of all notes
+ if SDL_ModState = 0 then
+ ChangeWholeTone(1);
+ if SDL_ModState = KMOD_LSHIFT then
+ ChangeWholeTone(12);
+ end;
+
+ SDLK_KP_MINUS:
+ begin
+ // Decrease tone of all notes
+ if SDL_ModState = 0 then
+ ChangeWholeTone(-1);
+ if SDL_ModState = KMOD_LSHIFT then
+ ChangeWholeTone(-12);
+ end;
+
+ SDLK_SLASH:
+ begin
+ if SDL_ModState = 0 then begin
+ // Insert start of sentece
+ if CurrentNote > 0 then
+ DivideSentence;
+ end;
+
+ if SDL_ModState = KMOD_LSHIFT then begin
+ // Join next sentence with current
+ if Lines[0].Current < Lines[0].High then
+ JoinSentence;
+ end;
+
+ if SDL_ModState = KMOD_LCTRL then begin
+ // divide note
+ DivideNote;
+ end;
+
+ end;
+
+ SDLK_F4:
+ begin
+ // Enter Text Edit Mode
+ TextEditMode := true;
+ end;
+
+ SDLK_SPACE:
+ begin
+ // Play Sentence
+ PlaySentenceMidi := false; // stop midi
+ PlaySentence := true;
+ Click := false;
+ AudioPlayback.Stop;
+ AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+ PlayStopTime := (GetTimeFromBeat(
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start +
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length));
+ AudioPlayback.Play;
+ LastClick := -100;
+ end;
+
+ SDLK_RETURN:
+ begin
+ end;
+
+ SDLK_LCTRL:
+ begin
+ end;
+
+ SDLK_DELETE:
+ begin
+ if SDL_ModState = KMOD_LCTRL then begin
+ // moves text to right in current sentence
+ DeleteNote;
+ end;
+ end;
+
+ SDLK_PERIOD:
+ begin
+ // moves text to right in current sentence
+ MoveTextToRight;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ // right
+ if SDL_ModState = 0 then begin
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Inc(CurrentNote);
+ if CurrentNote > Lines[0].Line[Lines[0].Current].HighNote then CurrentNote := 0;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ Lyric.Selected := CurrentNote;
+ end;
+
+ // ctrl + right
+ if SDL_ModState = KMOD_LCTRL then begin
+ if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then begin
+ Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+ if CurrentNote = 0 then begin
+ Inc(Lines[0].Line[Lines[0].Current].Start);
+ end;
+ end;
+ end;
+
+ // shift + right
+ if SDL_ModState = KMOD_LSHIFT then begin
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+ if CurrentNote = 0 then begin
+ Inc(Lines[0].Line[Lines[0].Current].Start);
+ end;
+ if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
+ Inc(Lines[0].Line[Lines[0].Current].End_);
+ end;
+
+ // alt + right
+ if SDL_ModState = KMOD_LALT then begin
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
+ Inc(Lines[0].Line[Lines[0].Current].End_);
+ end;
+
+ // alt + ctrl + shift + right = move all from cursor to right
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ MoveAllToEnd(1);
+ end;
+
+ end;
+
+ SDLK_LEFT:
+ begin
+ // left
+ if SDL_ModState = 0 then begin
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Dec(CurrentNote);
+ if CurrentNote = -1 then CurrentNote := Lines[0].Line[Lines[0].Current].HighNote;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ Lyric.Selected := CurrentNote;
+ end;
+
+ // ctrl + left
+ if SDL_ModState = KMOD_LCTRL then begin
+ Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ if CurrentNote = 0 then begin
+ Dec(Lines[0].Line[Lines[0].Current].Start);
+ end;
+ end;
+
+ // shift + left
+ if SDL_ModState = KMOD_LSHIFT then begin
+ Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+
+ // resizing sentences
+ if CurrentNote = 0 then begin
+ Dec(Lines[0].Line[Lines[0].Current].Start);
+ end;
+
+ if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
+ Dec(Lines[0].Line[Lines[0].Current].End_);
+
+ end;
+
+ // alt + left
+ if SDL_ModState = KMOD_LALT then begin
+ if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then begin
+ Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
+ Dec(Lines[0].Line[Lines[0].Current].End_);
+ end;
+ end;
+
+ // alt + ctrl + shift + right = move all from cursor to left
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ MoveAllToEnd(-1);
+ end;
+
+ end;
+
+ SDLK_DOWN:
+ begin
+
+ // skip to next sentence
+ if SDL_ModState = 0 then begin {$IFDEF UseMIDIPort}
+ MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
+ PlaySentenceMidi := false;
+ {$endif}
+
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Inc(Lines[0].Current);
+ CurrentNote := 0;
+ if Lines[0].Current > Lines[0].High then Lines[0].Current := 0;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+
+ Lyric.AddLine(Lines[0].Current);
+ Lyric.Selected := 0;
+ AudioPlayback.Stop;
+ PlaySentence := false;
+ end;
+
+ // decrease tone
+ if SDL_ModState = KMOD_LCTRL then begin
+ TransposeNote(-1);
+ end;
+
+ end;
+
+ SDLK_UP:
+ begin
+
+ // skip to previous sentence
+ if SDL_ModState = 0 then begin
+ {$IFDEF UseMIDIPort}
+ MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
+ PlaySentenceMidi := false;
+ {$endif}
+
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Dec(Lines[0].Current);
+ CurrentNote := 0;
+ if Lines[0].Current = -1 then Lines[0].Current := Lines[0].High;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+
+ Lyric.AddLine(Lines[0].Current);
+ Lyric.Selected := 0;
+ AudioPlayback.Stop;
+ PlaySentence := false;
+ end;
+
+ // increase tone
+ if SDL_ModState = KMOD_LCTRL then begin
+ TransposeNote(1);
+ end;
+ end;
+
+ end; // case
+ end;
+ end; // if
+end;
+
+function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ SDL_ModState: Word;
+begin
+ // used when in Text Edit Mode
+ Result := true;
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
+
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE:
+ begin
+ FadeTo(@ScreenSong);
+ end;
+ SDLK_F4, SDLK_RETURN:
+ begin
+ // Exit Text Edit Mode
+ TextEditMode := false;
+ end;
+ SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL:
+ begin
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text :=
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text + CharCode;
+ end;
+ SDLK_BACKSPACE:
+ begin
+ Delete(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text,
+ Length(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text), 1);
+ end;
+ SDLK_RIGHT:
+ begin
+ // right
+ if SDL_ModState = 0 then begin
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Inc(CurrentNote);
+ if CurrentNote > Lines[0].Line[Lines[0].Current].HighNote then CurrentNote := 0;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ Lyric.Selected := CurrentNote;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ // left
+ if SDL_ModState = 0 then begin
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0;
+ Dec(CurrentNote);
+ if CurrentNote = -1 then CurrentNote := Lines[0].Line[Lines[0].Current].HighNote;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ Lyric.Selected := CurrentNote;
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenEditSub.NewBeat;
+begin
+ // click
+{ for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNut do
+ if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = Czas.AktBeat) then begin
+ // old}
+// Music.PlayClick;
+end;
+
+procedure TScreenEditSub.DivideBPM;
+var
+ C: integer;
+ N: integer;
+begin
+ CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM / 2;
+ for C := 0 to Lines[0].High do begin
+ Lines[0].Line[C].Start := Lines[0].Line[C].Start div 2;
+ Lines[0].Line[C].End_ := Lines[0].Line[C].End_ div 2;
+ for N := 0 to Lines[0].Line[C].HighNote do begin
+ Lines[0].Line[C].Note[N].Start := Lines[0].Line[C].Note[N].Start div 2;
+ Lines[0].Line[C].Note[N].Length := Round(Lines[0].Line[C].Note[N].Length / 2);
+ end; // N
+ end; // C
+end;
+
+procedure TScreenEditSub.MultiplyBPM;
+var
+ C: integer;
+ N: integer;
+begin
+ CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM * 2;
+ for C := 0 to Lines[0].High do begin
+ Lines[0].Line[C].Start := Lines[0].Line[C].Start * 2;
+ Lines[0].Line[C].End_ := Lines[0].Line[C].End_ * 2;
+ for N := 0 to Lines[0].Line[C].HighNote do begin
+ Lines[0].Line[C].Note[N].Start := Lines[0].Line[C].Note[N].Start * 2;
+ Lines[0].Line[C].Note[N].Length := Lines[0].Line[C].Note[N].Length * 2;
+ end; // N
+ end; // C
+end;
+
+procedure TScreenEditSub.LyricsCapitalize;
+var
+ C: integer;
+ N: integer; // temporary
+ S: string;
+begin
+ // temporary
+{ for C := 0 to Lines[0].High do
+ for N := 0 to Lines[0].Line[C].HighNut do
+ Lines[0].Line[C].Note[N].Text := AnsiLowerCase(Lines[0].Line[C].Note[N].Text);}
+
+ for C := 0 to Lines[0].High do begin
+ S := AnsiUpperCase(Copy(Lines[0].Line[C].Note[0].Text, 1, 1));
+ S := S + Copy(Lines[0].Line[C].Note[0].Text, 2, Length(Lines[0].Line[C].Note[0].Text)-1);
+ Lines[0].Line[C].Note[0].Text := S;
+ end; // C
+end;
+
+procedure TScreenEditSub.LyricsCorrectSpaces;
+var
+ C: integer;
+ N: integer;
+begin
+ for C := 0 to Lines[0].High do begin
+ // correct starting spaces in the first word
+ while Copy(Lines[0].Line[C].Note[0].Text, 1, 1) = ' ' do
+ Lines[0].Line[C].Note[0].Text := Copy(Lines[0].Line[C].Note[0].Text, 2, 100);
+
+ // move spaces on the start to the end of the previous note
+ for N := 1 to Lines[0].Line[C].HighNote do begin
+ while (Copy(Lines[0].Line[C].Note[N].Text, 1, 1) = ' ') do begin
+ Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 2, 100);
+ Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
+ end;
+ end; // N
+
+ // correct '-' to '- '
+ for N := 0 to Lines[0].Line[C].HighNote do begin
+ if Lines[0].Line[C].Note[N].Text = '-' then
+ Lines[0].Line[C].Note[N].Text := '- ';
+ end; // N
+
+ // add space to the previous note when the current word is '- '
+ for N := 1 to Lines[0].Line[C].HighNote do begin
+ if Lines[0].Line[C].Note[N].Text = '- ' then
+ Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
+ end; // N
+
+ // correct too many spaces at the end of note
+ for N := 0 to Lines[0].Line[C].HighNote do begin
+ while Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text)-1, 2) = ' ' do
+ Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 1, Length(Lines[0].Line[C].Note[N].Text)-1);
+ end; // N
+
+ // and correct if there is no space at the end of sentence
+ N := Lines[0].Line[C].HighNote;
+ if Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text), 1) <> ' ' then
+ Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N].Text + ' ';
+
+ end; // C
+end;
+
+procedure TScreenEditSub.FixTimings;
+var
+ C: integer;
+ S: integer;
+ Min: integer;
+ Max: integer;
+begin
+ for C := 1 to Lines[0].High do begin
+ with Lines[0].Line[C-1] do begin
+ Min := Note[HighNote].Start + Note[HighNote].Length;
+ Max := Lines[0].Line[C].Note[0].Start;
+ case (Max - Min) of
+ 0: S := Max;
+ 1: S := Max;
+ 2: S := Max - 1;
+ 3: S := Max - 2;
+ else
+ if ((Max - Min) > 4) then
+ S := Min + 2
+ else
+ S := Max;
+ end; // case
+
+ Lines[0].Line[C].Start := S;
+ end; // with
+ end; // for
+end;
+
+procedure TScreenEditSub.DivideSentence;
+var
+ C: integer;
+ CStart: integer;
+ CNew: integer;
+ CLen: integer;
+ N: integer;
+ NStart: integer;
+ NHigh: integer;
+begin
+ // increase sentence length by 1
+ CLen := Length(Lines[0].Line);
+ SetLength(Lines[0].Line, CLen + 1);
+ Inc(Lines[0].Number);
+ Inc(Lines[0].High);
+
+ // move needed sentences to one forward. newly has the copy of divided sentence
+ CStart := Lines[0].Current;
+ for C := CLen-1 downto CStart do
+ Lines[0].Line[C+1] := Lines[0].Line[C];
+
+ // clear and set new sentence
+ CNew := CStart + 1;
+ NStart := CurrentNote;
+ Lines[0].Line[CNew].Start := Lines[0].Line[CStart].Note[NStart].Start;
+ Lines[0].Line[CNew].Lyric := '';
+ Lines[0].Line[CNew].LyricWidth := 0;
+ Lines[0].Line[CNew].End_ := 0;
+ Lines[0].Line[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
+ Lines[0].Line[CNew].HighNote := -1;
+ SetLength(Lines[0].Line[CNew].Note, 0);
+
+ // move right notes to new sentences
+ NHigh := Lines[0].Line[CStart].HighNote;
+ for N := NStart to NHigh do begin
+ // increase sentence counters
+ with Lines[0].Line[CNew] do
+ begin
+ Inc(HighNote);
+ SetLength(Note, HighNote + 1);
+ Note[HighNote] := Note[N];
+ End_ := Note[HighNote].Start + Note[HighNote].Length;
+
+ if Note[HighNote].Tone < BaseNote then
+ BaseNote := Note[HighNote].Tone;
+ end;
+ end;
+
+ // clear old notes and set sentence counters
+ Lines[0].Line[CStart].HighNote := NStart - 1;
+ Lines[0].Line[CStart].End_ := Lines[0].Line[CStart].Note[NStart-1].Start +
+ Lines[0].Line[CStart].Note[NStart-1].Length;
+ SetLength(Lines[0].Line[CStart].Note, Lines[0].Line[CStart].HighNote + 1);
+
+ Lines[0].Current := Lines[0].Current + 1;
+ CurrentNote := 0;
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ Lyric.AddLine(Lines[0].Current);
+end;
+
+procedure TScreenEditSub.JoinSentence;
+var
+ C: integer;
+ N: integer;
+ NStart: integer;
+ NDst: integer;
+begin
+ C := Lines[0].Current;
+
+ // set new sentence
+ NStart := Lines[0].Line[C].HighNote + 1;
+ Lines[0].Line[C].HighNote := Lines[0].Line[C].HighNote + Lines[0].Line[C+1].HighNote + 1;
+ SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);
+
+ // move right notes to new sentences
+ for N := 0 to Lines[0].Line[C+1].HighNote do begin
+ NDst := NStart + N;
+ Lines[0].Line[C].Note[NDst] := Lines[0].Line[C+1].Note[N];
+ end;
+
+ // increase sentence counters
+ NDst := Lines[0].Line[C].HighNote;
+ Lines[0].Line[C].End_ := Lines[0].Line[C].Note[NDst].Start +
+ Lines[0].Line[C].Note[NDst].Length;
+
+ // move needed sentences to one backward.
+ for C := Lines[0].Current + 1 to Lines[0].High - 1 do
+ Lines[0].Line[C] := Lines[0].Line[C+1];
+
+ // increase sentence length by 1
+ SetLength(Lines[0].Line, Length(Lines[0].Line) - 1);
+ Dec(Lines[0].Number);
+ Dec(Lines[0].High);
+end;
+
+procedure TScreenEditSub.DivideNote;
+var
+ C: integer;
+ N: integer;
+begin
+ C := Lines[0].Current;
+
+ with Lines[0].Line[C] do
+ begin
+ Inc(HighNote);
+ SetLength(Note, HighNote + 1);
+
+ // we copy all notes including selected one
+ for N := HighNote downto CurrentNote+1 do begin
+ Note[N] := Note[N-1];
+ end;
+
+ // me slightly modify new note
+ Note[CurrentNote].Length := 1;
+ Inc(Note[CurrentNote+1].Start);
+ Dec(Note[CurrentNote+1].Length);
+ Note[CurrentNote+1].Text := '- ';
+ Note[CurrentNote+1].Color := 0;
+ end;
+end;
+
+procedure TScreenEditSub.DeleteNote;
+var
+ C: integer;
+ N: integer;
+ NLen: integer;
+begin
+ C := Lines[0].Current;
+
+ //Do Not delete Last Note
+ if (Lines[0].High > 0) OR (Lines[0].Line[C].HighNote > 0) then
+ begin
+
+ // we copy all notes from the next to the selected one
+ for N := CurrentNote+1 to Lines[0].Line[C].HighNote do begin
+ Lines[0].Line[C].Note[N-1] := Lines[0].Line[C].Note[N];
+ end;
+
+ Dec(Lines[0].Line[C].HighNote);
+ if (Lines[0].Line[C].HighNote >= 0) then
+ begin
+ SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);
+
+ // me slightly modify new note
+ if CurrentNote > Lines[0].Line[C].HighNote then
+ Dec(CurrentNote);
+
+ Lines[0].Line[C].Note[CurrentNote].Color := 1;
+ end
+ //Last Note of current Sentence Deleted - > Delete Sentence
+ else
+ begin
+ //Move all Sentences after the current to the Left
+ for N := C+1 to Lines[0].High do
+ Lines[0].Line[N-1] := Lines[0].Line[N];
+
+ //Delete Last Sentence
+ SetLength(Lines[0].Line, Lines[0].High);
+ Lines[0].High := High(Lines[0].Line);
+ Lines[0].Number := Length(Lines[0].Line);
+
+ CurrentNote := 0;
+ if (C > 0) then
+ Lines[0].Current := C - 1
+ else
+ Lines[0].Current := 0;
+
+ Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
+ end;
+ end;
+end;
+
+procedure TScreenEditSub.TransposeNote(Transpose: integer);
+begin
+ Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone, Transpose);
+end;
+
+procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
+var
+ C: integer;
+ N: integer;
+begin
+ for C := 0 to Lines[0].High do begin
+ Lines[0].Line[C].BaseNote := Lines[0].Line[C].BaseNote + Tone;
+ for N := 0 to Lines[0].Line[C].HighNote do
+ Lines[0].Line[C].Note[N].Tone := Lines[0].Line[C].Note[N].Tone + Tone;
+ end;
+end;
+
+procedure TScreenEditSub.MoveAllToEnd(Move: integer);
+var
+ C: integer;
+ N: integer;
+ NStart: integer;
+begin
+ for C := Lines[0].Current to Lines[0].High do begin
+ NStart := 0;
+ if C = Lines[0].Current then NStart := CurrentNote;
+ for N := NStart to Lines[0].Line[C].HighNote do begin
+ Inc(Lines[0].Line[C].Note[N].Start, Move); // move note start
+
+ if N = 0 then begin // fix beginning
+ Inc(Lines[0].Line[C].Start, Move);
+ end;
+
+ if N = Lines[0].Line[C].HighNote then // fix ending
+ Inc(Lines[0].Line[C].End_, Move);
+
+ end; // for
+ end; // for
+end;
+
+procedure TScreenEditSub.MoveTextToRight;
+var
+ C: integer;
+ N: integer;
+ NHigh: integer;
+begin
+{ C := Lines[0].Current;
+
+ for N := Lines[0].Line[C].HighNut downto 1 do begin
+ Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
+ end; // for
+
+ Lines[0].Line[C].Note[0].Text := '- ';}
+
+ C := Lines[0].Current;
+ NHigh := Lines[0].Line[C].HighNote;
+
+ // last word
+ Lines[0].Line[C].Note[NHigh].Text := Lines[0].Line[C].Note[NHigh-1].Text + Lines[0].Line[C].Note[NHigh].Text;
+
+ // other words
+ for N := NHigh - 1 downto CurrentNote + 1 do begin
+ Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
+ end; // for
+ Lines[0].Line[C].Note[CurrentNote].Text := '- ';
+end;
+
+procedure TScreenEditSub.MarkSrc;
+begin
+ CopySrc := Lines[0].Current;
+end;
+
+procedure TScreenEditSub.PasteText;
+var
+ C: integer;
+ N: integer;
+begin
+ C := Lines[0].Current;
+
+ for N := 0 to Lines[0].Line[CopySrc].HighNote do
+ Lines[0].Line[C].Note[N].Text := Lines[0].Line[CopySrc].Note[N].Text;
+end;
+
+procedure TScreenEditSub.CopySentence(Src, Dst: integer);
+var
+ N: integer;
+ Time1: integer;
+ Time2: integer;
+ TD: integer;
+begin
+ Time1 := Lines[0].Line[Src].Note[0].Start;
+ Time2 := Lines[0].Line[Dst].Note[0].Start;
+ TD := Time2-Time1;
+
+ SetLength(Lines[0].Line[Dst].Note, Lines[0].Line[Src].HighNote + 1);
+ Lines[0].Line[Dst].HighNote := Lines[0].Line[Src].HighNote;
+ for N := 0 to Lines[0].Line[Src].HighNote do begin
+ Lines[0].Line[Dst].Note[N].Text := Lines[0].Line[Src].Note[N].Text;
+ Lines[0].Line[Dst].Note[N].Length := Lines[0].Line[Src].Note[N].Length;
+ Lines[0].Line[Dst].Note[N].Tone := Lines[0].Line[Src].Note[N].Tone;
+ Lines[0].Line[Dst].Note[N].Start := Lines[0].Line[Src].Note[N].Start + TD;
+ end;
+ N := Lines[0].Line[Src].HighNote;
+ Lines[0].Line[Dst].End_ := Lines[0].Line[Dst].Note[N].Start + Lines[0].Line[Dst].Note[N].Length;
+end;
+
+procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
+var
+ C: integer;
+begin
+ // create place for new sentences
+ SetLength(Lines[0].Line, Lines[0].Number + Num - 1);
+
+ // moves sentences next to the destination
+ for C := Lines[0].High downto Dst + 1 do begin
+ Lines[0].Line[C + Num - 1] := Lines[0].Line[C];
+ end;
+
+ // prepares new sentences: sets sentence start and create first note
+ for C := 1 to Num-1 do begin
+ Lines[0].Line[Dst + C].Start := Lines[0].Line[Dst + C - 1].Note[0].Start +
+ (Lines[0].Line[Src + C].Note[0].Start - Lines[0].Line[Src + C - 1].Note[0].Start);
+ SetLength(Lines[0].Line[Dst + C].Note, 1);
+ Lines[0].Line[Dst + C].HighNote := 0;
+ Lines[0].Line[Dst + C].Note[0].Start := Lines[0].Line[Dst + C].Start;
+ Lines[0].Line[Dst + C].Note[0].Length := 1;
+ Lines[0].Line[Dst + C].End_ := Lines[0].Line[Dst + C].Start + 1;
+ end;
+
+ // increase counters
+ Lines[0].Number := Lines[0].Number + Num - 1;
+ Lines[0].High := Lines[0].High + Num - 1;
+
+ for C := 0 to Num-1 do
+ CopySentence(Src + C, Dst + C);
+end;
+
+
+constructor TScreenEditSub.Create;
+begin
+ inherited Create;
+ SetLength(Player, 1);
+
+ // linijka
+ AddStatic(20, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), TEXTURE_TYPE_COLORIZED);
+ AddText(40, 17, 1, 6, 1, 1, 1, 'Line');
+ TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');
+
+ // Note
+ AddStatic(220, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), TEXTURE_TYPE_COLORIZED);
+ AddText(242, 17, 1, 6, 1, 1, 1, 'Note');
+ TextNote := AddText(320, 14, 1, 8, 0, 0, 0, '0 / 0');
+
+ // file info
+ AddStatic(150, 50, 500, 150, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(151, 52, 498, 146, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+ AddText(180, 65, 0, 8, 0, 0, 0, 'Title:');
+ AddText(180, 90, 0, 8, 0, 0, 0, 'Artist:');
+ AddText(180, 115, 0, 8, 0, 0, 0, 'Mp3:');
+ AddText(180, 140, 0, 8, 0, 0, 0, 'BPM:');
+ AddText(180, 165, 0, 8, 0, 0, 0, 'GAP:');
+
+ TextTitle := AddText(250, 65, 0, 8, 0, 0, 0, 'a');
+ TextArtist := AddText(250, 90, 0, 8, 0, 0, 0, 'b');
+ TextMp3 := AddText(250, 115, 0, 8, 0, 0, 0, 'c');
+ TextBPM := AddText(250, 140, 0, 8, 0, 0, 0, 'd');
+ TextGAP := AddText(250, 165, 0, 8, 0, 0, 0, 'e');
+
+{ AddInteraction(2, TextTitle);
+ AddInteraction(2, TextArtist);
+ AddInteraction(2, TextMp3);
+ AddInteraction(2, TextBPM);
+ AddInteraction(2, TextGAP);}
+
+ // note info
+ AddText(20, 190, 0, 8, 0, 0, 0, 'Start:');
+ AddText(20, 215, 0, 8, 0, 0, 0, 'Duration:');
+ AddText(20, 240, 0, 8, 0, 0, 0, 'Tone:');
+ AddText(20, 265, 0, 8, 0, 0, 0, 'Text:');
+
+ TextNStart := AddText(120, 190, 0, 8, 0, 0, 0, 'a');
+ TextNLength := AddText(120, 215, 0, 8, 0, 0, 0, 'b');
+ TextNTon := AddText(120, 240, 0, 8, 0, 0, 0, 'c');
+ TextNText := AddText(120, 265, 0, 8, 0, 0, 0, 'd');
+
+ // debug
+ TextDebug := AddText(30, 550, 0, 8, 0, 0, 0, '');
+
+end;
+
+procedure TScreenEditSub.onShow;
+begin
+ inherited;
+
+ Log.LogStatus('Initializing', 'TEditScreen.onShow');
+ Lyric := TEditorLyrics.Create;
+
+ ResetSingTemp;
+
+ try
+ //Check if File is XML
+ if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml'
+ then Error := not CurrentSong.LoadXMLSong()
+ else Error := not CurrentSong.LoadSong();
+ except
+ Error := True;
+ end;
+
+ if Error then
+ begin
+ //Error Loading Song -> Go back to Song Screen and Show some Error Message
+ FadeTo(@ScreenSong);
+ ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+ Exit;
+ end
+ else begin
+ {$IFDEF UseMIDIPort}
+ MidiOut := TMidiOutput.Create(nil);
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ MidiOut.Open;
+ {$ENDIF}
+ Text[TextTitle].Text := CurrentSong.Title;
+ Text[TextArtist].Text := CurrentSong.Artist;
+ Text[TextMp3].Text := CurrentSong.Mp3;
+
+ Lines[0].Current := 0;
+ CurrentNote := 0;
+ Lines[0].Line[0].Note[0].Color := 1;
+ AudioPlayback.Open(CurrentSong.Path + CurrentSong.Mp3);
+ //Set Down Music Volume for Better hearability of Midi Sounds
+ //Music.SetVolume(0.4);
+
+ Lyric.Clear;
+ Lyric.X := 400;
+ Lyric.Y := 500;
+ Lyric.Align := 1;
+ Lyric.Size := 14;
+ Lyric.ColR := 0;
+ Lyric.ColG := 0;
+ Lyric.ColB := 0;
+ Lyric.ColSR := Skin_FontHighlightR;
+ Lyric.ColSG := Skin_FontHighlightG;
+ Lyric.ColSB := Skin_FontHighlightB;
+ Lyric.AddLine(0);
+ Lyric.Selected := 0;
+
+ NotesH := 7;
+ NotesW := 4;
+
+ end;
+
+// Interaction := 0;
+ TextEditMode := false;
+end;
+
+function TScreenEditSub.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+ glClearColor(1,1,1,1);
+
+ // midi music
+ if PlaySentenceMidi then begin
+ {$IFDEF UseMIDIPort}
+ MidiPos := USTime.GetTime - MidiTime + MidiStart;
+
+
+ // stop the music
+ if (MidiPos > MidiStop) then begin
+ MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
+ PlaySentenceMidi := false;
+ end;
+ {$ENDIF}
+
+ // click
+ AktBeat := Floor(GetMidBeat(MidiPos - CurrentSong.GAP / 1000));
+ Text[TextDebug].Text := IntToStr(AktBeat);
+
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNote do
+ if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = AktBeat) then
+ begin
+
+
+ LastClick := AktBeat;
+ {$IFDEF UseMIDIPort}
+ if Pet > 0 then
+ MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[Pet-1].Tone + 60, 127);
+ MidiOut.PutShort($91, Lines[0].Line[Lines[0].Current].Note[Pet].Tone + 60, 127);
+ MidiLastNote := Pet;
+ {$ENDIF}
+
+ end;
+ end;
+ end; // if PlaySentenceMidi
+
+ // mp3 music
+ if PlaySentence then begin
+ // stop the music
+ if (AudioPlayback.Position > PlayStopTime) then
+ begin
+ AudioPlayback.Stop;
+ PlaySentence := false;
+ end;
+
+ // click
+ if (Click) and (PlaySentence) then begin
+// AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
+ AktBeat := Floor(GetMidBeat(AudioPlayback.Position - CurrentSong.GAP / 1000));
+ Text[TextDebug].Text := IntToStr(AktBeat);
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNote do
+ if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = AktBeat) then
+ begin
+ AudioPlayback.PlaySound( SoundLib.Click );
+ LastClick := AktBeat;
+ end;
+ end;
+ end; // click
+ end; // if PlaySentence
+
+
+ Text[TextSentence].Text := IntToStr(Lines[0].Current + 1) + ' / ' + IntToStr(Lines[0].Number);
+ Text[TextNote].Text := IntToStr(CurrentNote + 1) + ' / ' + IntToStr(Lines[0].Line[Lines[0].Current].HighNote + 1);
+
+ // Song info
+ Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
+ Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
+
+ //Error reading Variables when no Song is loaded
+ if not Error then
+ begin
+ // Note info
+ Text[TextNStart].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
+ Text[TextNLength].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
+ Text[TextNTon].Text := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' ( ' + GetNoteName(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' )';
+ Text[TextNText].Text := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
+ end;
+
+ // Text Edit Mode
+ if TextEditMode then
+ Text[TextNText].Text := Text[TextNText].Text + '|';
+
+ // draw static menu
+ inherited Draw;
+
+ // draw notes
+ SingDrawNoteLines(20, 300, 780, 15);
+ //Error Drawing when no Song is loaded
+ if not Error then
+ begin
+ SingDrawBeatDelimeters(40, 300, 760, 0);
+ EditDrawLine(40, 405, 760, 0, 15);
+ end;
+
+ // draw text
+ Lyric.Draw;
+
+ Result := true;
+end;
+
+procedure TScreenEditSub.onHide;
+begin
+ {$IFDEF UseMIDIPort}
+ MidiOut.Close;
+ MidiOut.Free;
+ {$ENDIF}
+ Lyric.Free;
+ //Music.SetVolume(1.0);
+end;
+
+function TScreenEditSub.GetNoteName(Note: Integer): String;
+var N1, N2: Integer;
+begin
+ if (Note > 0) then
+ begin
+ N1 := Note mod 12;
+ N2 := Note div 12;
+ end
+ else
+ begin
+ N1 := (Note + (-Trunc(Note/12)+1)*12) mod 12;
+ N2 := -1;
+ end;
+
+
+
+ case N1 of
+ 0: Result := 'c';
+ 1: Result := 'c#';
+ 2: Result := 'd';
+ 3: Result := 'd#';
+ 4: Result := 'e';
+ 5: Result := 'f';
+ 6: Result := 'f#';
+ 7: Result := 'g';
+ 8: Result := 'g#';
+ 9: Result := 'a';
+ 10: Result := 'b';
+ 11: Result := 'h';
+ end;
+
+ case N2 of
+ 0: Result := UpperCase(Result); //Normal Uppercase Note, 1: Normal lowercase Note
+ 2: Result := Result + ''''; //One Striped
+ 3: Result := Result + ''''''; //Two Striped
+ 4: Result := Result + ''''''''; //etc.
+ 5: Result := Result + '''''''''';
+ 6: Result := Result + '''''''''''';
+ 7: Result := Result + '''''''''''''';
+ end;
+end;
+
+end.
diff --git a/src/Screens/UScreenLevel.pas b/src/Screens/UScreenLevel.pas
new file mode 100644
index 00000000..1ea79e7f
--- /dev/null
+++ b/src/Screens/UScreenLevel.pas
@@ -0,0 +1,103 @@
+unit UScreenLevel;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenLevel = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic,
+ UMain,
+ UIni,
+ USong,
+ UTexture;
+
+function TScreenLevel.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenName);
+ end;
+
+ SDLK_RETURN:
+ begin
+ Ini.Difficulty := Interaction;
+ Ini.SaveLevel;
+ AudioPlayback.PlaySound(SoundLib.Start);
+ //Set Standard Mode
+ ScreenSong.Mode := smNormal;
+ FadeTo(@ScreenSong);
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenLevel.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Level);
+
+ AddButton(Theme.Level.ButtonEasy);
+ AddButton(Theme.Level.ButtonMedium);
+ AddButton(Theme.Level.ButtonHard);
+
+ Interaction := 0;
+end;
+
+procedure TScreenLevel.onShow;
+begin
+ inherited;
+
+ Interaction := Ini.Difficulty;
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenLevel.SetAnimationProgress(Progress: real);
+begin
+ Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenLoading.pas b/src/Screens/UScreenLoading.pas
new file mode 100644
index 00000000..ee3c6f7f
--- /dev/null
+++ b/src/Screens/UScreenLoading.pas
@@ -0,0 +1,57 @@
+unit UScreenLoading;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UThemes,
+ gl;
+
+type
+ TScreenLoading = class(TMenu)
+ public
+ Fadeout: boolean;
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function GetBGTexNum: GLUInt;
+ end;
+
+implementation
+
+uses UGraphic,
+ UTime;
+
+function TScreenLoading.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+end;
+
+constructor TScreenLoading.Create;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Loading);
+
+ Fadeout := false;
+end;
+
+procedure TScreenLoading.onShow;
+begin
+ inherited;
+end;
+
+function TScreenLoading.GetBGTexNum: GLUInt;
+begin
+ Result := Self.BackImg.TexNum;
+end;
+
+end.
diff --git a/src/Screens/UScreenMain.pas b/src/Screens/UScreenMain.pas
new file mode 100644
index 00000000..4dbdaaa1
--- /dev/null
+++ b/src/Screens/UScreenMain.pas
@@ -0,0 +1,256 @@
+unit UScreenMain;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ UDisplay,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes;
+
+type
+ TScreenMain = class(TMenu)
+ public
+ TextDescription: integer;
+ TextDescriptionLong: integer;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: cardinal; CharCode: widechar;
+ PressedDown: boolean): boolean; override;
+ procedure onShow; override;
+ procedure InteractNext; override;
+ procedure InteractPrev; override;
+ procedure InteractInc; override;
+ procedure InteractDec; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses
+ UGraphic,
+ UMain,
+ UIni,
+ UTexture,
+ USongs,
+ Textgl,
+ ULanguage,
+ UParty,
+ UDLLManager,
+ UScreenCredits,
+ USkins;
+
+function TScreenMain.ParseInput(PressedKey: cardinal; CharCode: widechar;
+ PressedDown: boolean): boolean;
+var
+ SDL_ModState: word;
+begin
+ Result := True;
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT +
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ if (PressedDown) then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := False;
+ Exit;
+ end;
+ 'C':
+ begin
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ FadeTo(@ScreenCredits, SoundLib.Start);
+ Exit;
+ end;
+ end;
+ 'M':
+ begin
+ if (Ini.Players >= 1) and (Length(DLLMan.Plugins) >= 1) then
+ begin
+ FadeTo(@ScreenPartyOptions, SoundLib.Start);
+ Exit;
+ end;
+ end;
+
+ 'S':
+ begin
+ FadeTo(@ScreenStatMain, SoundLib.Start);
+ Exit;
+ end;
+
+ 'E':
+ begin
+ FadeTo(@ScreenEdit, SoundLib.Start);
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ Result := False;
+ end;
+
+ SDLK_RETURN:
+ begin
+ //Solo
+ if (Interaction = 0) then
+ begin
+ if (Songs.SongList.Count >= 1) then
+ begin
+ if (Ini.Players >= 0) and (Ini.Players <= 3) then
+ PlayersPlay := Ini.Players + 1;
+ if (Ini.Players = 4) then
+ PlayersPlay := 6;
+
+ ScreenName.Goto_SingScreen := False;
+ FadeTo(@ScreenName, SoundLib.Start);
+ end
+ else //show error message
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
+ end;
+
+ //Multi
+ if Interaction = 1 then
+ begin
+ if (Songs.SongList.Count >= 1) then
+ begin
+ if (Length(DLLMan.Plugins) >= 1) then
+ begin
+ FadeTo(@ScreenPartyOptions, SoundLib.Start);
+ end
+ else //show error message, No Plugins Loaded
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS'));
+ end
+ else //show error message, No Songs Loaded
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
+ end;
+
+ //Stats
+ if Interaction = 2 then
+ begin
+ FadeTo(@ScreenStatMain, SoundLib.Start);
+ end;
+
+ //Editor
+ if Interaction = 3 then
+ begin
+ FadeTo(@ScreenEdit, SoundLib.Start);
+ end;
+
+ //Options
+ if Interaction = 4 then
+ begin
+ FadeTo(@ScreenOptions, SoundLib.Start);
+ end;
+
+ //Exit
+ if Interaction = 5 then
+ begin
+ Result := False;
+ end;
+ end;
+ {**
+ * Up and Down could be done at the same time,
+ * but I don't want to declare variables inside
+ * functions like this one, called so many times
+ *}
+ SDLK_DOWN: InteractInc;
+ SDLK_UP: InteractDec;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN:
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenMain.Create;
+begin
+ inherited Create;
+{**
+ * Attention ^^:
+ * New Creation Order needed because of LoadFromTheme
+ * and Button Collections.
+ * At First Custom Texts and Statics
+ * Then LoadFromTheme
+ * after LoadFromTheme the Buttons and Selects
+ *}
+ TextDescription := AddText(Theme.Main.TextDescription);
+ TextDescriptionLong := AddText(Theme.Main.TextDescriptionLong);
+
+ LoadFromTheme(Theme.Main);
+
+ AddButton(Theme.Main.ButtonSolo);
+ AddButton(Theme.Main.ButtonMulti);
+ AddButton(Theme.Main.ButtonStat);
+ AddButton(Theme.Main.ButtonEditor);
+ AddButton(Theme.Main.ButtonOptions);
+ AddButton(Theme.Main.ButtonExit);
+
+ Interaction := 0;
+end;
+
+procedure TScreenMain.onShow;
+begin
+ inherited;
+{**
+ * Start background music
+ *}
+ SoundLib.StartBgMusic;
+end;
+
+procedure TScreenMain.InteractNext;
+begin
+ inherited InteractNext;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+end;
+
+procedure TScreenMain.InteractPrev;
+begin
+ inherited InteractPrev;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+end;
+
+procedure TScreenMain.InteractDec;
+begin
+ inherited InteractDec;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+end;
+
+procedure TScreenMain.InteractInc;
+begin
+ inherited InteractInc;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+end;
+
+procedure TScreenMain.SetAnimationProgress(Progress: real);
+begin
+ Static[0].Texture.ScaleW := Progress;
+ Static[0].Texture.ScaleH := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenName.pas b/src/Screens/UScreenName.pas
new file mode 100644
index 00000000..f2d59f05
--- /dev/null
+++ b/src/Screens/UScreenName.pas
@@ -0,0 +1,243 @@
+unit UScreenName;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenName = class(TMenu)
+ public
+ Goto_SingScreen: Boolean; //If True then next Screen in SingScreen
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, UCommon;
+
+
+function TScreenName.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+SDL_ModState: Word;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ // check normal keys
+ if (IsAlphaNumericChar(CharCode) or
+ {(CharCode in [' ','-','_','!',',','<','/','*','?','''','"']))} IsPunctuationChar(CharCode)) then
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
+ Exit;
+ end;
+
+ // check special keys
+ case PressedKey of
+ // Templates for Names Mod
+ SDLK_F1:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
+ end;
+ SDLK_F2:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
+ end;
+ SDLK_F3:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
+ end;
+ SDLK_F4:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
+ end;
+ SDLK_F5:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
+ end;
+ SDLK_F6:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
+ end;
+ SDLK_F7:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
+ end;
+ SDLK_F8:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
+ end;
+ SDLK_F9:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
+ end;
+ SDLK_F10:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
+ end;
+ SDLK_F11:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
+ end;
+ SDLK_F12:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
+ end;
+
+
+ SDLK_BACKSPACE:
+ begin
+ Button[Interaction].Text[0].DeleteLastL;
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Ini.SaveNames;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ if GoTo_SingScreen then
+ FadeTo(@ScreenSong)
+ else
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ for I := 1 to 6 do
+ Ini.Name[I-1] := Button[I-1].Text[0].Text;
+ Ini.SaveNames;
+ AudioPlayback.PlaySound(SoundLib.Start);
+
+ if GoTo_SingScreen then
+ FadeTo(@ScreenSing)
+ else
+ FadeTo(@ScreenLevel);
+
+ GoTo_SingScreen := False;
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenName.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Name);
+
+
+ for I := 1 to 6 do
+ AddButton(Theme.Name.ButtonPlayer[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenName.onShow;
+var
+ I: integer;
+begin
+ inherited;
+
+ for I := 1 to 6 do
+ Button[I-1].Text[0].Text := Ini.Name[I-1];
+
+ for I := 1 to PlayersPlay do begin
+ Button[I-1].Visible := true;
+ Button[I-1].Selectable := true;
+ end;
+
+ for I := PlayersPlay+1 to 6 do begin
+ Button[I-1].Visible := false;
+ Button[I-1].Selectable := false;
+ end;
+
+end;
+
+procedure TScreenName.SetAnimationProgress(Progress: real);
+var
+ I: integer;
+begin
+ for I := 1 to 6 do
+ Button[I-1].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenOpen.pas b/src/Screens/UScreenOpen.pas
new file mode 100644
index 00000000..186b9b47
--- /dev/null
+++ b/src/Screens/UScreenOpen.pas
@@ -0,0 +1,173 @@
+unit UScreenOpen;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText,
+ ULyrics, Math, gl, UThemes;
+
+type
+ TScreenOpen = class(TMenu)
+ private
+ TextF: array[0..1] of integer;
+ TextN: integer;
+ public
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ BackScreen: pointer;
+ procedure AddBox(X, Y, W, H: real);
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+// function Draw: boolean; override;
+// procedure Finish;
+ end;
+
+implementation
+uses UGraphic, UDraw, UMain, USkins;
+
+function TScreenOpen.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+
+ if (PressedDown) then begin // Key Down
+ // check normal keys
+ case CharCode of
+ '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '.', ':', '\':
+ begin
+ if Interaction = 0 then begin
+ Text[TextN].Text := Text[TextN].Text + CharCode;
+ end;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ 8: // del
+ begin
+ if Interaction = 0 then
+ begin
+ Text[TextN].DeleteLastL;
+ end;
+ end;
+
+
+ SDLK_ESCAPE :
+ begin
+ //Empty Filename and go to last Screen
+ ConversionFileName := '';
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end;
+
+ SDLK_RETURN:
+ begin
+ if (Interaction = 2) then begin
+ //Update Filename and go to last Screen
+ ConversionFileName := Text[TextN].Text;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end
+ else if (Interaction = 1) then
+ begin
+ //Empty Filename and go to last Screen
+ ConversionFileName := '';
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+
+ SDLK_DOWN:
+ begin
+ end;
+
+ SDLK_UP:
+ begin
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenOpen.AddBox(X, Y, W, H: real);
+begin
+ AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+end;
+
+constructor TScreenOpen.Create;
+begin
+ inherited Create;
+
+ // linijka
+{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED);
+ AddText(35, 17, 1, 6, 1, 1, 1, 'Linijka');
+ TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');}
+
+ // file list
+// AddBox(400, 100, 350, 450);
+
+// TextF[0] := AddText(430, 155, 0, 8, 0, 0, 0, 'a');
+// TextF[1] := AddText(430, 180, 0, 8, 0, 0, 0, 'a');
+
+ // file name
+ AddBox(20, 540, 500, 40);
+ TextN := AddText(50, 548, 0, 8, 0, 0, 0, ConversionFileName);
+ AddInteraction(iText, TextN);
+
+ // buttons
+ {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(30, 5, 0, 0, 0, 'OK');}
+ // buttons
+ AddButton(540, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(30, 5, 0, 0, 0, 'OK');
+
+
+end;
+
+procedure TScreenOpen.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+(*function TScreenEditSub.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+
+end;
+
+procedure TScreenEditSub.Finish;
+begin
+//
+end;*)
+
+end.
+
diff --git a/src/Screens/UScreenOptions.pas b/src/Screens/UScreenOptions.pas
new file mode 100644
index 00000000..24633115
--- /dev/null
+++ b/src/Screens/UScreenOptions.pas
@@ -0,0 +1,196 @@
+unit UScreenOptions;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptions = class(TMenu)
+ public
+ TextDescription: integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractNext; override;
+ procedure InteractPrev; override;
+ procedure InteractNextRow; override;
+ procedure InteractPrevRow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic;
+
+function TScreenOptions.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+// Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 0 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsGame);
+ end;
+
+ if SelInteraction = 1 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsGraphics);
+ end;
+
+ if SelInteraction = 2 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsSound);
+ end;
+
+ if SelInteraction = 3 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsLyrics);
+ end;
+
+ if SelInteraction = 4 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsThemes);
+ end;
+
+ if SelInteraction = 5 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsRecord);
+ end;
+
+ if SelInteraction = 6 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenOptionsAdvanced);
+ end;
+
+ if SelInteraction = 7 then
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+ end;
+ SDLK_DOWN: InteractNextRow;
+ SDLK_UP: InteractPrevRow;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenOptions.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ TextDescription := AddText(Theme.Options.TextDescription);
+
+ LoadFromTheme(Theme.Options);
+
+ AddButton(Theme.Options.ButtonGame);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[0]);
+
+ AddButton(Theme.Options.ButtonGraphics);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[1]);
+
+ AddButton(Theme.Options.ButtonSound);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[2]);
+
+ AddButton(Theme.Options.ButtonLyrics);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[3]);
+
+ AddButton(Theme.Options.ButtonThemes);
+ if (Length(Button[4].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[4]);
+
+ AddButton(Theme.Options.ButtonRecord);
+ if (Length(Button[5].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[5]);
+
+ AddButton(Theme.Options.ButtonAdvanced);
+ if (Length(Button[6].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[6]);
+
+ AddButton(Theme.Options.ButtonExit);
+ if (Length(Button[7].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptions.onShow;
+begin
+ inherited;
+end;
+
+procedure TScreenOptions.InteractNext;
+begin
+ inherited InteractNext;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+procedure TScreenOptions.InteractPrev;
+begin
+ inherited InteractPrev;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+procedure TScreenOptions.InteractNextRow;
+begin
+ inherited InteractNextRow;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+procedure TScreenOptions.InteractPrevRow;
+begin
+ inherited InteractPrevRow;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+procedure TScreenOptions.SetAnimationProgress(Progress: real);
+begin
+ Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress;
+ Button[3].Texture.ScaleW := Progress;
+ Button[4].Texture.ScaleW := Progress;
+ Button[5].Texture.ScaleW := Progress;
+ Button[6].Texture.ScaleW := Progress;
+ Button[7].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsAdvanced.pas b/src/Screens/UScreenOptionsAdvanced.pas
new file mode 100644
index 00000000..be8895e1
--- /dev/null
+++ b/src/Screens/UScreenOptionsAdvanced.pas
@@ -0,0 +1,113 @@
+unit UScreenOptionsAdvanced;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsAdvanced = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, SysUtils;
+
+function TScreenOptionsAdvanced.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ // Escape -> save nothing - just leave this screen
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ //SelectLoadAnimation Hidden because it is useless atm
+ //if SelInteraction = 7 then begin
+ if SelInteraction = 6 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ //SelectLoadAnimation Hidden because it is useless atm
+ //if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ //SelectLoadAnimation Hidden because it is useless atm
+ //if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsAdvanced.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsAdvanced);
+
+ //SelectLoadAnimation Hidden because it is useless atm
+ //AddSelect(Theme.OptionsAdvanced.SelectLoadAnimation, Ini.LoadAnimation, ILoadAnimation);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectScreenFade, Ini.ScreenFade, IScreenFade);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectEffectSing, Ini.EffectSing, IEffectSing);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectLineBonus, Ini.LineBonus, ILineBonus);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectOnSongClick, Ini.OnSongClick, IOnSongClick);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectAskbeforeDel, Ini.AskBeforeDel, IAskbeforeDel);
+ AddSelectSlide(Theme.OptionsAdvanced.SelectPartyPopup, Ini.PartyPopup, IPartyPopup);
+
+ AddButton(Theme.OptionsAdvanced.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsAdvanced.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsGame.pas b/src/Screens/UScreenOptionsGame.pas
new file mode 100644
index 00000000..2dc8dd7f
--- /dev/null
+++ b/src/Screens/UScreenOptionsGame.pas
@@ -0,0 +1,117 @@
+unit UScreenOptionsGame;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes, USongs;
+
+type
+ TScreenOptionsGame = class(TMenu)
+ public
+ old_Tabs, old_Sorting: integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure RefreshSongs;
+ end;
+
+implementation
+
+uses UGraphic, SysUtils;
+
+function TScreenOptionsGame.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ RefreshSongs;
+
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 6 then begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ RefreshSongs;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsGame.Create;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsGame);
+
+ //Refresh Songs Patch
+ old_Sorting := Ini.Sorting;
+ old_Tabs := Ini.Tabs;
+
+ AddSelectSlide(Theme.OptionsGame.SelectPlayers, Ini.Players, IPlayers);
+ AddSelectSlide(Theme.OptionsGame.SelectDifficulty, Ini.Difficulty, IDifficulty);
+ AddSelectSlide(Theme.OptionsGame.SelectLanguage, Ini.Language, ILanguage);
+ AddSelectSlide(Theme.OptionsGame.SelectTabs, Ini.Tabs, ITabs);
+ AddSelectSlide(Theme.OptionsGame.SelectSorting, Ini.Sorting, ISorting);
+ AddSelectSlide(Theme.OptionsGame.SelectDebug, Ini.Debug, IDebug);
+
+ AddButton(Theme.OptionsGame.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+end;
+
+//Refresh Songs Patch
+procedure TScreenOptionsGame.RefreshSongs;
+begin
+if (ini.Sorting <> old_Sorting) or (ini.Tabs <> old_Tabs) then
+ ScreenSong.Refresh;
+end;
+
+procedure TScreenOptionsGame.onShow;
+begin
+ inherited;
+
+// Interaction := 0;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsGraphics.pas b/src/Screens/UScreenOptionsGraphics.pas
new file mode 100644
index 00000000..f2b6faa2
--- /dev/null
+++ b/src/Screens/UScreenOptionsGraphics.pas
@@ -0,0 +1,113 @@
+unit UScreenOptionsGraphics;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsGraphics = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, SysUtils, TypInfo;
+
+function TScreenOptionsGraphics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ // Escape -> save nothing - just leave this screen
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+{ if SelInteraction <= 1 then begin
+ Restart := true;
+ end;}
+ if SelInteraction = 6 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ // FIXME: changing the video mode does not work this way in windows
+ // and MacOSX as all textures will be invalidated through this.
+ // See the ALT+TAB code too.
+ {$IFDEF Linux}
+ Reinitialize3D();
+ {$ENDIF}
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < 6) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < 6) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsGraphics.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+ LoadFromTheme(Theme.OptionsGraphics);
+
+ AddSelectSlide(Theme.OptionsGraphics.SelectResolution, Ini.Resolution, IResolution);
+ AddSelectSlide(Theme.OptionsGraphics.SelectFullscreen, Ini.Fullscreen, IFullscreen);
+ AddSelectSlide(Theme.OptionsGraphics.SelectDepth, Ini.Depth, IDepth);
+ AddSelectSlide(Theme.OptionsGraphics.SelectVisualizer, Ini.VisualizerOption, IVisualizer);
+ AddSelectSlide(Theme.OptionsGraphics.SelectOscilloscope, Ini.Oscilloscope, IOscilloscope);
+ AddSelectSlide(Theme.OptionsGraphics.SelectMovieSize, Ini.MovieSize, IMovieSize);
+
+
+ AddButton(Theme.OptionsGraphics.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+end;
+
+procedure TScreenOptionsGraphics.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsLyrics.pas b/src/Screens/UScreenOptionsLyrics.pas
new file mode 100644
index 00000000..42f1fadb
--- /dev/null
+++ b/src/Screens/UScreenOptionsLyrics.pas
@@ -0,0 +1,103 @@
+unit UScreenOptionsLyrics;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsLyrics = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, SysUtils;
+
+function TScreenOptionsLyrics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ // Escape -> save nothing - just leave this screen
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 3 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsLyrics.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsLyrics);
+
+ AddSelectSlide(Theme.OptionsLyrics.SelectLyricsFont, Ini.LyricsFont, ILyricsFont);
+ AddSelectSlide(Theme.OptionsLyrics.SelectLyricsEffect, Ini.LyricsEffect, ILyricsEffect);
+ //AddSelect(Theme.OptionsLyrics.SelectSolmization, Ini.Solmization, ISolmization); GAH!!!!11 DIE!!!
+ AddSelectSlide(Theme.OptionsLyrics.SelectNoteLines, Ini.NoteLines, INoteLines);
+
+
+ AddButton(Theme.OptionsLyrics.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+end;
+
+procedure TScreenOptionsLyrics.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsRecord.pas b/src/Screens/UScreenOptionsRecord.pas
new file mode 100644
index 00000000..885f7db5
--- /dev/null
+++ b/src/Screens/UScreenOptionsRecord.pas
@@ -0,0 +1,785 @@
+unit UScreenOptionsRecord;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UMusic,
+ URecord,
+ UMenu;
+
+type
+ TDrawState = record
+ ChannelIndex: integer;
+ R, G, B: real; // mapped player color (normal)
+ RD, GD, BD: real; // mapped player color (dark)
+ end;
+
+ TPeakInfo = record
+ Volume: single;
+ Time: cardinal;
+ end;
+
+ TScreenOptionsRecord = class(TMenu)
+ private
+ // max. count of input-channels determined for all devices
+ MaxChannelCount: integer;
+
+ // current input device
+ CurrentDeviceIndex: integer;
+ PreviewDeviceIndex: integer;
+
+ // string arrays for select-slide options
+ InputSourceNames: array of string;
+ InputDeviceNames: array of string;
+
+ // dynamic generated themes for channel select-sliders
+ SelectSlideChannelTheme: array of TThemeSelectSlide;
+
+ // indices for widget-updates
+ SelectInputSourceID: integer;
+ SelectSlideChannelID: array of integer;
+
+ // interaction IDs
+ ExitButtonIID: integer;
+
+ // dummy data for non-available channels
+ ChannelToPlayerMapDummy: integer;
+
+ // preview channel-buffers
+ PreviewChannel: array of TCaptureBuffer;
+ ChannelPeak: array of TPeakInfo;
+
+ // Device source volume
+ SourceVolume: single;
+ NextVolumePollTime: cardinal;
+
+ procedure StartPreview;
+ procedure StopPreview;
+ procedure UpdateInputDevice;
+ procedure ChangeVolume(VolumeChange: single);
+ procedure DrawVolume(x, y, Width, Height: single);
+ procedure DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
+ procedure DrawPitch(const State: TDrawState; x, y, Width, Height: single);
+ public
+ constructor Create; override;
+ function Draw: boolean; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ end;
+
+const
+ PeakDecay = 0.2; // strength of peak-decay (reduction after one sec)
+
+const
+ BarHeight = 11; // height of each bar (volume/vu-meter/pitch)
+ BarUpperSpacing = 1; // spacing between a bar-area and the previous widget
+ BarLowerSpacing = 3; // spacing between a bar-area and the next widget
+ SourceBarsTotalHeight = BarHeight + BarUpperSpacing + BarLowerSpacing;
+ ChannelBarsTotalHeight = 2*BarHeight + BarUpperSpacing + BarLowerSpacing;
+
+implementation
+
+uses
+ SysUtils,
+ Math,
+ SDL,
+ gl,
+ TextGL,
+ UGraphic,
+ UDraw,
+ UMain,
+ UMenuSelectSlide,
+ UMenuText,
+ UFiles,
+ UDisplay,
+ UIni,
+ ULog;
+
+function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ '+':
+ begin
+ // FIXME: add a nice volume-slider instead
+ // or at least provide visualization and acceleration if the user holds the key pressed.
+ ChangeVolume(0.02);
+ end;
+ '-':
+ begin
+ // FIXME: add a nice volume-slider instead
+ // or at least provide visualization and acceleration if the user holds the key pressed.
+ ChangeVolume(-0.02);
+ end;
+ 'T':
+ begin
+ if ((SDL_GetModState() and KMOD_SHIFT) <> 0) then
+ Ini.ThresholdIndex := (Ini.ThresholdIndex + Length(IThresholdVals) - 1) mod Length(IThresholdVals)
+ else
+ Ini.ThresholdIndex := (Ini.ThresholdIndex + 1) mod Length(IThresholdVals);
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ // Escape -> save nothing - just leave this screen
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if (SelInteraction = ExitButtonIID) then
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ UpdateInputDevice;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ UpdateInputDevice;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsRecord.Create;
+var
+ DeviceIndex: integer;
+ SourceIndex: integer;
+ ChannelIndex: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+ ChannelTheme: ^TThemeSelectSlide;
+ //ButtonTheme: TThemeButton;
+ WidgetYPos: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsRecord);
+
+ // set CurrentDeviceIndex to a valid device
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ CurrentDeviceIndex := 0
+ else
+ CurrentDeviceIndex := -1;
+
+ PreviewDeviceIndex := -1;
+
+ WidgetYPos := 0;
+
+ // init sliders if at least one device was detected
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ // init device-selection slider
+ SetLength(InputDeviceNames, Length(AudioInputProcessor.DeviceList));
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ InputDeviceNames[DeviceIndex] := AudioInputProcessor.DeviceList[DeviceIndex].Name;
+ end;
+ // add device-selection slider (InteractionID: 0)
+ AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, CurrentDeviceIndex, InputDeviceNames);
+
+ // init source-selection slider
+ SetLength(InputSourceNames, Length(InputDevice.Source));
+ for SourceIndex := 0 to High(InputDevice.Source) do
+ begin
+ InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
+ end;
+ // add source-selection slider (InteractionID: 1)
+ SelectInputSourceID := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput,
+ InputDeviceCfg.Input, InputSourceNames);
+
+ // add space for source volume bar
+ WidgetYPos := Theme.OptionsRecord.SelectSlideInput.Y +
+ Theme.OptionsRecord.SelectSlideInput.H +
+ SourceBarsTotalHeight;
+
+ // find max. channel count of all devices
+ MaxChannelCount := 0;
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ if (AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels > MaxChannelCount) then
+ MaxChannelCount := AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels;
+ end;
+
+ // init channel-to-player mapping sliders
+ SetLength(SelectSlideChannelID, MaxChannelCount);
+ SetLength(SelectSlideChannelTheme, MaxChannelCount);
+
+ for ChannelIndex := 0 to MaxChannelCount-1 do
+ begin
+ // copy reference slide
+ SelectSlideChannelTheme[ChannelIndex] :=
+ Theme.OptionsRecord.SelectSlideChannel;
+ // set current channel-theme
+ ChannelTheme := @SelectSlideChannelTheme[ChannelIndex];
+ // adjust vertical position
+ ChannelTheme.Y := WidgetYPos;
+ // calc size of next slide (add space for bars)
+ WidgetYPos := WidgetYPos + ChannelTheme.H + ChannelBarsTotalHeight;
+ // append channel index to name
+ ChannelTheme.Text := ChannelTheme.Text + IntToStr(ChannelIndex+1);
+
+ // show/hide widgets depending on whether the channel exists
+ if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
+ begin
+ // current device has this channel
+
+ // add slider
+ SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
+ InputDeviceCfg.ChannelToPlayerMap[ChannelIndex], IChannelPlayer);
+ end
+ else
+ begin
+ // current device does not have that many channels
+
+ // add slider but hide it and assign a dummy variable to it
+ SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
+ ChannelToPlayerMapDummy, IChannelPlayer);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
+ end;
+ end;
+ end;
+
+ // add Exit-button
+ //ButtonTheme := Theme.OptionsRecord.ButtonExit;
+ // adjust button position
+ //if (WidgetYPos <> 0) then
+ // ButtonTheme.Y := WidgetYPos;
+ //AddButton(ButtonTheme);
+ // I uncommented the stuff above, because it's not skinable :X
+ AddButton(Theme.OptionsRecord.ButtonExit);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+ // store InteractionID
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ ExitButtonIID := MaxChannelCount + 2
+ else
+ ExitButtonIID := 0;
+
+ // set focus
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsRecord.UpdateInputDevice;
+var
+ SourceIndex: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+ ChannelIndex: integer;
+begin
+ //Log.LogStatus('Update input-device', 'TScreenOptionsRecord.UpdateCard') ;
+
+ StopPreview();
+
+ // set CurrentDeviceIndex to a valid device
+ if (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList)) then
+ CurrentDeviceIndex := 0;
+
+ // update sliders if at least one device was detected
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ // update source-selection slider
+ SetLength(InputSourceNames, Length(InputDevice.Source));
+ for SourceIndex := 0 to High(InputDevice.Source) do
+ begin
+ InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
+ end;
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectInputSourceID,
+ InputSourceNames, InputDeviceCfg.Input);
+
+ // update channel-to-player mapping sliders
+ for ChannelIndex := 0 to MaxChannelCount-1 do
+ begin
+ // show/hide widgets depending on whether the channel exists
+ if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
+ begin
+ // current device has this channel
+
+ // show slider
+ UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
+ SelectSlideChannelID[ChannelIndex], IChannelPlayer,
+ InputDeviceCfg.ChannelToPlayerMap[ChannelIndex]);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := true;
+ end
+ else
+ begin
+ // current device does not have that many channels
+
+ // hide slider and assign a dummy variable to it
+ UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
+ SelectSlideChannelID[ChannelIndex], IChannelPlayer,
+ ChannelToPlayerMapDummy);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
+ end;
+ end;
+ end;
+
+ StartPreview();
+end;
+
+procedure TScreenOptionsRecord.ChangeVolume(VolumeChange: single);
+var
+ InputDevice: TAudioInputDevice;
+ Volume: single;
+begin
+ // validate CurrentDeviceIndex
+ if ((CurrentDeviceIndex < 0) or
+ (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList))) then
+ begin
+ Exit;
+ end;
+
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ if not assigned(InputDevice) then
+ Exit;
+
+ // set new volume
+ Volume := InputDevice.GetVolume() + VolumeChange;
+ InputDevice.SetVolume(Volume);
+ //DebugWriteln('Volume: ' + floattostr(InputDevice.GetVolume));
+
+ // volume must be polled again
+ NextVolumePollTime := 0;
+end;
+
+procedure TScreenOptionsRecord.onShow;
+var
+ ChannelIndex: integer;
+begin
+ inherited;
+
+ Interaction := 0;
+
+ // create preview sound-buffers
+ SetLength(PreviewChannel, MaxChannelCount);
+ for ChannelIndex := 0 to High(PreviewChannel) do
+ PreviewChannel[ChannelIndex] := TCaptureBuffer.Create();
+
+ SetLength(ChannelPeak, MaxChannelCount);
+
+ StartPreview();
+end;
+
+procedure TScreenOptionsRecord.onHide;
+var
+ ChannelIndex: integer;
+begin
+ StopPreview();
+
+ // free preview buffers
+ for ChannelIndex := 0 to High(PreviewChannel) do
+ PreviewChannel[ChannelIndex].Free;
+ SetLength(PreviewChannel, 0);
+ SetLength(ChannelPeak, 0);
+end;
+
+procedure TScreenOptionsRecord.StartPreview;
+var
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+begin
+ if ((CurrentDeviceIndex >= 0) and
+ (CurrentDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ // set preview channel as active capture channel
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ begin
+ PreviewChannel[ChannelIndex].Clear();
+ Device.LinkCaptureBuffer(ChannelIndex, PreviewChannel[ChannelIndex]);
+ FillChar(ChannelPeak[ChannelIndex], SizeOf(TPeakInfo), 0);
+ end;
+ Device.Start();
+ PreviewDeviceIndex := CurrentDeviceIndex;
+
+ // volume must be polled again
+ NextVolumePollTime := 0;
+ end;
+end;
+
+procedure TScreenOptionsRecord.StopPreview;
+var
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+begin
+ if ((PreviewDeviceIndex >= 0) and
+ (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
+ Device.Stop;
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ Device.LinkCaptureBuffer(ChannelIndex, nil);
+ end;
+ PreviewDeviceIndex := -1;
+end;
+
+
+procedure TScreenOptionsRecord.DrawVolume(x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ VolBarInnerWidth: integer;
+ Volume: single;
+const
+ VolBarInnerHSpacing = 2;
+ VolBarInnerVSpacing = 1;
+begin
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x1 + Width;
+ y2 := y1 + Height;
+
+ // init blend mode
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
+
+ // TODO: if no volume is available, show some info (a blue bar maybe)
+ if (SourceVolume >= 0) then
+ Volume := SourceVolume
+ else
+ Volume := 0;
+
+ // coordinates for first half of the volume bar
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * Volume;
+ y1 := y1 + VolBarInnerVSpacing;
+ y2 := y2 - VolBarInnerVSpacing;
+
+ // draw volume-bar
+ glBegin(GL_QUADS);
+ // draw volume bar
+ glColor3f(0.4, 0.3, 0.3);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glColor3f(1, 0.1, 0.1);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+ glEnd();
+
+ { not needed anymore
+ // coordinates for separator
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth;
+
+ // draw separator
+ glBegin(GL_LINE_STRIP);
+ glColor4f(0.1, 0.1, 0.1, 0.2);
+ glVertex2f(x1, y2);
+ glColor4f(0.4, 0.4, 0.4, 0.2);
+ glVertex2f((x1+x2)/2, y2);
+ glColor4f(0.1, 0.1, 0.1, 0.2);
+ glVertex2f(x2, y2);
+ glEnd();
+ }
+
+ glDisable(GL_BLEND);
+end;
+
+procedure TScreenOptionsRecord.DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ Volume, PeakVolume: single;
+ Delta: single;
+ VolBarInnerWidth: integer;
+const
+ VolBarInnerHSpacing = 2;
+ VolBarInnerVSpacing = 1;
+begin
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x1 + Width;
+ y2 := y1 + Height;
+
+ // init blend mode
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
+
+ // vertical positions
+ y1 := y1 + VolBarInnerVSpacing;
+ y2 := y2 - VolBarInnerVSpacing;
+
+ // coordinates for bevel
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth;
+
+ glBegin(GL_QUADS);
+ Volume := PreviewChannel[State.ChannelIndex].MaxSampleVolume();
+
+ // coordinates for volume bar
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * Volume;
+
+ // draw volume bar
+ glColor3f(State.RD, State.GD, State.BD);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glColor3f(State.R, State.G, State.B);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+
+ Delta := (SDL_GetTicks() - ChannelPeak[State.ChannelIndex].Time)/1000;
+ PeakVolume := ChannelPeak[State.ChannelIndex].Volume - Delta*Delta*PeakDecay;
+
+ // determine new peak-volume
+ if (Volume > PeakVolume) then
+ begin
+ PeakVolume := Volume;
+ ChannelPeak[State.ChannelIndex].Volume := Volume;
+ ChannelPeak[State.ChannelIndex].Time := SDL_GetTicks();
+ end;
+
+ x1 := x + VolBarInnerHSpacing + VolBarInnerWidth * PeakVolume;
+ x2 := x1 + 2;
+
+ // draw peak
+ glColor3f(0.8, 0.8, 0.8);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+
+ // draw threshold
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * IThresholdVals[Ini.ThresholdIndex];
+
+ glColor4f(0.3, 0.3, 0.3, 0.6);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+ glEnd();
+
+ glDisable(GL_BLEND);
+end;
+
+procedure TScreenOptionsRecord.DrawPitch(const State: TDrawState; x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ i: integer;
+ ToneBoxWidth: real;
+ ToneString: PChar;
+ ToneStringWidth, ToneStringHeight: real;
+ ToneStringMaxWidth: real;
+ ToneStringCenterXOffset: real;
+const
+ PitchBarInnerHSpacing = 2;
+ PitchBarInnerVSpacing = 1;
+begin
+ // calc tone pitch
+ PreviewChannel[State.ChannelIndex].AnalyzeBuffer();
+
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x + Width;
+ y2 := y + Height;
+
+ // init blend mode
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ // coordinates for tone boxes
+ ToneBoxWidth := Width / NumHalftones;
+ y1 := y1 + PitchBarInnerVSpacing;
+ y2 := y2 - PitchBarInnerVSpacing;
+
+ glBegin(GL_QUADS);
+ // draw tone boxes
+ for i := 0 to NumHalftones-1 do
+ begin
+ x1 := x + i * ToneBoxWidth + PitchBarInnerHSpacing;
+ x2 := x1 + ToneBoxWidth - 2*PitchBarInnerHSpacing;
+
+ if ((PreviewChannel[State.ChannelIndex].ToneValid) and
+ (PreviewChannel[State.ChannelIndex].ToneAbs = i)) then
+ begin
+ // highlight current tone-pitch
+ glColor3f(1, i / (NumHalftones-1), 0)
+ end
+ else
+ begin
+ // grey other tone-pitches
+ glColor3f(0.3, i / (NumHalftones-1) * 0.3, 0);
+ end;
+
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ end;
+ glEnd();
+
+ glDisable(GL_BLEND);
+
+ ///
+ // draw the name of the tone
+ ///////
+
+ ToneString := PChar(PreviewChannel[State.ChannelIndex].ToneString);
+ ToneStringHeight := ChannelBarsTotalHeight;
+
+ // initialize font
+ // TODO: what about reflection, italic etc.?
+ SetFontSize(ToneStringHeight/3);
+
+ // center
+ // Note: for centering let us assume that G#4 has the max. horizontal extent
+ ToneStringWidth := glTextWidth(ToneString);
+ ToneStringMaxWidth := glTextWidth('G#4');
+ ToneStringCenterXOffset := (ToneStringMaxWidth-ToneStringWidth) / 2;
+
+ // draw
+ SetFontPos(x-ToneStringWidth-ToneStringCenterXOffset, y-ToneStringHeight/2);
+ glColor3f(0, 0, 0);
+ glPrint(ToneString);
+end;
+
+function TScreenOptionsRecord.Draw: boolean;
+var
+ i: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+ SelectSlide: TSelectSlide;
+ BarXOffset, BarYOffset, BarWidth: real;
+ ChannelIndex: integer;
+ State: TDrawState;
+begin
+ DrawBG;
+ DrawFG;
+
+ if ((PreviewDeviceIndex >= 0) and
+ (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
+ DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
+
+ // update source volume
+ if (SDL_GetTicks() >= NextVolumePollTime) then
+ begin
+ NextVolumePollTime := SDL_GetTicks() + 500; // next poll in 500ms
+ SourceVolume := Device.GetVolume();
+ end;
+
+ // get source select slide
+ SelectSlide := SelectsS[SelectInputSourceID];
+ BarXOffset := SelectSlide.TextureSBG.X;
+ BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
+ BarWidth := SelectSlide.TextureSBG.W;
+ DrawVolume(SelectSlide.TextureSBG.X, BarYOffset, BarWidth, BarHeight);
+
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ begin
+ // load player color mapped to current input channel
+ if (DeviceCfg.ChannelToPlayerMap[ChannelIndex] > 0) then
+ begin
+ // set mapped channel to corresponding player-color
+ LoadColor(State.R, State.G, State.B, 'P'+ IntToStr(DeviceCfg.ChannelToPlayerMap[ChannelIndex]) + 'Dark');
+ end
+ else
+ begin
+ // set non-mapped channel to white
+ State.R := 1; State.G := 1; State.B := 1;
+ end;
+
+ // dark player colors
+ State.RD := 0.2 * State.R;
+ State.GD := 0.2 * State.G;
+ State.BD := 0.2 * State.B;
+
+ // channel select slide
+ SelectSlide := SelectsS[SelectSlideChannelID[ChannelIndex]];
+
+ BarXOffset := SelectSlide.TextureSBG.X;
+ BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
+ BarWidth := SelectSlide.TextureSBG.W;
+
+ State.ChannelIndex := ChannelIndex;
+
+ DrawVUMeter(State, BarXOffset, BarYOffset, BarWidth, BarHeight);
+ DrawPitch(State, BarXOffset, BarYOffset+BarHeight, BarWidth, BarHeight);
+ end;
+ end;
+
+ Result := True;
+end;
+
+
+end.
diff --git a/src/Screens/UScreenOptionsSound.pas b/src/Screens/UScreenOptionsSound.pas
new file mode 100644
index 00000000..9c602788
--- /dev/null
+++ b/src/Screens/UScreenOptionsSound.pas
@@ -0,0 +1,133 @@
+unit UScreenOptionsSound;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsSound = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: cardinal; CharCode: widechar;
+ PressedDown: boolean): boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, SysUtils;
+
+function TScreenOptionsSound.ParseInput(PressedKey: cardinal;
+ CharCode: widechar; PressedDown: boolean): boolean;
+begin
+ Result := True;
+ if (PressedDown) then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ // Escape -> save nothing - just leave this screen
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 8 then
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP:
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < 8) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < 8) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+
+{**
+ * Actually this one isn't pretty - but it does the trick of
+ * turning the background music on/off in "real time"
+ * bgm = background music
+ * TODO: - Fetching the SelectInteraction via something more descriptive
+ * - Obtaining the current value of a select is imho ugly
+ *}
+ if (SelInteraction = 1) then
+ begin
+ if TBackgroundMusicOption(SelectsS[1].SelectedOption) = bmoOn then
+ SoundLib.StartBgMusic
+ else
+ SoundLib.PauseBgMusic;
+ end;
+
+end;
+
+constructor TScreenOptionsSound.Create;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsSound);
+
+ AddSelectSlide(Theme.OptionsSound.SelectSlideVoicePassthrough,
+ Ini.VoicePassthrough, IVoicePassthrough);
+ AddSelectSlide(Theme.OptionsSound.SelectBackgroundMusic,
+ Ini.BackgroundMusicOption, IBackgroundMusic);
+ AddSelectSlide(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost);
+ // TODO: - MicBoost needs to be moved to ScreenOptionsRecord
+ AddSelectSlide(Theme.OptionsSound.SelectClickAssist, Ini.ClickAssist, IClickAssist);
+ AddSelectSlide(Theme.OptionsSound.SelectBeatClick, Ini.BeatClick, IBeatClick);
+ AddSelectSlide(Theme.OptionsSound.SelectThreshold, Ini.ThresholdIndex, IThreshold);
+ AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewVolume,
+ Ini.PreviewVolume, IPreviewVolume);
+ AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewFading,
+ Ini.PreviewFading, IPreviewFading);
+
+ AddButton(Theme.OptionsSound.ButtonExit);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsSound.onShow;
+begin
+ inherited;
+ Interaction := 0;
+end;
+
+end.
diff --git a/src/Screens/UScreenOptionsThemes.pas b/src/Screens/UScreenOptionsThemes.pas
new file mode 100644
index 00000000..a4f00b64
--- /dev/null
+++ b/src/Screens/UScreenOptionsThemes.pas
@@ -0,0 +1,171 @@
+unit UScreenOptionsThemes;
+
+interface
+
+{$I switches.inc}
+
+uses
+ SDL,
+ UMenu,
+ UDisplay,
+ UMusic,
+ UFiles,
+ UIni,
+ UThemes;
+
+type
+ TScreenOptionsThemes = class(TMenu)
+ private
+ procedure ReloadTheme;
+ public
+ SkinSelect: Integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractInc; override;
+ procedure InteractDec; override;
+ end;
+
+implementation
+
+uses UMain,
+ UGraphic,
+ USkins,
+ SysUtils;
+
+function TScreenOptionsThemes.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ // Escape -> save nothing - just leave this screen
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 3 then
+ begin
+ Ini.Save;
+
+ // Reload all screens, after Theme changed
+ // Todo : JB - Check if theme was actually changed
+ UGraphic.UnLoadScreens();
+ UGraphic.LoadScreens();
+
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenOptionsThemes.InteractInc;
+begin
+ inherited InteractInc;
+
+ //Update Skins
+ if (SelInteraction = 0) then
+ begin
+ Skin.OnThemeChange;
+ UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
+ end;
+
+ ReloadTheme();
+end;
+
+procedure TScreenOptionsThemes.InteractDec;
+begin
+ inherited InteractDec;
+
+ //Update Skins
+ if (SelInteraction = 0 ) then
+ begin
+ Skin.OnThemeChange;
+ UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
+ end;
+
+ ReloadTheme();
+end;
+
+constructor TScreenOptionsThemes.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsThemes);
+
+ AddSelectSlide(Theme.OptionsThemes.SelectTheme, Ini.Theme, ITheme);
+
+ SkinSelect := AddSelectSlide(Theme.OptionsThemes.SelectSkin, Ini.SkinNo, ISkin);
+
+ AddSelectSlide(Theme.OptionsThemes.SelectColor, Ini.Color, IColor);
+
+ AddButton(Theme.OptionsThemes.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+end;
+
+procedure TScreenOptionsThemes.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsThemes.ReloadTheme;
+begin
+ Theme.LoadTheme(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color);
+
+ ScreenOptionsThemes := TScreenOptionsThemes.create();
+ ScreenOptionsThemes.onshow;
+ Display.CurrentScreen := @ScreenOptionsThemes;
+
+ ScreenOptionsThemes.Interaction := self.Interaction;
+ ScreenOptionsThemes.Draw;
+
+
+ Display.Draw;
+ SwapBuffers;
+
+ freeandnil( self );
+end;
+
+end.
diff --git a/src/Screens/UScreenPartyNewRound.pas b/src/Screens/UScreenPartyNewRound.pas
new file mode 100644
index 00000000..057344dc
--- /dev/null
+++ b/src/Screens/UScreenPartyNewRound.pas
@@ -0,0 +1,439 @@
+unit UScreenPartyNewRound;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenPartyNewRound = class(TMenu)
+ public
+ //Texts:
+ TextRound1: Cardinal;
+ TextRound2: Cardinal;
+ TextRound3: Cardinal;
+ TextRound4: Cardinal;
+ TextRound5: Cardinal;
+ TextRound6: Cardinal;
+ TextRound7: Cardinal;
+
+ TextWinner1: Cardinal;
+ TextWinner2: Cardinal;
+ TextWinner3: Cardinal;
+ TextWinner4: Cardinal;
+ TextWinner5: Cardinal;
+ TextWinner6: Cardinal;
+ TextWinner7: Cardinal;
+
+ TextNextRound: Cardinal;
+ TextNextRoundNo: Cardinal;
+ TextNextPlayer1: Cardinal;
+ TextNextPlayer2: Cardinal;
+ TextNextPlayer3: Cardinal;
+
+ //Statics
+ StaticRound1: Cardinal;
+ StaticRound2: Cardinal;
+ StaticRound3: Cardinal;
+ StaticRound4: Cardinal;
+ StaticRound5: Cardinal;
+ StaticRound6: Cardinal;
+ StaticRound7: Cardinal;
+
+ //Scores
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+
+ TextTeam1Players: Cardinal;
+ TextTeam2Players: Cardinal;
+ TextTeam3Players: Cardinal;
+
+ StaticTeam1: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam3: Cardinal;
+ StaticNextPlayer1: Cardinal;
+ StaticNextPlayer2: Cardinal;
+ StaticNextPlayer3: Cardinal;
+
+
+
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic,
+ UMain,
+ UIni,
+ UTexture,
+ UParty,
+ UDLLManager,
+ ULanguage,
+ USong,
+ ULog;
+
+function TScreenPartyNewRound.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
+ end;
+
+ SDLK_RETURN:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ if DLLMan.Selected.LoadSong then
+ begin
+ //Select PartyMode ScreenSong
+ ScreenSong.Mode := smPartyMode;
+ FadeTo(@ScreenSong);
+ end
+ else
+ begin
+ FadeTo(@ScreenSingModi);
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyNewRound.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ TextRound1 := AddText (Theme.PartyNewRound.TextRound1);
+ TextRound2 := AddText (Theme.PartyNewRound.TextRound2);
+ TextRound3 := AddText (Theme.PartyNewRound.TextRound3);
+ TextRound4 := AddText (Theme.PartyNewRound.TextRound4);
+ TextRound5 := AddText (Theme.PartyNewRound.TextRound5);
+ TextRound6 := AddText (Theme.PartyNewRound.TextRound6);
+ TextRound7 := AddText (Theme.PartyNewRound.TextRound7);
+
+ TextWinner1 := AddText (Theme.PartyNewRound.TextWinner1);
+ TextWinner2 := AddText (Theme.PartyNewRound.TextWinner2);
+ TextWinner3 := AddText (Theme.PartyNewRound.TextWinner3);
+ TextWinner4 := AddText (Theme.PartyNewRound.TextWinner4);
+ TextWinner5 := AddText (Theme.PartyNewRound.TextWinner5);
+ TextWinner6 := AddText (Theme.PartyNewRound.TextWinner6);
+ TextWinner7 := AddText (Theme.PartyNewRound.TextWinner7);
+
+ TextNextRound := AddText (Theme.PartyNewRound.TextNextRound);
+ TextNextRoundNo := AddText (Theme.PartyNewRound.TextNextRoundNo);
+ TextNextPlayer1 := AddText (Theme.PartyNewRound.TextNextPlayer1);
+ TextNextPlayer2 := AddText (Theme.PartyNewRound.TextNextPlayer2);
+ TextNextPlayer3 := AddText (Theme.PartyNewRound.TextNextPlayer3);
+
+ StaticRound1 := AddStatic (Theme.PartyNewRound.StaticRound1);
+ StaticRound2 := AddStatic (Theme.PartyNewRound.StaticRound2);
+ StaticRound3 := AddStatic (Theme.PartyNewRound.StaticRound3);
+ StaticRound4 := AddStatic (Theme.PartyNewRound.StaticRound4);
+ StaticRound5 := AddStatic (Theme.PartyNewRound.StaticRound5);
+ StaticRound6 := AddStatic (Theme.PartyNewRound.StaticRound6);
+ StaticRound7 := AddStatic (Theme.PartyNewRound.StaticRound7);
+
+ //Scores
+ TextScoreTeam1 := AddText (Theme.PartyNewRound.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyNewRound.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyNewRound.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyNewRound.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyNewRound.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyNewRound.TextNameTeam3);
+
+ //Players
+ TextTeam1Players := AddText (Theme.PartyNewRound.TextTeam1Players);
+ TextTeam2Players := AddText (Theme.PartyNewRound.TextTeam2Players);
+ TextTeam3Players := AddText (Theme.PartyNewRound.TextTeam3Players);
+
+ StaticTeam1 := AddStatic (Theme.PartyNewRound.StaticTeam1);
+ StaticTeam2 := AddStatic (Theme.PartyNewRound.StaticTeam2);
+ StaticTeam3 := AddStatic (Theme.PartyNewRound.StaticTeam3);
+ StaticNextPlayer1 := AddStatic (Theme.PartyNewRound.StaticNextPlayer1);
+ StaticNextPlayer2 := AddStatic (Theme.PartyNewRound.StaticNextPlayer2);
+ StaticNextPlayer3 := AddStatic (Theme.PartyNewRound.StaticNextPlayer3);
+
+ LoadFromTheme(Theme.PartyNewRound);
+end;
+
+procedure TScreenPartyNewRound.onShow;
+var
+ I: Integer;
+ function GetTeamPlayers(const Num: Byte): String;
+ var
+ Players: Array of String;
+ J: Byte;
+ begin // to-do : Party
+ if (Num-1 >= {PartySession.Teams.NumTeams}0) then
+ exit;
+
+ {//Create Players Array
+ SetLength(Players, PartySession.Teams.TeamInfo[Num-1].NumPlayers);
+ For J := 0 to PartySession.Teams.TeamInfo[Num-1].NumPlayers-1 do
+ Players[J] := String(PartySession.Teams.TeamInfo[Num-1].PlayerInfo[J].Name);}
+
+ //Implode and Return
+ Result := Language.Implode(Players);
+ end;
+begin
+ inherited;
+
+ // to-do : Party
+ //PartySession.StartRound;
+
+ //Set Visibility of Round Infos
+ // to-do : Party
+ I := {Length(PartySession.Rounds)}0;
+ if (I >= 1) then
+ begin
+ Static[StaticRound1].Visible := True;
+ Text[TextRound1].Visible := True;
+ Text[TextWinner1].Visible := True;
+
+ //Texts:
+ //Text[TextRound1].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[0].Plugin].Name);
+ //Text[TextWinner1].Text := PartySession.GetWinnerString(0);
+ end
+ else
+ begin
+ Static[StaticRound1].Visible := False;
+ Text[TextRound1].Visible := False;
+ Text[TextWinner1].Visible := False;
+ end;
+
+ if (I >= 2) then
+ begin
+ Static[StaticRound2].Visible := True;
+ Text[TextRound2].Visible := True;
+ Text[TextWinner2].Visible := True;
+
+ //Texts:
+ //Text[TextRound2].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[1].Plugin].Name);
+ //Text[TextWinner2].Text := PartySession.GetWinnerString(1);
+ end
+ else
+ begin
+ Static[StaticRound2].Visible := False;
+ Text[TextRound2].Visible := False;
+ Text[TextWinner2].Visible := False;
+ end;
+
+ if (I >= 3) then
+ begin
+ Static[StaticRound3].Visible := True;
+ Text[TextRound3].Visible := True;
+ Text[TextWinner3].Visible := True;
+
+ //Texts:
+ //Text[TextRound3].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[2].Plugin].Name);
+ //Text[TextWinner3].Text := PartySession.GetWinnerString(2);
+ end
+ else
+ begin
+ Static[StaticRound3].Visible := False;
+ Text[TextRound3].Visible := False;
+ Text[TextWinner3].Visible := False;
+ end;
+
+ if (I >= 4) then
+ begin
+ Static[StaticRound4].Visible := True;
+ Text[TextRound4].Visible := True;
+ Text[TextWinner4].Visible := True;
+
+ //Texts:
+ //Text[TextRound4].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[3].Plugin].Name);
+ //Text[TextWinner4].Text := PartySession.GetWinnerString(3);
+ end
+ else
+ begin
+ Static[StaticRound4].Visible := False;
+ Text[TextRound4].Visible := False;
+ Text[TextWinner4].Visible := False;
+ end;
+
+ if (I >= 5) then
+ begin
+ Static[StaticRound5].Visible := True;
+ Text[TextRound5].Visible := True;
+ Text[TextWinner5].Visible := True;
+
+ //Texts:
+ //Text[TextRound5].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[4].Plugin].Name);
+ //Text[TextWinner5].Text := PartySession.GetWinnerString(4);
+ end
+ else
+ begin
+ Static[StaticRound5].Visible := False;
+ Text[TextRound5].Visible := False;
+ Text[TextWinner5].Visible := False;
+ end;
+
+ if (I >= 6) then
+ begin
+ Static[StaticRound6].Visible := True;
+ Text[TextRound6].Visible := True;
+ Text[TextWinner6].Visible := True;
+
+ //Texts:
+ //Text[TextRound6].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[5].Plugin].Name);
+ //Text[TextWinner6].Text := PartySession.GetWinnerString(5);
+ end
+ else
+ begin
+ Static[StaticRound6].Visible := False;
+ Text[TextRound6].Visible := False;
+ Text[TextWinner6].Visible := False;
+ end;
+
+ if (I >= 7) then
+ begin
+ Static[StaticRound7].Visible := True;
+ Text[TextRound7].Visible := True;
+ Text[TextWinner7].Visible := True;
+
+ //Texts:
+ //Text[TextRound7].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[6].Plugin].Name);
+ //Text[TextWinner7].Text := PartySession.GetWinnerString(6);
+ end
+ else
+ begin
+ Static[StaticRound7].Visible := False;
+ Text[TextRound7].Visible := False;
+ Text[TextWinner7].Visible := False;
+ end;
+
+ //Display Scores
+ {if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[0].Score);
+ Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[0].Name);
+ Text[TextTeam1Players].Text := GetTeamPlayers(1);
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Text[TextTeam1Players].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ Static[StaticNextPlayer1].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Text[TextTeam1Players].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ Static[StaticNextPlayer1].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[1].Score);
+ Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[1].Name);
+ Text[TextTeam2Players].Text := GetTeamPlayers(2);
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Text[TextTeam2Players].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ Static[StaticNextPlayer2].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Text[TextTeam2Players].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ Static[StaticNextPlayer2].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[2].Score);
+ Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[2].Name);
+ Text[TextTeam3Players].Text := GetTeamPlayers(3);
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Text[TextTeam3Players].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ Static[StaticNextPlayer3].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Text[TextTeam3Players].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ Static[StaticNextPlayer3].Visible := False;
+ end;
+
+ //nextRound Texts
+ Text[TextNextRound].Text := Language.Translate(DllMan.Selected.PluginDesc);
+ Text[TextNextRoundNo].Text := InttoStr(PartySession.CurRound + 1);
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextNextPlayer1].Text := PartySession.Teams.Teaminfo[0].Playerinfo[PartySession.Teams.Teaminfo[0].CurPlayer].Name;
+ Text[TextNextPlayer1].Visible := True;
+ end
+ else
+ Text[TextNextPlayer1].Visible := False;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextNextPlayer2].Text := PartySession.Teams.Teaminfo[1].Playerinfo[PartySession.Teams.Teaminfo[1].CurPlayer].Name;
+ Text[TextNextPlayer2].Visible := True;
+ end
+ else
+ Text[TextNextPlayer2].Visible := False;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextNextPlayer3].Text := PartySession.Teams.Teaminfo[2].Playerinfo[PartySession.Teams.Teaminfo[2].CurPlayer].Name;
+ Text[TextNextPlayer3].Visible := True;
+ end
+ else
+ Text[TextNextPlayer3].Visible := False; }
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyNewRound.SetAnimationProgress(Progress: real);
+begin
+ {Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress; }
+end;
+
+end.
diff --git a/src/Screens/UScreenPartyOptions.pas b/src/Screens/UScreenPartyOptions.pas
new file mode 100644
index 00000000..bd05e653
--- /dev/null
+++ b/src/Screens/UScreenPartyOptions.pas
@@ -0,0 +1,279 @@
+unit UScreenPartyOptions;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenPartyOptions = class(TMenu)
+ public
+ SelectLevel: Cardinal;
+ SelectPlayList: Cardinal;
+ SelectPlayList2: Cardinal;
+ SelectRounds: Cardinal;
+ SelectTeams: Cardinal;
+ SelectPlayers1: Cardinal;
+ SelectPlayers2: Cardinal;
+ SelectPlayers3: Cardinal;
+
+ PlayList: Integer;
+ PlayList2: Integer;
+ Rounds: Integer;
+ NumTeams: Integer;
+ NumPlayer1, NumPlayer2, NumPlayer3: Integer;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ procedure SetPlaylist2;
+ end;
+
+var
+ IPlaylist: array[0..2] of String;
+ IPlaylist2: array of String;
+const
+ ITeams: array[0..1] of String =('2', '3');
+ IPlayers: array[0..3] of String =('1', '2', '3', '4');
+ IRounds: array[0..5] of String = ('2', '3', '4', '5', '6', '7');
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, USong, UDLLManager, UPlaylist, USongs;
+
+function TScreenPartyOptions.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+ var
+ I, J: Integer;
+ OnlyMultiPlayer: boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ //Don'T start when Playlist is Selected and there are no Playlists
+ 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;
+ end;
+ //Save Difficulty
+ Ini.Difficulty := SelectsS[SelectLevel].SelectedOption;
+ Ini.SaveLevel;
+
+
+ //Save Num Teams:
+ {PartySession.Teams.NumTeams := NumTeams + 2;
+ PartySession.Teams.Teaminfo[0].NumPlayers := NumPlayer1+1;
+ PartySession.Teams.Teaminfo[1].NumPlayers := NumPlayer2+1;
+ PartySession.Teams.Teaminfo[2].NumPlayers := NumPlayer3+1;}
+
+ //Save Playlist
+ PlaylistMan.Mode := TSingMode( Playlist );
+ PlaylistMan.CurPlayList := High(Cardinal);
+ //If Category Selected Search Category ID
+ if Playlist = 1 then
+ begin
+ J := -1;
+ For I := 0 to high(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Inc(J);
+
+ if J = Playlist2 then
+ begin
+ PlaylistMan.CurPlayList := I;
+ Break;
+ end;
+ end;
+
+ //No Categorys or Invalid Entry
+ If PlaylistMan.CurPlayList = High(Cardinal) then
+ Exit;
+ end
+ else
+ PlaylistMan.CurPlayList := Playlist2;
+
+ //Start Party
+ // to-do : Party
+ //PartySession.StartNewParty(Rounds + 2);
+
+ AudioPlayback.PlaySound(SoundLib.Start);
+ //Go to Player Screen
+ FadeTo(@ScreenPartyPlayer);
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+
+ //Change Playlist2 if Playlist is Changed
+ If (Interaction = 1) then
+ begin
+ SetPlaylist2;
+ end //Change Team3 Players visibility
+ Else If (Interaction = 4) then
+ begin
+ SelectsS[7].Visible := (NumTeams = 1);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+
+ //Change Playlist2 if Playlist is Changed
+ If (Interaction = 1) then
+ begin
+ SetPlaylist2;
+ end //Change Team3 Players visibility
+ Else If (Interaction = 4) then
+ begin
+ SelectsS[7].Visible := (NumTeams = 1);
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyOptions.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+ //Fill IPlaylist
+ IPlaylist[0] := Language.Translate('PARTY_PLAYLIST_ALL');
+ IPlaylist[1] := Language.Translate('PARTY_PLAYLIST_CATEGORY');
+ IPlaylist[2] := Language.Translate('PARTY_PLAYLIST_PLAYLIST');
+
+ //Fill IPlaylist2
+ SetLength(IPlaylist2, 1);
+ IPlaylist2[0] := '---';
+
+ //Clear all Selects
+ NumTeams := 0;
+ NumPlayer1 := 0;
+ NumPlayer2 := 0;
+ NumPlayer3 := 0;
+ Rounds := 5;
+ PlayList := 0;
+ PlayList2 := 0;
+
+ //Load Screen From Theme
+ LoadFromTheme(Theme.PartyOptions);
+
+ SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, Theme.ILevel);
+ SelectPlayList := AddSelectSlide (Theme.PartyOptions.SelectPlayList, PlayList, IPlaylist);
+ SelectPlayList2 := AddSelectSlide (Theme.PartyOptions.SelectPlayList2, PlayList2, IPlaylist2);
+ SelectRounds := AddSelectSlide (Theme.PartyOptions.SelectRounds, Rounds, IRounds);
+ SelectTeams := AddSelectSlide (Theme.PartyOptions.SelectTeams, NumTeams, ITeams);
+ SelectPlayers1 := AddSelectSlide (Theme.PartyOptions.SelectPlayers1, NumPlayer1, IPlayers);
+ SelectPlayers2 := AddSelectSlide (Theme.PartyOptions.SelectPlayers2, NumPlayer2, IPlayers);
+ SelectPlayers3 := AddSelectSlide (Theme.PartyOptions.SelectPlayers3, NumPlayer3, IPlayers);
+
+ Interaction := 0;
+
+ //Hide Team3 Players
+ SelectsS[7].Visible := False;
+end;
+
+procedure TScreenPartyOptions.SetPlaylist2;
+var I: Integer;
+begin
+ Case Playlist of
+ 0:
+ begin
+ SetLength(IPlaylist2, 1);
+ IPlaylist2[0] := '---';
+ end;
+ 1:
+ begin
+ SetLength(IPlaylist2, 0);
+ For I := 0 to high(CatSongs.Song) do
+ begin
+ If (CatSongs.Song[I].Main) then
+ begin
+ SetLength(IPlaylist2, Length(IPlaylist2) + 1);
+ IPlaylist2[high(IPlaylist2)] := CatSongs.Song[I].Artist;
+ end;
+ end;
+
+ If (Length(IPlaylist2) = 0) then
+ begin
+ SetLength(IPlaylist2, 1);
+ IPlaylist2[0] := 'No Categories found';
+ end;
+ end;
+ 2:
+ begin
+ if (Length(PlaylistMan.Playlists) > 0) then
+ begin
+ SetLength(IPlaylist2, Length(PlaylistMan.Playlists));
+ PlaylistMan.GetNames(IPlaylist2);
+ end
+ else
+ begin
+ SetLength(IPlaylist2, 1);
+ IPlaylist2[0] := 'No Playlists found';
+ end;
+ end;
+ end;
+
+ Playlist2 := 0;
+ UpdateSelectSlideOptions(Theme.PartyOptions.SelectPlayList2, 2, IPlaylist2, Playlist2);
+end;
+
+procedure TScreenPartyOptions.onShow;
+begin
+ inherited;
+
+ Randomize;
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyOptions.SetAnimationProgress(Progress: real);
+begin
+ {for I := 0 to 6 do
+ SelectS[I].Texture.ScaleW := Progress;}
+end;
+
+end.
diff --git a/src/Screens/UScreenPartyPlayer.pas b/src/Screens/UScreenPartyPlayer.pas
new file mode 100644
index 00000000..fa717677
--- /dev/null
+++ b/src/Screens/UScreenPartyPlayer.pas
@@ -0,0 +1,340 @@
+unit UScreenPartyPlayer;
+
+Interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenPartyPlayer = class(TMenu)
+ public
+ Team1Name: Cardinal;
+ Player1Name: Cardinal;
+ Player2Name: Cardinal;
+ Player3Name: Cardinal;
+ Player4Name: Cardinal;
+
+ Team2Name: Cardinal;
+ Player5Name: Cardinal;
+ Player6Name: Cardinal;
+ Player7Name: Cardinal;
+ Player8Name: Cardinal;
+
+ Team3Name: Cardinal;
+ Player9Name: Cardinal;
+ Player10Name: Cardinal;
+ Player11Name: Cardinal;
+ Player12Name: Cardinal;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, UParty;
+
+function TScreenPartyPlayer.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+{*I, *}J: integer; // Auto Removed, Unused Variable (I)
+ SDL_ModState: Word;
+ procedure IntNext;
+ begin
+ repeat
+ InteractNext;
+ until Button[Interaction].Visible;
+ end;
+ procedure IntPrev;
+ begin
+ repeat
+ InteractPrev;
+ until Button[Interaction].Visible;
+ end;
+begin
+ Result := true;
+
+ if (PressedDown) then
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT)
+ else
+ SDL_ModState := 0;
+
+ begin // Key Down
+ // check normal keys
+ case CharCode of
+ '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"':
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ // Templates for Names Mod
+ SDLK_F1:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
+ end;
+ SDLK_F2:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
+ end;
+ SDLK_F3:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
+ end;
+ SDLK_F4:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
+ end;
+ SDLK_F5:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
+ end;
+ SDLK_F6:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
+ end;
+ SDLK_F7:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
+ end;
+ SDLK_F8:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
+ end;
+ SDLK_F9:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
+ end;
+ SDLK_F10:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
+ end;
+ SDLK_F11:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
+ end;
+ SDLK_F12:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ Button[Interaction].Text[0].DeleteLastL;
+ end;
+
+ SDLK_ESCAPE:
+ begin
+ Ini.SaveNames;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenPartyOptions);
+ end;
+
+ SDLK_RETURN:
+ begin
+
+ {//Save PlayerNames
+ for I := 0 to PartySession.Teams.NumTeams-1 do
+ begin
+ PartySession.Teams.Teaminfo[I].Name := PChar(Button[I*5].Text[0].Text);
+ for J := 0 to PartySession.Teams.Teaminfo[I].NumPlayers-1 do
+ begin
+ PartySession.Teams.Teaminfo[I].Playerinfo[J].Name := PChar(Button[I*5 + J+1].Text[0].Text);
+ PartySession.Teams.Teaminfo[I].Playerinfo[J].TimesPlayed := 0;
+ end;
+ end;
+
+ AudioPlayback.PlayStart;
+ FadeTo(@ScreenPartyNewRound);}
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: IntNext;
+ SDLK_UP: IntPrev;
+ SDLK_RIGHT: IntNext;
+ SDLK_LEFT: IntPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPartyPlayer.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.PartyPlayer);
+
+ Team1Name := AddButton(Theme.PartyPlayer.Team1Name);
+ AddButton(Theme.PartyPlayer.Player1Name);
+ AddButton(Theme.PartyPlayer.Player2Name);
+ AddButton(Theme.PartyPlayer.Player3Name);
+ AddButton(Theme.PartyPlayer.Player4Name);
+
+ Team2Name := AddButton(Theme.PartyPlayer.Team2Name);
+ AddButton(Theme.PartyPlayer.Player5Name);
+ AddButton(Theme.PartyPlayer.Player6Name);
+ AddButton(Theme.PartyPlayer.Player7Name);
+ AddButton(Theme.PartyPlayer.Player8Name);
+
+ Team3Name := AddButton(Theme.PartyPlayer.Team3Name);
+ AddButton(Theme.PartyPlayer.Player9Name);
+ AddButton(Theme.PartyPlayer.Player10Name);
+ AddButton(Theme.PartyPlayer.Player11Name);
+ AddButton(Theme.PartyPlayer.Player12Name);
+
+ Interaction := 0;
+end;
+
+procedure TScreenPartyPlayer.onShow;
+var
+ I: integer;
+begin
+ inherited;
+
+ // Templates for Names Mod
+ for I := 1 to 4 do
+ Button[I].Text[0].Text := Ini.Name[I-1];
+
+ for I := 6 to 9 do
+ Button[I].Text[0].Text := Ini.Name[I-2];
+
+ for I := 11 to 14 do
+ Button[I].Text[0].Text := Ini.Name[I-3];
+
+ Button[0].Text[0].Text := Ini.NameTeam[0];
+ Button[5].Text[0].Text := Ini.NameTeam[1];
+ Button[10].Text[0].Text := Ini.NameTeam[2];
+ // Templates for Names Mod end
+
+ {If (PartySession.Teams.NumTeams>=1) then
+ begin
+ Button[0].Visible := True;
+ Button[1].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=1);
+ Button[2].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=2);
+ Button[3].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=3);
+ Button[4].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[0].Visible := False;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := False;
+ Button[4].Visible := False;
+ end;
+
+ If (PartySession.Teams.NumTeams>=2) then
+ begin
+ Button[5].Visible := True;
+ Button[6].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=1);
+ Button[7].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=2);
+ Button[8].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=3);
+ Button[9].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[5].Visible := False;
+ Button[6].Visible := False;
+ Button[7].Visible := False;
+ Button[8].Visible := False;
+ Button[9].Visible := False;
+ end;
+
+ If (PartySession.Teams.NumTeams>=3) then
+ begin
+ Button[10].Visible := True;
+ Button[11].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=1);
+ Button[12].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=2);
+ Button[13].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=3);
+ Button[14].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[10].Visible := False;
+ Button[11].Visible := False;
+ Button[12].Visible := False;
+ Button[13].Visible := False;
+ Button[14].Visible := False;
+ end; }
+
+end;
+
+procedure TScreenPartyPlayer.SetAnimationProgress(Progress: real);
+var
+ I: integer;
+begin
+ for I := 0 to high(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenPartyScore.pas b/src/Screens/UScreenPartyScore.pas
new file mode 100644
index 00000000..176a94b2
--- /dev/null
+++ b/src/Screens/UScreenPartyScore.pas
@@ -0,0 +1,302 @@
+unit UScreenPartyScore;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
+
+type
+ TScreenPartyScore = class(TMenu)
+ public
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+ StaticTeam1: Cardinal;
+ StaticTeam1BG: Cardinal;
+ StaticTeam1Deco: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam2BG: Cardinal;
+ StaticTeam2Deco: Cardinal;
+ StaticTeam3: Cardinal;
+ StaticTeam3BG: Cardinal;
+ StaticTeam3Deco: Cardinal;
+ TextWinner: Cardinal;
+
+ DecoTex: Array[0..5] of Integer;
+ DecoColor: Array[0..5] of Record
+ R, G, B: Real;
+ end;
+
+ MaxScore: Word;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage, UTexture, USkins;
+
+function TScreenPartyScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ {if (PartySession.CurRound < High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else // to-do : Party
+ begin
+ PartySession.EndRound; }
+ FadeTo(@ScreenPartyWin);
+ //end;
+ end;
+
+ SDLK_RETURN:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ // to-do : Party
+ {if (PartySession.CurRound < High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else }
+ FadeTo(@ScreenPartyWin);
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyScore.Create;
+var
+// I: integer; // Auto Removed, Unused Variable
+ Tex: TTexture;
+ R, G, B: Real;
+ Color: Integer;
+begin
+ inherited Create;
+
+ TextScoreTeam1 := AddText (Theme.PartyScore.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyScore.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyScore.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyScore.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyScore.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyScore.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyScore.StaticTeam1);
+ StaticTeam1BG := AddStatic (Theme.PartyScore.StaticTeam1BG);
+ StaticTeam1Deco := AddStatic (Theme.PartyScore.StaticTeam1Deco);
+ StaticTeam2 := AddStatic (Theme.PartyScore.StaticTeam2);
+ StaticTeam2BG := AddStatic (Theme.PartyScore.StaticTeam2BG);
+ StaticTeam2Deco := AddStatic (Theme.PartyScore.StaticTeam2Deco);
+ StaticTeam3 := AddStatic (Theme.PartyScore.StaticTeam3);
+ StaticTeam3BG := AddStatic (Theme.PartyScore.StaticTeam3BG);
+ StaticTeam3Deco := AddStatic (Theme.PartyScore.StaticTeam3Deco);
+
+ TextWinner := AddText (Theme.PartyScore.TextWinner);
+
+ //Load Deco Textures
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ //Get Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.FirstColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[0].R := R;
+ DecoColor[0].G := G;
+ DecoColor[0].B := B;
+
+ //Load Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture)), Theme.PartyScore.DecoTextures.FirstTyp, Color);
+ DecoTex[0] := Tex.TexNum;
+
+ //Get Second Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.SecondColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[1].R := R;
+ DecoColor[1].G := G;
+ DecoColor[1].B := B;
+
+ //Load Second Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture)), Theme.PartyScore.DecoTextures.SecondTyp, Color);
+ DecoTex[1] := Tex.TexNum;
+
+ //Get Third Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.ThirdColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[2].R := R;
+ DecoColor[2].G := G;
+ DecoColor[2].B := B;
+
+ //Load Third Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture)), Theme.PartyScore.DecoTextures.ThirdTyp, Color);
+ DecoTex[2] := Tex.TexNum;
+ end;
+
+ LoadFromTheme(Theme.PartyScore);
+end;
+
+procedure TScreenPartyScore.onShow;
+var
+ I, J: Integer;
+ Placings: Array [0..5] of Byte;
+begin
+ inherited;
+
+
+ //Get Maxscore
+
+ MaxScore := 0;
+ for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ begin
+ if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
+ MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
+ end;
+
+ //Get Placings
+ for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ begin
+ Placings[I] := 0;
+ for J := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ If (ScreenSingModi.PlayerInfo.Playerinfo[J].Score > ScreenSingModi.PlayerInfo.Playerinfo[I].Score) then
+ Inc(Placings[I]);
+ end;
+
+
+ //Set Static Length
+ Static[StaticTeam1].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ Static[StaticTeam2].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ Static[StaticTeam3].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+
+ //fix: prevents static from drawn out of bounds.
+ if Static[StaticTeam1].Texture.ScaleW > 99 then Static[StaticTeam1].Texture.ScaleW := 99;
+ if Static[StaticTeam2].Texture.ScaleW > 99 then Static[StaticTeam2].Texture.ScaleW := 99;
+ if Static[StaticTeam3].Texture.ScaleW > 99 then Static[StaticTeam3].Texture.ScaleW := 99;
+
+ //End Last Round // to-do : Party
+ //PartySession.EndRound;
+
+ //Set Winnertext
+ //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(PartySession.CurRound)]);
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score);
+ Text[TextNameTeam1].Text := String(ScreenSingModi.TeamInfo.Teaminfo[0].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam1Deco].Texture.TexNum := DecoTex[Placings[0]];
+ Static[StaticTeam1Deco].Texture.ColR := DecoColor[Placings[0]].R;
+ Static[StaticTeam1Deco].Texture.ColG := DecoColor[Placings[0]].G;
+ Static[StaticTeam1Deco].Texture.ColB := DecoColor[Placings[0]].B;
+ end;
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ Static[StaticTeam1BG].Visible := True;
+ Static[StaticTeam1Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ Static[StaticTeam1BG].Visible := False;
+ Static[StaticTeam1Deco].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score);
+ Text[TextNameTeam2].Text := String(ScreenSingModi.TeamInfo.Teaminfo[1].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam2Deco].Texture.TexNum := DecoTex[Placings[1]];
+ Static[StaticTeam2Deco].Texture.ColR := DecoColor[Placings[1]].R;
+ Static[StaticTeam2Deco].Texture.ColG := DecoColor[Placings[1]].G;
+ Static[StaticTeam2Deco].Texture.ColB := DecoColor[Placings[1]].B;
+ end;
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ Static[StaticTeam2BG].Visible := True;
+ Static[StaticTeam2Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ Static[StaticTeam2BG].Visible := False;
+ Static[StaticTeam2Deco].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score);
+ Text[TextNameTeam3].Text := String(ScreenSingModi.TeamInfo.Teaminfo[2].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam3Deco].Texture.TexNum := DecoTex[Placings[2]];
+ Static[StaticTeam3Deco].Texture.ColR := DecoColor[Placings[2]].R;
+ Static[StaticTeam3Deco].Texture.ColG := DecoColor[Placings[2]].G;
+ Static[StaticTeam3Deco].Texture.ColB := DecoColor[Placings[2]].B;
+ end;
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ Static[StaticTeam3BG].Visible := True;
+ Static[StaticTeam3Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ Static[StaticTeam3BG].Visible := False;
+ Static[StaticTeam3Deco].Visible := False;
+ end;
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyScore.SetAnimationProgress(Progress: real);
+begin
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+end;
+
+end.
diff --git a/src/Screens/UScreenPartyWin.pas b/src/Screens/UScreenPartyWin.pas
new file mode 100644
index 00000000..002c6f75
--- /dev/null
+++ b/src/Screens/UScreenPartyWin.pas
@@ -0,0 +1,267 @@
+unit UScreenPartyWin;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
+
+type
+ TScreenPartyWin = class(TMenu)
+ public
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+ StaticTeam1: Cardinal;
+ StaticTeam1BG: Cardinal;
+ StaticTeam1Deco: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam2BG: Cardinal;
+ StaticTeam2Deco: Cardinal;
+ StaticTeam3: Cardinal;
+ StaticTeam3BG: Cardinal;
+ StaticTeam3Deco: Cardinal;
+ TextWinner: Cardinal;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage;
+
+function TScreenPartyWin.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenMain);
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyWin.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ TextScoreTeam1 := AddText (Theme.PartyWin.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyWin.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyWin.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyWin.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyWin.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyWin.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyWin.StaticTeam1);
+ StaticTeam1BG := AddStatic (Theme.PartyWin.StaticTeam1BG);
+ StaticTeam1Deco := AddStatic (Theme.PartyWin.StaticTeam1Deco);
+ StaticTeam2 := AddStatic (Theme.PartyWin.StaticTeam2);
+ StaticTeam2BG := AddStatic (Theme.PartyWin.StaticTeam2BG);
+ StaticTeam2Deco := AddStatic (Theme.PartyWin.StaticTeam2Deco);
+ StaticTeam3 := AddStatic (Theme.PartyWin.StaticTeam3);
+ StaticTeam3BG := AddStatic (Theme.PartyWin.StaticTeam3BG);
+ StaticTeam3Deco := AddStatic (Theme.PartyWin.StaticTeam3Deco);
+
+ TextWinner := AddText (Theme.PartyWin.TextWinner);
+
+ LoadFromTheme(Theme.PartyWin);
+end;
+
+procedure TScreenPartyWin.onShow;
+//var
+// I: Integer; // Auto Removed, Unused Variable
+// Placing: Integer; // Auto Removed, Unused Variable
+
+ Function GetTeamColor(Team: Byte): Cardinal;
+ var
+ NameString: String;
+ begin
+ NameString := 'P' + InttoStr(Team+1) + 'Dark';
+
+ Result := ColorExists(NameString);
+ end;
+
+begin
+ inherited;
+
+ // to-do : Party
+ //Get Team Placing
+ //Placing := PartySession.GetTeamOrder;
+
+ //Set Winnertext
+ //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.Teams.Teaminfo[Placing[0]].Name]);
+ {if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[0]].Score);
+ Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[Placing[0]].Name);
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ Static[StaticTeam1BG].Visible := True;
+ Static[StaticTeam1Deco].Visible := True;
+
+ //Set Static Color to Team Color
+ If (Theme.PartyWin.StaticTeam1BG.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[0]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam1BG].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam1BG].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam1BG].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+
+ If (Theme.PartyWin.StaticTeam1.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[0]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam1].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam1].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam1].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ Static[StaticTeam1BG].Visible := False;
+ Static[StaticTeam1Deco].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[1]].Score);
+ Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[Placing[1]].Name);
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ Static[StaticTeam2BG].Visible := True;
+ Static[StaticTeam2Deco].Visible := True;
+
+ //Set Static Color to Team Color
+ If (Theme.PartyWin.StaticTeam2BG.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[1]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam2BG].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam2BG].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam2BG].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+
+ If (Theme.PartyWin.StaticTeam2.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[1]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam2].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam2].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam2].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ Static[StaticTeam2BG].Visible := False;
+ Static[StaticTeam2Deco].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[Placing[2]].Score);
+ Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[Placing[2]].Name);
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ Static[StaticTeam3BG].Visible := True;
+ Static[StaticTeam3Deco].Visible := True;
+
+ //Set Static Color to Team Color
+ If (Theme.PartyWin.StaticTeam3BG.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[2]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam3BG].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam3BG].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam3BG].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+
+ If (Theme.PartyWin.StaticTeam3.Color = 'TeamColor') then
+ begin
+ I := GetTeamColor(Placing[2]);
+ if (I <> -1) then
+ begin
+ Static[StaticTeam3].Texture.ColR := Color[I].RGB.R;
+ Static[StaticTeam3].Texture.ColG := Color[I].RGB.G;
+ Static[StaticTeam3].Texture.ColB := Color[I].RGB.B;
+ end;
+ end;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ Static[StaticTeam3BG].Visible := False;
+ Static[StaticTeam3Deco].Visible := False;
+ end; }
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyWin.SetAnimationProgress(Progress: real);
+begin
+ {if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Score / maxScore;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Score / maxScore;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Score / maxScore;}
+end;
+
+end.
diff --git a/src/Screens/UScreenPopup.pas b/src/Screens/UScreenPopup.pas
new file mode 100644
index 00000000..b51fac98
--- /dev/null
+++ b/src/Screens/UScreenPopup.pas
@@ -0,0 +1,252 @@
+unit UScreenPopup;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenPopupCheck = class(TMenu)
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure ShowPopup(msg: String);
+ function Draw: boolean; override;
+ end;
+
+type
+ TScreenPopupError = class(TMenu)
+{ private
+ CurMenu: Byte; //Num of the cur. Shown Menu}
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure ShowPopup(msg: String);
+ function Draw: boolean; override;
+ end;
+
+var
+// ISelections: Array of String;
+ SelectValue: Integer;
+
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UPlaylist, UDisplay;
+
+function TScreenPopupCheck.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Display.CheckOK:=False;
+ Display.NextScreenWithCheck:=NIL;
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ case Interaction of
+ 0: begin
+ //Hack to Finish Singscreen correct on Exit with Q Shortcut
+ if (Display.NextScreenWithCheck = NIL) then
+ begin
+ if (Display.CurrentScreen = @ScreenSing) then
+ ScreenSing.Finish
+ else if (Display.CurrentScreen = @ScreenSingModi) then
+ ScreenSingModi.Finish;
+ end;
+
+ Display.CheckOK:=True;
+ end;
+ 1: begin
+ Display.CheckOK:=False;
+ Display.NextScreenWithCheck:=NIL;
+ end;
+ end;
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPopupCheck.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.CheckPopup.Background.Tex);
+
+ AddButton(Theme.CheckPopup.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddButton(Theme.CheckPopup.Button2);
+ if (Length(Button[1].Text) = 0) then
+ AddButtonText(14, 20, 'Button 2');
+
+ AddText(Theme.CheckPopup.TextCheck);
+
+ for I := 0 to High(Theme.CheckPopup.Static) do
+ AddStatic(Theme.CheckPopup.Static[I]);
+
+ for I := 0 to High(Theme.CheckPopup.Text) do
+ AddText(Theme.CheckPopup.Text[I]);
+
+ Interaction := 0;
+end;
+
+function TScreenPopupCheck.Draw: boolean;
+begin
+ Draw:=inherited Draw;
+end;
+
+procedure TScreenPopupCheck.onShow;
+begin
+ inherited;
+end;
+
+procedure TScreenPopupCheck.ShowPopup(msg: String);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+
+ Text[0].Text := Language.Translate(msg);
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_NO');
+end;
+
+// error popup
+
+function TScreenPopupError.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPopupError.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.CheckPopup.Background.Tex);
+
+ AddButton(Theme.ErrorPopup.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddText(Theme.ErrorPopup.TextError);
+
+ for I := 0 to High(Theme.ErrorPopup.Static) do
+ AddStatic(Theme.ErrorPopup.Static[I]);
+
+ for I := 0 to High(Theme.ErrorPopup.Text) do
+ AddText(Theme.ErrorPopup.Text[I]);
+
+ Interaction := 0;
+end;
+
+function TScreenPopupError.Draw: boolean;
+begin
+ Draw:=inherited Draw;
+end;
+
+procedure TScreenPopupError.onShow;
+begin
+ inherited;
+
+end;
+
+procedure TScreenPopupError.onHide;
+begin
+end;
+
+procedure TScreenPopupError.ShowPopup(msg: String);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+
+{ //dirty hack... Text[0] is invisible for some strange reason
+ for i:=1 to high(Text) do
+ if i-1 <= high(msg) then
+ begin
+ Text[i].Visible:=True;
+ Text[i].Text := msg[i-1];
+ end
+ else
+ begin
+ Text[i].Visible:=False;
+ end;}
+ Text[0].Text:=msg;
+
+ Button[0].Visible := True;
+
+ Button[0].Text[0].Text := 'OK';
+end;
+
+end.
diff --git a/src/Screens/UScreenScore.pas b/src/Screens/UScreenScore.pas
new file mode 100644
index 00000000..ab6c020d
--- /dev/null
+++ b/src/Screens/UScreenScore.pas
@@ -0,0 +1,848 @@
+unit UScreenScore;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UDisplay,
+ UMusic,
+ USongs,
+ UThemes,
+ gl,
+ math,
+ UTexture;
+
+const
+ ZBars : real = 0.8; // Z value for the bars
+ ZRatingPic : real = 0.8; // Z value for the rating pictures
+
+ EaseOut_MaxSteps : real = 10; // that's the speed of the bars (10 is fast | 100 is slower)
+
+ BarRaiseSpeed : cardinal = 0; // Time for raising the bar one step higher (in ms)
+
+type
+ TPlayerScoreScreenTexture = record // holds all colorized textures for up to 6 players
+ //Bar textures
+ Score_NoteBarLevel_Dark : TTexture; // Note
+ Score_NoteBarRound_Dark : TTexture; // that's the round thing on top
+
+ Score_NoteBarLevel_Light : TTexture; // LineBonus | Phrasebonus
+ Score_NoteBarRound_Light : TTexture;
+
+ Score_NoteBarLevel_Lightest : TTexture; // GoldenNotes
+ Score_NoteBarRound_Lightest : TTexture;
+ end;
+
+ TPlayerScoreScreenData = record // holds the positions and other data
+ Bar_Y :Real;
+ Bar_Actual_Height : Real; // this one holds the actual height of the bar, while we animate it
+ BarScore_ActualHeight : Real;
+ BarLine_ActualHeight : Real;
+ BarGolden_ActualHeight : Real;
+ end;
+
+ TPlayerScoreRatingPics = record // a fine array of the rating pictures
+ RateEaseStep : Integer;
+ RateEaseValue: Real;
+ end;
+
+ TScreenScore = class(TMenu)
+ private
+ BarTime : Cardinal;
+ ArrayStartModifier : integer;
+ public
+ aPlayerScoreScreenTextures : array[1..6] of TPlayerScoreScreenTexture;
+ aPlayerScoreScreenDatas : array[1..6] of TPlayerScoreScreenData;
+ aPlayerScoreScreenRatings : array[1..6] of TPlayerScoreRatingPics;
+
+ BarScore_EaseOut_Step : real;
+ BarPhrase_EaseOut_Step : real;
+ BarGolden_EaseOut_Step : real;
+
+ TextArtist: integer;
+ TextTitle: integer;
+
+ TextArtistTitle : integer;
+
+ TextName: array[1..6] of integer;
+ TextScore: array[1..6] of integer;
+
+ TextNotes: array[1..6] of integer;
+ TextNotesScore: array[1..6] of integer;
+ TextLineBonus: array[1..6] of integer;
+ TextLineBonusScore: array[1..6] of integer;
+ TextGoldenNotes: array[1..6] of integer;
+ TextGoldenNotesScore: array[1..6] of integer;
+ TextTotal: array[1..6] of integer;
+ TextTotalScore: array[1..6] of integer;
+
+ PlayerStatic: array[1..6] of array of integer;
+ PlayerTexts : array[1..6] of array of integer;
+
+
+ StaticBoxLightest: array[1..6] of integer;
+ StaticBoxLight: array[1..6] of integer;
+ StaticBoxDark: array[1..6] of integer;
+
+ StaticBackLevel: array[1..6] of integer;
+ StaticBackLevelRound: array[1..6] of integer;
+ StaticLevel: array[1..6] of integer;
+ StaticLevelRound: array[1..6] of integer;
+
+ Animation: real;
+
+ TextScore_ActualValue : array[1..6] of integer;
+ TextPhrase_ActualValue : array[1..6] of integer;
+ TextGolden_ActualValue : array[1..6] of integer;
+
+
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onShowFinish; override;
+ function Draw: boolean; override;
+ procedure FillPlayer(Item, P: integer);
+
+ procedure EaseBarIn(PlayerNumber : Integer; BarType: String);
+ procedure EaseScoreIn(PlayerNumber : Integer; ScoreType: String);
+
+ procedure FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
+
+
+ procedure DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
+
+ //Rating Picture
+ procedure ShowRating(PlayerNumber: integer);
+ function CalculateBouncing(PlayerNumber : Integer): real;
+ procedure DrawRating(PlayerNumber:integer;Rating:integer);
+ end;
+
+implementation
+
+
+uses UGraphic,
+ UScreenSong,
+ UMenuStatic,
+ UTime,
+ UMain,
+ UIni,
+ ULog,
+ ULanguage;
+
+function TScreenScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE,
+ SDLK_RETURN:
+ begin
+ FadeTo(@ScreenTop5);
+ Exit;
+ end;
+
+ SDLK_SYSREQ:
+ begin
+ Display.SaveScreenShot;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenScore.Create;
+var
+ Player: integer;
+ Counter: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Score);
+
+ // These two texts arn't used in the deluxe skin
+ TextArtist := AddText(Theme.Score.TextArtist);
+ TextTitle := AddText(Theme.Score.TextTitle);
+
+ TextArtistTitle := AddText(Theme.Score.TextArtistTitle);
+
+ for Player := 1 to 6 do
+ begin
+ SetLength(PlayerStatic[Player], Length(Theme.Score.PlayerStatic[Player]));
+ SetLength(PlayerTexts[Player], Length(Theme.Score.PlayerTexts[Player]));
+
+ for Counter := 0 to High(Theme.Score.PlayerStatic[Player]) do
+ PlayerStatic[Player, Counter] := AddStatic(Theme.Score.PlayerStatic[Player, Counter]);
+
+ for Counter := 0 to High(Theme.Score.PlayerTexts[Player]) do
+ PlayerTexts[Player, Counter] := AddText(Theme.Score.PlayerTexts[Player, Counter]);
+
+ TextName[Player] := AddText(Theme.Score.TextName[Player]);
+ TextScore[Player] := AddText(Theme.Score.TextScore[Player]);
+
+ TextNotes[Player] := AddText(Theme.Score.TextNotes[Player]);
+ TextNotesScore[Player] := AddText(Theme.Score.TextNotesScore[Player]);
+ TextLineBonus[Player] := AddText(Theme.Score.TextLineBonus[Player]);
+ TextLineBonusScore[Player] := AddText(Theme.Score.TextLineBonusScore[Player]);
+ TextGoldenNotes[Player] := AddText(Theme.Score.TextGoldenNotes[Player]);
+ TextGoldenNotesScore[Player] := AddText(Theme.Score.TextGoldenNotesScore[Player]);
+ TextTotal[Player] := AddText(Theme.Score.TextTotal[Player]);
+ TextTotalScore[Player] := AddText(Theme.Score.TextTotalScore[Player]);
+
+ StaticBoxLightest[Player] := AddStatic(Theme.Score.StaticBoxLightest[Player]);
+ StaticBoxLight[Player] := AddStatic(Theme.Score.StaticBoxLight[Player]);
+ StaticBoxDark[Player] := AddStatic(Theme.Score.StaticBoxDark[Player]);
+
+ StaticBackLevel[Player] := AddStatic(Theme.Score.StaticBackLevel[Player]);
+ StaticBackLevelRound[Player] := AddStatic(Theme.Score.StaticBackLevelRound[Player]);
+ StaticLevel[Player] := AddStatic(Theme.Score.StaticLevel[Player]);
+ StaticLevelRound[Player] := AddStatic(Theme.Score.StaticLevelRound[Player]);
+
+ //textures
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Dark := Tex_Score_NoteBarLevel_Dark[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Dark := Tex_Score_NoteBarRound_Dark[Player];
+
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Light := Tex_Score_NoteBarLevel_Light[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Light := Tex_Score_NoteBarRound_Light[Player];
+
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Lightest := Tex_Score_NoteBarLevel_Lightest[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Lightest := Tex_Score_NoteBarRound_Lightest[Player];
+ end;
+
+end;
+
+procedure TScreenScore.onShow;
+var
+ P: integer; // player
+ I: integer;
+ V: array[1..6] of boolean; // visibility array
+
+begin
+
+{**
+ * Turn backgroundmusic on
+ *}
+ SoundLib.StartBgMusic;
+
+ inherited;
+
+ // all statics / texts are loaded at start - so that we have them all even if we change the amount of players
+ // To show the corrects statics / text from the them, we simply modify the start of the according arrays
+ // 1 Player -> Player[0].Score (The score for one player starts at 0)
+ // -> Statics[1] (The statics for the one player screen start at 1)
+ // 2 Player -> Player[0..1].Score
+ // -> Statics[2..3]
+ // 3 Player -> Player[0..5].Score
+ // -> Statics[4..6]
+ case PlayersPlay of
+ 1: ArrayStartModifier := 0;
+ 2, 4: ArrayStartModifier := 1;
+ 3, 6: ArrayStartModifier := 3;
+ else
+ ArrayStartModifier := 0; //this should never happen
+ end;
+
+ for P := 1 to PlayersPlay do
+ begin
+ // data
+ aPlayerScoreScreenDatas[P].Bar_Y := Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
+
+ // ratings
+ aPlayerScoreScreenRatings[P].RateEaseStep := 1;
+ aPlayerScoreScreenRatings[P].RateEaseValue := 20;
+ end;
+
+
+ Text[TextArtist].Text := CurrentSong.Artist;
+ Text[TextTitle].Text := CurrentSong.Title;
+ Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
+
+ // set visibility
+ case PlayersPlay of
+ 1: begin
+ V[1] := true;
+ V[2] := false;
+ V[3] := false;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 2, 4: begin
+ V[1] := false;
+ V[2] := true;
+ V[3] := true;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 3, 6: begin
+ V[1] := false;
+ V[2] := false;
+ V[3] := false;
+ V[4] := true;
+ V[5] := true;
+ V[6] := true;
+ end;
+ end;
+
+ for P := 1 to 6 do
+ begin
+ Text[TextName[P]].Visible := V[P];
+ Text[TextScore[P]].Visible := V[P];
+
+ // We set alpha to 0 , so we can nicely blend them in when we need them
+ Text[TextScore[P]].Alpha := 0;
+ Text[TextNotesScore[P]].Alpha := 0;
+ Text[TextNotes[P]].Alpha := 0;
+ Text[TextLineBonus[P]].Alpha := 0;
+ Text[TextLineBonusScore[P]].Alpha := 0;
+ Text[TextGoldenNotes[P]].Alpha := 0;
+ Text[TextGoldenNotesScore[P]].Alpha := 0;
+ Text[TextTotal[P]].Alpha := 0;
+ Text[TextTotalScore[P]].Alpha := 0;
+ Static[StaticBoxLightest[P]].Texture.Alpha := 0;
+ Static[StaticBoxLight[P]].Texture.Alpha := 0;
+ Static[StaticBoxDark[P]].Texture.Alpha := 0;
+
+
+ Text[TextNotes[P]].Visible := V[P];
+ Text[TextNotesScore[P]].Visible := V[P];
+ Text[TextLineBonus[P]].Visible := V[P];
+ Text[TextLineBonusScore[P]].Visible := V[P];
+ Text[TextGoldenNotes[P]].Visible := V[P];
+ Text[TextGoldenNotesScore[P]].Visible := V[P];
+ Text[TextTotal[P]].Visible := V[P];
+ Text[TextTotalScore[P]].Visible := V[P];
+
+ for I := 0 to high(PlayerStatic[P]) do
+ Static[PlayerStatic[P, I]].Visible := V[P];
+
+ for I := 0 to high(PlayerTexts[P]) do
+ Text[PlayerTexts[P, I]].Visible := V[P];
+
+ Static[StaticBoxLightest[P]].Visible := V[P];
+ Static[StaticBoxLight[P]].Visible := V[P];
+ Static[StaticBoxDark[P]].Visible := V[P];
+
+ // we draw that on our own
+ Static[StaticBackLevel[P]].Visible := false;
+ Static[StaticBackLevelRound[P]].Visible := false;
+ Static[StaticLevel[P]].Visible := false;
+ Static[StaticLevelRound[P]].Visible := false;
+ end;
+end;
+
+procedure TScreenScore.onShowFinish;
+var
+ index : integer;
+begin
+ for index := 1 to (PlayersPlay) do
+ begin
+ TextScore_ActualValue[index] := 0;
+ TextPhrase_ActualValue[index] := 0;
+ TextGolden_ActualValue[index] := 0;
+ end;
+
+ BarScore_EaseOut_Step := 1;
+ BarPhrase_EaseOut_Step := 1;
+ BarGolden_EaseOut_Step := 1;
+end;
+
+function TScreenScore.Draw: boolean;
+var
+ CurrentTime : Cardinal;
+ PlayerCounter : integer;
+begin
+
+ inherited Draw;
+{*
+ player[0].ScoreInt := 7000;
+ player[0].ScoreLineInt := 2000;
+ player[0].ScoreGoldenInt := 1000;
+ player[0].ScoreTotalInt := 10000;
+
+ player[1].ScoreInt := 2500;
+ player[1].ScoreLineInt := 1100;
+ player[1].ScoreGoldenInt := 900;
+ player[1].ScoreTotalInt := 4500;
+*}
+ // Let's start to arise the bars
+ CurrentTime := SDL_GetTicks();
+ if((CurrentTime >= BarTime) AND ShowFinish) then
+ begin
+ BarTime := CurrentTime + BarRaiseSpeed;
+
+ for PlayerCounter := 1 to PlayersPlay do
+ begin
+ // We actually arise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore)
+ if (BarScore_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarScore_EaseOut_Step:= BarScore_EaseOut_Step + 1;
+
+ // PhrasenBonus
+ if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
+ begin
+ if (BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1;
+
+
+ // GoldenNotebonus
+ if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
+ begin
+ if (BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1;
+
+ // Draw golden score bar #
+ EaseBarIn(PlayerCounter, 'Golden');
+ EaseScoreIn(PlayerCounter,'Golden');
+ end;
+
+ // Draw phrase score bar #
+ EaseBarIn(PlayerCounter, 'Line');
+ EaseScoreIn(PlayerCounter,'Line');
+ end;
+
+ // Draw plain score bar #
+ EaseBarIn(PlayerCounter, 'Note');
+ EaseScoreIn(PlayerCounter,'Note');
+
+
+ FillPlayerItems(PlayerCounter,'Funky');
+
+ end;
+ end;
+
+
+(*
+ //todo: i need a clever method to draw statics with their z value
+ for I := 0 to Length(Static) - 1 do
+ Static[I].Draw;
+ for I := 0 to Length(Text) - 1 do
+ Text[I].Draw;
+*)
+
+ Result := true;
+end;
+
+procedure TscreenScore.FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
+var
+ ThemeIndex: integer;
+begin
+ // todo: take the name from player[PlayerNumber].Name instead of the ini when this is done (mog)
+ Text[TextName[PlayerNumber + ArrayStartModifier]].Text := Ini.Name[PlayerNumber - 1];
+ // end todo
+
+ ThemeIndex := PlayerNumber + ArrayStartModifier;
+
+ //golden
+ Text[TextGoldenNotesScore[ThemeIndex]].Text := IntToStr(TextGolden_ActualValue[PlayerNumber]);
+ Text[TextGoldenNotesScore[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
+
+ Static[StaticBoxLightest[ThemeIndex]].Texture.Alpha := (BarGolden_EaseOut_Step / 100);
+ Text[TextGoldenNotes[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
+
+ // line bonus
+ Text[TextLineBonusScore[ThemeIndex]].Text := IntToStr(TextPhrase_ActualValue[PlayerNumber]);
+ Text[TextLineBonusScore[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
+
+ Static[StaticBoxLight[ThemeIndex]].Texture.Alpha := (BarPhrase_EaseOut_Step / 100);
+ Text[TextLineBonus[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
+
+ // plain score
+ Text[TextNotesScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber]);
+ Text[TextNotes[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Static[StaticBoxDark[ThemeIndex]].Texture.Alpha := (BarScore_EaseOut_Step / 100);
+ Text[TextNotesScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ // total score
+ Text[TextTotalScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber] + TextPhrase_ActualValue[PlayerNumber] + TextGolden_ActualValue[PlayerNumber]);
+ Text[TextTotalScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ if(BarGolden_EaseOut_Step = 100) then
+ begin
+ ShowRating(PlayerNumber);
+ end;
+end;
+
+
+procedure TScreenScore.ShowRating(PlayerNumber: integer);
+var
+ Rating : integer;
+ ThemeIndex : integer;
+begin
+
+ ThemeIndex := PlayerNumber + ArrayStartModifier;
+
+ case (Player[PlayerNumber-1].ScoreTotalInt) of
+ 0..2009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
+ Rating := 0;
+ end;
+ 2010..4009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_AMATEUR');
+ Rating := 1;
+ end;
+ 4010..5009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_WANNABE');
+ Rating := 2;
+ end;
+ 5010..6009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_HOPEFUL');
+ Rating := 3;
+ end;
+ 6010..7509:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_RISING_STAR');
+ Rating := 4;
+ end;
+ 7510..8509:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
+ Rating := 5;
+ end;
+ 8510..9009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
+ Rating := 6;
+ end;
+ 9010..10000:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_ULTRASTAR');
+ Rating := 7;
+ end;
+ else
+ Rating := 0; // Cheata :P
+ end;
+
+ //todo: this could break if the width is not given, for instance when there's a skin with no picture for ratings
+ if ( Theme.Score.StaticRatings[ThemeIndex].W > 0 ) AND ( aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue > 0 ) then
+ begin
+ Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
+ end;
+ // end todo
+
+ DrawRating(PlayerNumber, Rating);
+end;
+
+procedure TscreenScore.DrawRating(PlayerNumber:integer;Rating:integer);
+var
+ Posx : real;
+ Posy : real;
+ Width :real;
+begin
+
+ CalculateBouncing(PlayerNumber);
+
+ PosX := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].X + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W * 0.5);
+ PosY := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].Y + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].H * 0.5); ;
+
+ Width := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue/2;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Score_Ratings[Rating].TexNum);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(PosX - Width, PosY - Width);
+ glTexCoord2f(Tex_Score_Ratings[Rating].TexW, 0); glVertex2f(PosX + Width, PosY - Width);
+ glTexCoord2f(Tex_Score_Ratings[Rating].TexW, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX + Width, PosY + Width);
+ glTexCoord2f(0, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX - Width, PosY + Width);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+end;
+
+
+
+function TscreenScore.CalculateBouncing(PlayerNumber : Integer): real;
+var
+ ReturnValue : real;
+ p, s : real;
+
+ RaiseStep, MaxVal : real;
+ EaseOut_Step : integer;
+begin
+ EaseOut_Step := aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep;
+ MaxVal := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W;
+
+ RaiseStep := EaseOut_Step;
+
+ if (MaxVal > 0) AND (RaiseStep > 0) then
+ RaiseStep := RaiseStep / MaxVal;
+
+ if (RaiseStep = 1) then
+ begin
+ ReturnValue := MaxVal;
+ end
+ else
+ begin
+ p := MaxVal * 0.4;
+
+ s := p/(2*PI) * arcsin (1);
+ ReturnValue := MaxVal * power(2,-5 * RaiseStep) * sin( (RaiseStep * MaxVal - s) * (2 * PI) / p) + MaxVal;
+
+ inc(aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep);
+ aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue := ReturnValue;
+ end;
+
+ Result := ReturnValue;
+end;
+
+
+procedure TscreenScore.EaseBarIn(PlayerNumber : Integer; BarType: String);
+const
+ RaiseSmoothness : integer = 100;
+var
+ MaxHeight : real;
+ NewHeight : real;
+
+ Height2Reach : real;
+ RaiseStep : real;
+ BarStartPosY : single;
+
+ lTmp : real;
+ Score : integer;
+begin
+ MaxHeight := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].H;
+
+ // let's get the points according to the bar we draw
+ // score array starts at 0, which means the score for player 1 is in score[0]
+ // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
+ if (BarType = 'Note') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreInt;
+ RaiseStep := BarScore_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight;
+ end
+ else if (BarType = 'Line') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreLineInt;
+ RaiseStep := BarPhrase_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight;
+ end
+ else if (BarType = 'Golden') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreGoldenInt;
+ RaiseStep := BarGolden_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight;
+ end
+ else
+ begin
+ Log.LogCritical('Unknown bar-type: ' + BarType, 'TScreenScore.EaseBarIn');
+ Exit; // suppress warnings
+ end;
+
+ // the height dependend of the score
+ Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight;
+
+ if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then
+ begin
+ // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions
+ // Calculate the actual step according to the maxsteps
+ RaiseStep := RaiseStep / EaseOut_MaxSteps;
+
+ // quadratic easing out - decelerating to zero velocity
+ // -end_position * current_time * ( current_time - 2 ) + start_postion
+ lTmp := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY);
+
+ if ( RaiseSmoothness > 0 ) and ( lTmp > 0 ) then
+ NewHeight := lTmp / RaiseSmoothness;
+
+ end
+ else
+ NewHeight := Height2Reach;
+
+ DrawBar(BarType, PlayerNumber, BarStartPosY, NewHeight);
+
+ if (BarType = 'Note') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight := NewHeight
+ else if (BarType = 'Line') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight := NewHeight
+ else if (BarType = 'Golden') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarGolden_ActualHeight := NewHeight;
+end;
+
+procedure TscreenScore.DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
+var
+ Width:real;
+ BarStartPosX:real;
+begin
+ // this is solely for better readability of the drawing
+ Width := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].W;
+ BarStartPosX := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].X;
+
+ glColor4f(1, 1, 1, 1);
+
+ // set the texture for the bar
+ if (BarType = 'Note') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Dark.TexNum);
+ if (BarType = 'Line') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Light.TexNum);
+ if (BarType = 'Golden') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Lightest.TexNum);
+
+ //draw it
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY, ZBars);
+ glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY, ZBars);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+
+ //the round thing on top
+ if (BarType = 'Note') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Dark.TexNum);
+ if (BarType = 'Line') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Light.TexNum);
+ if (BarType = 'Golden') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Lightest.TexNum);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
+ glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
+ glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+end;
+
+procedure TScreenScore.EaseScoreIn(PlayerNumber: integer; ScoreType : String);
+const
+ RaiseSmoothness : integer = 100;
+var
+ RaiseStep : Real;
+ lTmpA : Real;
+ ScoreReached :Integer;
+ EaseOut_Step :Real;
+ ActualScoreValue:integer;
+begin
+ if (ScoreType = 'Note') then
+ begin
+ EaseOut_Step := BarScore_EaseOut_Step;
+ ActualScoreValue := TextScore_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreInt;
+ end;
+ if (ScoreType = 'Line') then
+ begin
+ EaseOut_Step := BarPhrase_EaseOut_Step;
+ ActualScoreValue := TextPhrase_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreLineInt;
+ end;
+ if (ScoreType = 'Golden') then
+ begin
+ EaseOut_Step := BarGolden_EaseOut_Step;
+ ActualScoreValue := TextGolden_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt;
+ end;
+
+ // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
+ RaiseStep := EaseOut_Step;
+
+ if (ActualScoreValue < ScoreReached) then
+ begin
+ // Calculate the actual step according to the maxsteps
+ RaiseStep := RaiseStep / EaseOut_MaxSteps;
+
+ // quadratic easing out - decelerating to zero velocity
+ // -end_position * current_time * ( current_time - 2 ) + start_postion
+ lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20));
+ if ( lTmpA > 0 ) AND
+ ( RaiseSmoothness > 0 ) then
+ begin
+ if (ScoreType = 'Note') then
+ TextScore_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ if (ScoreType = 'Line') then
+ TextPhrase_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ if (ScoreType = 'Golden') then
+ TextGolden_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ end;
+ end
+ else
+ begin
+ if (ScoreType = 'Note') then
+ TextScore_ActualValue[PlayerNumber] := ScoreReached;
+ if (ScoreType = 'Line') then
+ TextPhrase_ActualValue[PlayerNumber] := ScoreReached;
+ if (ScoreType = 'Golden') then
+ TextGolden_ActualValue[PlayerNumber] := ScoreReached;
+ end;
+end;
+
+procedure TScreenScore.FillPlayer(Item, P: integer);
+var
+ S: string;
+begin
+ Text[TextName[Item]].Text := Ini.Name[P];
+
+ S := IntToStr((Round(Player[P].Score) div 10) * 10);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextNotesScore[Item]].Text := S;
+
+ // while (Length(S)<5) do S := '0' + S;
+ // Text[TextTotalScore[Item]].Text := S;
+
+ //fixed: line bonus and golden notes don't show up,
+ // another bug: total score was shown without added golden-, linebonus
+ S := IntToStr(Player[P].ScoreTotalInt);
+ while (Length(S)<5) do
+ S := '0' + S;
+ Text[TextTotalScore[Item]].Text := S;
+
+ S := IntToStr(Player[P].ScoreLineInt);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextLineBonusScore[Item]].Text := S;
+
+ S := IntToStr(Player[P].ScoreGoldenInt);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextGoldenNotesScore[Item]].Text := S;
+ //end of fix
+
+
+end;
+
+end.
diff --git a/src/Screens/UScreenSing.pas b/src/Screens/UScreenSing.pas
new file mode 100644
index 00000000..911d122e
--- /dev/null
+++ b/src/Screens/UScreenSing.pas
@@ -0,0 +1,934 @@
+unit UScreenSing;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ gl,
+ UThemes,
+ UGraphicClasses,
+ USingScores;
+
+type
+ TLyricsSyncSource = class(TSyncSource)
+ function GetClock(): real; override;
+ end;
+
+type
+ TScreenSing = class(TMenu)
+ protected
+ Paused: boolean; //Pause Mod
+ LyricsSync: TLyricsSyncSource;
+ NumEmptySentences: integer;
+ public
+ //TextTime: integer;
+
+ // TimeBar fields
+ StaticTimeProgress: integer;
+ TextTimeText: integer;
+
+ StaticP1: integer;
+ TextP1: integer;
+
+ //shown when game is in 2/4 player modus
+ StaticP1TwoP: integer;
+ TextP1TwoP: integer;
+
+ //shown when game is in 3/6 player modus
+ StaticP1ThreeP: integer;
+ TextP1ThreeP: integer;
+
+ StaticP2R: integer;
+ TextP2R: integer;
+
+ StaticP2M: integer;
+ TextP2M: integer;
+
+ StaticP3R: integer;
+ TextP3R: integer;
+
+ StaticPausePopup: integer;
+
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Lyrics: TLyricEngine;
+
+ //Score Manager:
+ Scores: TSingScores;
+
+ fShowVisualization: boolean;
+ fCurrentVideoPlaybackEngine: IVideoPlayback;
+
+ constructor Create; override;
+ procedure onShow; override;
+ procedure onShowFinish; override;
+
+ function ParseInput(PressedKey: cardinal; CharCode: widechar;
+ PressedDown: boolean): boolean; override;
+ function Draw: boolean; override;
+
+ procedure Finish; virtual;
+ procedure Pause; // Toggle Pause
+
+ procedure OnSentenceEnd(SentenceIndex: cardinal); // for LineBonus + Singbar
+ procedure OnSentenceChange(SentenceIndex: cardinal); // for Golden Notes
+ end;
+
+implementation
+
+uses UGraphic,
+ UDraw,
+ UMain,
+ USong,
+ Classes,
+ URecord,
+ ULanguage,
+ Math;
+
+ // Method for input parsing. If False is returned, GetNextWindow
+ // should be checked to know the next window to load;
+function TScreenSing.ParseInput(PressedKey: cardinal; CharCode: widechar;
+ PressedDown: boolean): boolean;
+begin
+ Result := True;
+ if (PressedDown) then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ //When not ask before Exit then Finish now
+ if (Ini.AskbeforeDel <> 1) then
+ Finish
+ //else just Pause and let the Popup make the Work
+ else if not Paused then
+ Pause;
+
+ Result := False;
+ Exit;
+ end;
+ 'V': //Show Visualization
+ begin
+ fShowVisualization := not fShowVisualization;
+
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine := Visualization
+ else
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine.play;
+
+ Exit;
+ end;
+ 'P':
+ begin
+ Pause;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ //Record Sound Hack:
+ //Sound[0].BufferLong
+
+ Finish;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenScore);
+ end;
+
+ SDLK_SPACE:
+ begin
+ Pause;
+ end;
+
+ SDLK_TAB: //Change Visualization Preset
+ begin
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine.Position := now; // move to a random position
+ end;
+
+ SDLK_RETURN:
+ begin
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN:
+ begin
+ end;
+ SDLK_UP:
+ begin
+ end;
+ end;
+ end;
+end;
+
+//Pause Mod
+procedure TScreenSing.Pause;
+begin
+ if (not Paused) then //enable Pause
+ begin
+ // pause Time
+ Paused := True;
+
+ LyricsState.Pause();
+
+ // pause Music
+ AudioPlayback.Pause;
+
+ // pause Video
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path +
+ CurrentSong.Video) then
+ fCurrentVideoPlaybackEngine.Pause;
+
+ end
+ else //disable Pause
+ begin
+ LyricsState.Resume();
+
+ // Play Music
+ AudioPlayback.Play;
+
+ // Video
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path +
+ CurrentSong.Video) then
+ fCurrentVideoPlaybackEngine.Pause;
+
+ Paused := False;
+ end;
+end;
+//Pause Mod End
+
+constructor TScreenSing.Create;
+var
+ I: integer;
+ P: integer;
+begin
+ inherited Create;
+
+ fShowVisualization := False;
+
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ //Create Score Class
+ Scores := TSingScores.Create;
+ Scores.LoadfromTheme;
+
+ LoadFromTheme(Theme.Sing);
+
+ //TimeBar
+ StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
+ TextTimeText := AddText(Theme.Sing.TextTimeText);
+
+ // 1 player | P1
+ StaticP1 := AddStatic(Theme.Sing.StaticP1);
+ TextP1 := AddText(Theme.Sing.TextP1);
+
+ // 2 or 4 players | P1
+ StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
+ TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
+
+ // | P2
+ StaticP2R := AddStatic(Theme.Sing.StaticP2R);
+ TextP2R := AddText(Theme.Sing.TextP2R);
+
+ // 3 or 6 players | P1
+ StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
+ TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
+
+ // | P2
+ StaticP2M := AddStatic(Theme.Sing.StaticP2M);
+ TextP2M := AddText(Theme.Sing.TextP2M);
+
+ // | P3
+ StaticP3R := AddStatic(Theme.Sing.StaticP3R);
+ TextP3R := AddText(Theme.Sing.TextP3R);
+
+ StaticPausePopup := AddStatic(Theme.Sing.PausePopUp);
+
+ //Pausepopup is not visibile at the beginning
+ Static[StaticPausePopup].Visible := False;
+
+ Lyrics := TLyricEngine.Create(80, Skin_LyricsT, 640, 12, 80, Skin_LyricsT + 36, 640, 12);
+
+ LyricsSync := TLyricsSyncSource.Create();
+end;
+
+procedure TScreenSing.onShow;
+var
+ P: integer;
+ V1: boolean;
+ V1TwoP: boolean; //Position of ScoreBox in two-player mode
+ V1ThreeP: boolean; //Position of ScoreBox in three-player mode
+ V2R: boolean;
+ V2M: boolean;
+ V3R: boolean;
+ NR: TRecR; //Some enlightment of who, how and what this is here please
+ Color: TRGB;
+
+ success: boolean;
+begin
+ inherited;
+
+ Log.LogStatus('Begin', 'onShow');
+ FadeOut := False;
+
+ // reset video playback engine, to play Video Clip...
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ // setup score manager
+ Scores.ClearPlayers; // clear old player values
+ Color.R := 0;
+ Color.G := 0;
+ Color.B := 0; // dummy atm <- \(O.o)/? B like bummy?
+
+ // add new players
+ for P := 0 to PlayersPlay - 1 do
+ begin
+ Scores.AddPlayer(Tex_ScoreBG[P], Color);
+ end;
+
+ Scores.Init; //Get Positions for Players
+
+ // prepare players
+ SetLength(Player, PlayersPlay);
+
+ case PlayersPlay of
+ 1:
+ begin
+ V1 := True;
+ V1TwoP := False;
+ V1ThreeP := False;
+ V2R := False;
+ V2M := False;
+ V3R := False;
+ end;
+ 2:
+ begin
+ V1 := False;
+ V1TwoP := True;
+ V1ThreeP := False;
+ V2R := True;
+ V2M := False;
+ V3R := False;
+ end;
+ 3:
+ begin
+ V1 := False;
+ V1TwoP := False;
+ V1ThreeP := True;
+ V2R := False;
+ V2M := True;
+ V3R := True;
+ end;
+ 4:
+ begin // double screen
+ V1 := False;
+ V1TwoP := True;
+ V1ThreeP := False;
+ V2R := True;
+ V2M := False;
+ V3R := False;
+ end;
+ 6:
+ begin // double screen
+ V1 := False;
+ V1TwoP := False;
+ V1ThreeP := True;
+ V2R := False;
+ V2M := True;
+ V3R := True;
+ end;
+
+ end;
+
+ //This one is shown in 1P mode
+ Static[StaticP1].Visible := V1;
+ Text[TextP1].Visible := V1;
+
+
+ //This one is shown in 2/4P mode
+ Static[StaticP1TwoP].Visible := V1TwoP;
+ Text[TextP1TwoP].Visible := V1TwoP;
+
+ Static[StaticP2R].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+
+
+ //This one is shown in 3/6P mode
+ Static[StaticP1ThreeP].Visible := V1ThreeP;
+ Text[TextP1ThreeP].Visible := V1ThreeP;
+
+
+ Static[StaticP2M].Visible := V2M;
+ Text[TextP2M].Visible := V2M;
+
+
+ Static[StaticP3R].Visible := V3R;
+ Text[TextP3R].Visible := V3R;
+
+
+ // FIXME: sets Path and Filename to ''
+ ResetSingTemp;
+
+ CurrentSong := CatSongs.Song[CatSongs.Selected];
+
+ // FIXME: bad style, put the try-except into LoadSong() and not here
+ try
+ // Check if file is XML
+ if copy(CurrentSong.FileName, length(CurrentSong.FileName) - 3, 4) = '.xml' then
+ success := CurrentSong.LoadXMLSong()
+ else
+ success := CurrentSong.LoadSong();
+ except
+ success := False;
+ end;
+
+ if (not success) then
+ begin
+ // error loading song -> go back to song screen and show some error message
+ FadeTo(@ScreenSong);
+ // select new song in party mode
+ if ScreenSong.Mode = smPartyMode then
+ ScreenSong.SelectRandomSong();
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_CORRUPT_SONG'));
+ // FIXME: do we need this?
+ CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
+ Exit;
+ end;
+
+ // reset video playback engine, to play video clip...
+ fCurrentVideoPlaybackEngine.Close;
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+{**
+ * == Background ==
+ * We have four types of backgrounds:
+ * + Blank : Nothing has been set, this is our fallback
+ * + Picture : Picture has been set, and exists - otherwise we fallback
+ * + Video : Video has been set, and exists - otherwise we fallback
+ * + Visualization: + Off : No Visialization
+ * + WhenNoVideo: Overwrites Blank and Picture
+ * + On : Overwrites Blank, Picture and Video
+ *}
+{**
+ * set background to: video
+ *}
+ CurrentSong.VideoLoaded := False;
+ fShowVisualization := False;
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
+ begin
+ if (fCurrentVideoPlaybackEngine.Open(CurrentSong.Path + CurrentSong.Video)) then
+ begin
+ fShowVisualization := False;
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+ fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start;
+ CurrentSong.VideoLoaded := True;
+ fCurrentVideoPlaybackEngine.play;
+ end;
+ end;
+
+{**
+ * set background to: picture
+ *}
+ if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = False)
+ and (TVisualizerOption(Ini.VisualizerOption) = voOff) then
+ try
+ Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background);
+ except
+ Log.LogError('Background could not be loaded: ' + CurrentSong.Path +
+ CurrentSong.Background);
+ Tex_Background.TexNum := 0;
+ end
+ else
+ Tex_Background.TexNum := 0;
+{**
+ * set background to: visualization (Overwrites all)
+ *}
+ if (TVisualizerOption(Ini.VisualizerOption) in [voOn]) then
+ begin
+ fShowVisualization := True;
+ fCurrentVideoPlaybackEngine := Visualization;
+ fCurrentVideoPlaybackEngine.play;
+ end;
+
+{**
+ * set background to: visualization (Videos are still shown)
+ *}
+ if ((TVisualizerOption(Ini.VisualizerOption) in [voWhenNoVideo]) and
+ (CurrentSong.VideoLoaded = False)) then
+ begin
+ fShowVisualization := True;
+ fCurrentVideoPlaybackEngine := Visualization;
+ fCurrentVideoPlaybackEngine.play;
+ end;
+
+ // prepare lyrics timer
+ LyricsState.Reset();
+ LyricsState.SetCurrentTime(CurrentSong.Start);
+ LyricsState.StartTime := CurrentSong.Gap;
+ if (CurrentSong.Finish > 0) then
+ LyricsState.TotalTime := CurrentSong.Finish / 1000
+ else
+ LyricsState.TotalTime := AudioPlayback.Length;
+ LyricsState.UpdateBeats();
+
+ // prepare music
+ AudioPlayback.Stop();
+ AudioPlayback.Position := CurrentSong.Start;
+ // synchronize music to the lyrics
+ AudioPlayback.SetSyncSource(LyricsSync);
+
+ // prepare and start voice-capture
+ AudioInput.CaptureStart;
+
+ for P := 0 to High(Player) do
+ ClearScores(P);
+
+ // main text
+ Lyrics.Clear(CurrentSong.BPM[0].BPM, CurrentSong.Resolution);
+
+ // set custom options
+ case Ini.LyricsFont of
+ 0:
+ begin
+ Lyrics.UpperLineSize := 14;
+ Lyrics.LowerLineSize := 14;
+ Lyrics.FontStyle := 0;
+
+ Lyrics.LineColor_en.R := Skin_FontR;
+ Lyrics.LineColor_en.G := Skin_FontG;
+ Lyrics.LineColor_en.B := Skin_FontB;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.4;
+ Lyrics.LineColor_dis.G := 0.4;
+ Lyrics.LineColor_dis.B := 0.4;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 5 / 256;
+ Lyrics.LineColor_act.G := 163 / 256;
+ Lyrics.LineColor_act.B := 210 / 256;
+ Lyrics.LineColor_act.A := 1;
+ end;
+ 1:
+ begin
+ Lyrics.UpperLineSize := 14;
+ Lyrics.LowerLineSize := 14;
+ Lyrics.FontStyle := 2;
+
+ Lyrics.LineColor_en.R := 0.75;
+ Lyrics.LineColor_en.G := 0.75;
+ Lyrics.LineColor_en.B := 1;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.8;
+ Lyrics.LineColor_dis.G := 0.8;
+ Lyrics.LineColor_dis.B := 0.8;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 0.5;
+ Lyrics.LineColor_act.G := 0.5;
+ Lyrics.LineColor_act.B := 1;
+ Lyrics.LineColor_act.A := 1;
+ end;
+ 2:
+ begin
+ Lyrics.UpperLineSize := 12;
+ Lyrics.LowerLineSize := 12;
+ Lyrics.FontStyle := 3;
+
+ Lyrics.LineColor_en.R := 0.75;
+ Lyrics.LineColor_en.G := 0.75;
+ Lyrics.LineColor_en.B := 1;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.8;
+ Lyrics.LineColor_dis.G := 0.8;
+ Lyrics.LineColor_dis.B := 0.8;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 0.5;
+ Lyrics.LineColor_act.G := 0.5;
+ Lyrics.LineColor_act.B := 1;
+ Lyrics.LineColor_act.A := 1;
+ end;
+ end; // case
+
+ // Initialize lyrics by filling its queue
+ while (not Lyrics.IsQueueFull) and (Lyrics.LineCounter <=
+ High(Lines[0].Line)) do
+ begin
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+ end;
+
+ // Deactivate pause
+ Paused := False;
+
+ // Kill all stars not killed yet (GoldenStarsTwinkle Mod)
+ GoldenRec.SentenceChange;
+
+ // set Position of Line Bonus - Line Bonus end
+ // set number of empty sentences for Line Bonus
+ NumEmptySentences := 0;
+ for P := Low(Lines[0].Line) to High(Lines[0].Line) do
+ if Lines[0].Line[P].TotalNotes = 0 then
+ Inc(NumEmptySentences);
+
+ Log.LogStatus('End', 'onShow');
+end;
+
+procedure TScreenSing.onShowFinish;
+begin
+ // start lyrics
+ LyricsState.Resume();
+
+ // start music
+ AudioPlayback.Play();
+
+ // start timer
+ CountSkipTimeSet;
+end;
+
+function TScreenSing.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Flash: real;
+ S: integer;
+ T: integer;
+ CurLyricsTime: real;
+begin
+
+ // set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then
+ begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1';
+ Text[TextP1ThreeP].Text := 'P1';
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then
+ begin
+ case PlayersPlay of
+ 4:
+ begin
+ Text[TextP1TwoP].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6:
+ begin
+ Text[TextP1ThreeP].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+
+ ////
+ // dual screen, part 1
+ ////////////////////////
+
+ // Note: ScreenX is the offset of the current screen in dual-screen mode so we
+ // will move the statics and texts to the correct screen here.
+ // FIXME: clean up this weird stuff. Commenting this stuff out, nothing
+ // was missing on screen w/ 6 players - so do we even need this stuff?
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10 * ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X + 10 * ScreenX;
+
+ {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10 * ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X + 10 * ScreenX;
+
+ {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
+
+ // end of weird stuff
+
+ Static[1].Texture.X := Static[1].Texture.X + 10 * ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10 * ScreenX;
+
+
+
+ // retrieve current lyrics time, we have to store the value to avoid
+ // that min- and sec-values do not match
+ CurLyricsTime := LyricsState.GetCurrentTime();
+ Min := Round(CurLyricsTime) div 60;
+ Sec := Round(CurLyricsTime) mod 60;
+
+ // update static menu with time ...
+ Text[TextTimeText].Text := '';
+ if Min < 10 then
+ Text[TextTimeText].Text := '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
+ if Sec < 10 then
+ Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
+
+ // draw static menu (BG)
+ // Note: there is no menu and the animated background brakes the video playback
+ //DrawBG;
+
+ // Draw Background
+ SingDrawBackground;
+
+ // update and draw movie
+ if (ShowFinish and (CurrentSong.VideoLoaded or fShowVisualization)) then
+ begin
+ if assigned(fCurrentVideoPlaybackEngine) then
+ begin
+ fCurrentVideoPlaybackEngine.GetFrame(LyricsState.GetCurrentTime());
+ fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
+ end;
+ end;
+
+ // draw static menu (FG)
+ DrawFG;
+
+ // check for music finish
+ //Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LyricsState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish));
+ if ShowFinish then
+ begin
+ if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or
+ (LyricsState.GetCurrentTime() * 1000 <= CurrentSong.Finish)) then
+ begin
+ // analyze song if not paused
+ if (not Paused) then
+ Sing(Self);
+ end
+ else
+ begin
+ if (not FadeOut) then
+ begin
+ Finish;
+ FadeOut := True;
+ FadeTo(@ScreenScore);
+ end;
+ end;
+ end;
+
+ // always draw custom items
+ SingDraw;
+
+ //GoldenNoteStarsTwinkle
+ GoldenRec.SpawnRec;
+
+ //Draw Scores
+ Scores.Draw;
+
+ ////
+ // dual screen, part 2
+ ////////////////////////
+
+ // Note: ScreenX is the offset of the current screen in dual-screen mode so we
+ // will move the statics and texts to the correct screen here.
+ // FIXME: clean up this weird stuff
+
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10 * ScreenX;
+ Text[TextP1].X := Text[TextP1].X - 10 * ScreenX;
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10 * ScreenX;
+ Text[TextP2R].X := Text[TextP2R].X - 10 * ScreenX;
+
+ //end of weird
+
+ Static[1].Texture.X := Static[1].Texture.X - 10 * ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10 * ScreenX;
+
+ // Draw Pausepopup
+ // FIXME: this is a workaround that the Static is drawn over the Lyrics, Lines, Scores and Effects
+ // maybe someone could find a better solution
+ if Paused then
+ begin
+ Static[StaticPausePopup].Visible := True;
+ Static[StaticPausePopup].Draw;
+ Static[StaticPausePopup].Visible := False;
+ end;
+
+ Result := True;
+end;
+
+procedure TScreenSing.Finish;
+begin
+ AudioInput.CaptureStop;
+ AudioPlayback.Stop;
+ AudioPlayback.SetSyncSource(nil);
+
+ if (Ini.SavePlayback = 1) then
+ begin
+ Log.BenchmarkStart(0);
+ Log.LogVoice(0);
+ Log.LogVoice(1);
+ Log.LogVoice(2);
+ Log.BenchmarkEnd(0);
+ Log.LogBenchmark('Creating files', 0);
+ end;
+
+ if CurrentSong.VideoLoaded then
+ begin
+ fCurrentVideoPlaybackEngine.Close;
+ CurrentSong.VideoLoaded := False; // to prevent drawing closed video
+ end;
+
+ SetFontItalic(False);
+end;
+
+procedure TScreenSing.OnSentenceEnd(SentenceIndex: cardinal);
+var
+ PlayerIndex: integer;
+ CurrentPlayer: PPLayer;
+ CurrentScore: real;
+ Line: PLine;
+ LinePerfection: real; // perfection of singing performance on the current line
+ Rating: integer;
+ LineScore: real;
+ LineBonus: real;
+ MaxSongScore: integer; // max. points for the song (without line bonus)
+ MaxLineScore: real; // max. points for the current line
+const
+ // TODO: move this to a better place
+ MAX_LINE_RATING = 8; // max. rating for singing performance
+begin
+ Line := @Lines[0].Line[SentenceIndex];
+
+ // check for empty sentence
+ if (Line.TotalNotes <= 0) then
+ Exit;
+
+ // set max song score
+ if (Ini.LineBonus = 0) then
+ MaxSongScore := MAX_SONG_SCORE
+ else
+ MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
+
+ // Note: ScoreValue is the sum of all note values of the song
+ MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue);
+
+ for PlayerIndex := 0 to High(Player) do
+ begin
+ CurrentPlayer := @Player[PlayerIndex];
+ CurrentScore := CurrentPlayer.Score + CurrentPlayer.ScoreGolden;
+
+ // Line Bonus
+
+ // points for this line
+ LineScore := CurrentScore - CurrentPlayer.ScoreLast;
+
+ // determine LinePerfection
+ // Note: the "+2" extra points are a little bonus so the player does not
+ // have to be that perfect to reach the bonus steps.
+ LinePerfection := (LineScore + 2) / MaxLineScore;
+
+ // clamp LinePerfection to range [0..1]
+ if (LinePerfection < 0) then
+ LinePerfection := 0
+ else if (LinePerfection > 1) then
+ LinePerfection := 1;
+
+ // add line-bonus if enabled
+ if (Ini.LineBonus > 0) then
+ begin
+ // line-bonus points (same for each line, no matter how long the line is)
+ LineBonus := MAX_SONG_LINE_BONUS / (Length(Lines[0].Line) -
+ NumEmptySentences);
+ // apply line-bonus
+ CurrentPlayer.ScoreLine :=
+ CurrentPlayer.ScoreLine + LineBonus * LinePerfection;
+ CurrentPlayer.ScoreLineInt := Round(CurrentPlayer.ScoreLine / 10) * 10;
+ // update total score
+ CurrentPlayer.ScoreTotalInt :=
+ CurrentPlayer.ScoreInt +
+ CurrentPlayer.ScoreGoldenInt
+ + CurrentPlayer.ScoreLineInt;
+
+ // spawn rating pop-up
+ Rating := Round(LinePerfection * MAX_LINE_RATING);
+ Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt);
+ end;
+
+ // PerfectLineTwinkle (effect), Part 1
+ if (Ini.EffectSing = 1) then
+ CurrentPlayer.LastSentencePerfect := (LinePerfection >= 1);
+
+ // refresh last score
+ CurrentPlayer.ScoreLast := CurrentScore;
+ end;
+
+ // PerfectLineTwinkle (effect), Part 2
+ if (Ini.EffectSing = 1) then
+ GoldenRec.SpawnPerfectLineTwinkle;
+end;
+
+ // Called on sentence change
+ // SentenceIndex: index of the new active sentence
+procedure TScreenSing.OnSentenceChange(SentenceIndex: cardinal);
+var
+ LyricEngine: TLyricEngine;
+begin
+ //GoldenStarsTwinkle
+ GoldenRec.SentenceChange;
+
+ // Fill lyrics queue and set upper line to the current sentence
+ while (Lyrics.GetUpperLineIndex() < SentenceIndex) or
+ (not Lyrics.IsQueueFull) do
+ begin
+ // Add the next line to the queue or a dummy if no more lines are available
+ if (Lyrics.LineCounter <= High(Lines[0].Line)) then
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter])
+ else
+ Lyrics.AddLine(nil);
+ end;
+
+ // AddLine draws the passed line to the back-buffer of the render context
+ // and copies it into a texture afterwards (offscreen rendering).
+ // This leaves an in invalidated screen. Calling Draw() makes sure,
+ // that the back-buffer stores the sing-screen, when the next
+ // swap between the back- and front-buffer is done (eliminates flickering)
+ // calling AddLine() right before the regular screen update (Display.Draw)
+ // would be a better solution.
+ Draw;
+end;
+
+function TLyricsSyncSource.GetClock(): real;
+begin
+ Result := LyricsState.GetCurrentTime();
+end;
+
+end.
+
diff --git a/src/Screens/UScreenSingModi.pas b/src/Screens/UScreenSingModi.pas
new file mode 100644
index 00000000..616ba1c1
--- /dev/null
+++ b/src/Screens/UScreenSingModi.pas
@@ -0,0 +1,707 @@
+unit UScreenSingModi;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ gl,
+
+ UThemes,
+ //ULCD, //TODO: maybe LCD Support as Plugin?
+ UScreenSing,
+ ModiSDK;
+
+type
+ TScreenSingModi = class(TScreenSing)
+ protected
+ //paused: boolean; //Pause Mod
+ //PauseTime: Real;
+ //NumEmptySentences: integer;
+ public
+ //TextTime: integer;
+
+ //StaticP1: integer;
+ //StaticP1ScoreBG: integer;
+ //TextP1: integer;
+ //TextP1Score: integer;
+
+ //StaticP2R: integer;
+ //StaticP2RScoreBG: integer;
+ //TextP2R: integer;
+ //TextP2RScore: integer;
+
+ //StaticP2M: integer;
+ //StaticP2MScoreBG: integer;
+ //TextP2M: integer;
+ //TextP2MScore: integer;
+
+ //StaticP3R: integer;
+ //StaticP3RScoreBG: integer;
+ //TextP3R: integer;
+ //TextP3RScore: integer;
+
+ //Tex_Background: TTexture;
+ //FadeOut: boolean;
+ //LyricMain: TLyric;
+ //LyricSub: TLyric;
+ Winner: Byte; //Who Wins
+ PlayerInfo: TPlayerInfo;
+ TeamInfo: TTeamInfo;
+
+ constructor Create; override;
+ procedure onShow; override;
+ //procedure onShowFinish; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure Finish; override;
+ //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //procedure Pause; //Pause Mod(Toggles Pause)
+ end;
+
+type
+ TCustomSoundEntry = record
+ Filename : String;
+ Stream : TAudioPlaybackStream;
+ end;
+
+var
+ //Custom Sounds
+ CustomSounds: array of TCustomSoundEntry;
+
+//Procedured for Plugin
+function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall;
+//function Translate (const Name: PChar): PChar; stdcall;
+procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
+function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
+procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
+
+//Utilys
+function ToSentences(Const Lines: TLines): TSentences;
+
+implementation
+uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSingModi.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Finish;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenPartyScore);
+ end;
+
+ else
+ Result := inherited ParseInput(PressedKey, CharCode, PressedDown);
+ end;
+ end;
+end;
+
+constructor TScreenSingModi.Create;
+begin
+ inherited Create;
+
+end;
+
+function ToSentences(Const Lines: TLines): TSentences;
+var
+ I, J: Integer;
+begin
+ Result.Current := Lines.Current;
+ Result.High := Lines.High;
+ Result.Number := Lines.Number;
+ Result.Resolution := Lines.Resolution;
+ Result.NotesGAP := Lines.NotesGAP;
+ Result.TotalLength := Lines.ScoreValue;
+
+ SetLength(Result.Sentence, Length(Lines.Line));
+ for I := low(Result.Sentence) to high(Result.Sentence) do
+ begin
+ Result.Sentence[I].Start := Lines.Line[I].Start;
+ Result.Sentence[I].StartNote := Lines.Line[I].Note[0].Start;
+ Result.Sentence[I].Lyric := Lines.Line[I].Lyric;
+ Result.Sentence[I].LyricWidth := Lines.Line[I].LyricWidth;
+ Result.Sentence[I].End_ := Lines.Line[I].End_;
+ Result.Sentence[I].BaseNote := Lines.Line[I].BaseNote;
+ Result.Sentence[I].HighNote := Lines.Line[I].HighNote;
+ Result.Sentence[I].TotalNotes := Lines.Line[I].TotalNotes;
+
+ SetLength(Result.Sentence[I].Note, Length(Lines.Line[I].Note));
+ for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do
+ begin
+ Result.Sentence[I].Note[J].Color := Lines.Line[I].Note[J].Color;
+ Result.Sentence[I].Note[J].Start := Lines.Line[I].Note[J].Start;
+ Result.Sentence[I].Note[J].Length := Lines.Line[I].Note[J].Length;
+ Result.Sentence[I].Note[J].Tone := Lines.Line[I].Note[J].Tone;
+ //Result.Sentence[I].Note[J].Text := Lines.Line[I].Note[J].Tekst;
+ Result.Sentence[I].Note[J].FreeStyle := (Lines.Line[I].Note[J].NoteType = ntFreestyle);
+ end;
+ end;
+end;
+
+procedure TScreenSingModi.onShow;
+var
+ I: Integer;
+begin
+ inherited;
+
+ PlayersPlay := TeamInfo.NumTeams;
+
+ if DLLMan.Selected.LoadSong then //Start with Song
+ begin
+ inherited;
+ end
+ else //Start Without Song
+ begin
+ AudioInput.CaptureStart;
+ end;
+
+//Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]);
+ PlayerInfo.Playerinfo[I].Score := 0;
+ PlayerInfo.Playerinfo[I].Bar := 50;
+ PlayerInfo.Playerinfo[I].Enabled := True;
+ end;
+
+ for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do
+ begin
+ PlayerInfo.Playerinfo[I].Score:= 0;
+ PlayerInfo.Playerinfo[I].Bar := 0;
+ PlayerInfo.Playerinfo[I].Enabled := False;
+ end;
+
+ {Case PlayersPlay of
+ 1: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
+ end;
+ 2,4: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ end;
+ 3,6: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ end;
+ end; }
+
+ // play music (I)
+ //Music.CaptureStart;
+ //Music.MoveTo(AktSong.Start);
+
+ //Init Plugin
+ if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Lines[0]), LoadTex, Print, LoadSound, PlaySound) then
+ begin
+ //Fehler
+ Log.LogError('Could not Init Plugin');
+ Halt;
+ end;
+
+ // Set Background (Little Workaround, maybe change sometime)
+ if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then
+ ScreenSing.Tex_Background := Tex_Background;
+
+ Winner := 0;
+
+ //Set Score Visibility
+ {if PlayersPlay = 1 then begin
+ Text[TextP1Score].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin
+ Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin
+ Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end; }
+end;
+
+function TScreenSingModi.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ S, I: integer;
+ T: integer;
+ CurLyricsTime: real;
+begin
+ Result := false;
+
+ //Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name);
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ if (Player[I].ScoreTotalInt <= MAX_SONG_SCORE) then
+ PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalInt;
+ PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100);
+ end;
+ end;
+
+ //Show Score
+ if DLLMan.Selected.ShowScore then
+ begin
+ {//ScoreBG Mod
+ // set player colors
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+
+
+
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
+
+
+
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P3Dark');
+
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
+
+
+
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P6Dark');
+
+
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
+
+
+
+
+ end;
+ end;
+ //end ScoreBG Mod }
+
+ // set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin
+ Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then begin
+ case PlayersPlay of
+ 4: begin
+ Text[TextP1TwoP].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1ThreeP].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+
+ // stereo <- and where iss P2M? or P3?
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
+ Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
+
+ {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
+ Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
+
+ {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
+
+ // .. and scores
+ {if PlayersPlay = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1Score].Text := Tekst;
+ end;
+
+ if PlayersPlay = 2 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 3 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[4].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[5].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ end; }
+
+ end; //ShowScore
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10*ScreenX;
+
+ if DLLMan.Selected.LoadSong then
+ begin
+ // update static menu with time ...
+ CurLyricsTime := LyricsState.GetCurrentTime();
+ Min := Round(CurLyricsTime) div 60;
+ Sec := Round(CurLyricsTime) mod 60;
+
+ Text[TextTimeText].Text := '';
+ if Min < 10 then Text[TextTimeText].Text := '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
+ end;
+
+ // draw static menu (BG)
+ DrawBG;
+
+ //Draw Background
+ if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then
+ SingDrawBackground;
+
+ // comment by blindy: wo zum henker wird denn in diesem screen ein video abgespielt?
+ // update and draw movie
+ // wie wo wadd? also in der selben funktion in der uscreensing kommt des video in der zeile 995, oder was wollteste wissen? :X
+{ if ShowFinish and CurrentSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin
+ UpdateSmpeg; // this only draws
+ end;}
+
+ // draw static menu (FG)
+ DrawFG;
+
+ if ShowFinish then begin
+ if DllMan.Selected.LoadSong then
+ begin
+ if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (LyricsState.GetCurrentTime*1000 <= CurrentSong.Finish)) then begin
+ //Pause Mod:
+ if not Paused then
+ Sing(Self); // analyze song
+ end else begin
+ if not FadeOut then begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+ end;
+
+ // draw custom items
+ SingModiDraw(PlayerInfo); // always draw
+
+ //GoldenNoteStarsTwinkle Mod
+ GoldenRec.SpawnRec;
+ //GoldenNoteStarsTwinkle Mod
+
+ //Update PlayerInfo
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
+ PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalInt;
+ end;
+ end;
+
+ if ((ShowFinish) AND (NOT Paused)) then
+ begin
+ if not DLLMan.PluginDraw(Playerinfo, Lines[0].Current) then
+ begin
+ if not FadeOut then begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+
+ //Change PlayerInfo/Changeables
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if (Player[I].ScoreTotalInt <> PlayerInfo.Playerinfo[I].Score) then
+ begin
+ //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI);
+ Player[I].ScoreTotalInt := PlayerInfo.Playerinfo[I].Score;
+ end;
+ {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then
+ Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; }
+ end;
+
+ // back stereo
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
+ Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
+
+ {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;}
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
+ Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
+
+ {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;}
+
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10*ScreenX;
+
+ Result := true;
+end;
+
+procedure TScreenSingModi.Finish;
+begin
+inherited Finish;
+
+Winner := DllMan.PluginFinish(PlayerInfo);
+
+//Log.LogError('Winner: ' + InttoStr(Winner));
+
+//DLLMan.UnLoadPlugin;
+end;
+
+function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall;
+var
+ Texname, EXT: String;
+ Tex: TTexture;
+begin
+ //Get texture Name
+ TexName := Skin.GetTextureFileName(String(Name));
+ //Get File Typ
+ Ext := ExtractFileExt(TexName);
+ if (uppercase(Ext) = '.JPG') then
+ Ext := 'JPG'
+ else
+ Ext := 'BMP';
+
+ Tex := Texture.LoadTexture(false, PChar(TexName), UTEXTURE.TTextureType(Typ), 0);
+
+ Result.TexNum := Tex.TexNum;
+ Result.W := Tex.W;
+ Result.H := Tex.H;
+end;
+{
+function Translate (const Name: PChar): PChar; stdcall;
+begin
+ Result := PChar(Language.Translate(String(Name)));
+end; }
+
+procedure Print(const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
+begin
+ SetFontItalic ((Style and 128) = 128);
+ SetFontStyle(Style and 7);
+ SetFontSize(Size);
+ SetFontPos (X, Y);
+ glPrint (PChar(Language.Translate(String(Text))));
+end;
+
+function LoadSound(const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
+var
+ Stream: TAudioPlaybackStream;
+ i: Integer;
+ Filename: String;
+begin
+ //Search for Sound in already loaded Sounds
+ Filename := UpperCase(SoundPath + Name);
+ for i := 0 to High(CustomSounds) do
+ begin
+ if (UpperCase(CustomSounds[i].Filename) = Filename) then
+ begin
+ Result := i;
+ Exit;
+ end;
+ end;
+
+ Stream := AudioPlayback.OpenSound(SoundPath + String(Name));
+ if (Stream = nil) then
+ begin
+ Result := 0;
+ Exit;
+ end;
+
+ SetLength(CustomSounds, Length(CustomSounds)+1);
+ CustomSounds[High(CustomSounds)].Stream := Stream;
+ Result := High(CustomSounds);
+end;
+
+procedure PlaySound(const Index: Cardinal); stdcall; //Plays a Custom Sound
+begin
+ if (Index <= High(CustomSounds)) then
+ AudioPlayback.PlaySound(CustomSounds[Index].Stream);
+end;
+
+end.
+
diff --git a/src/Screens/UScreenSong.pas b/src/Screens/UScreenSong.pas
new file mode 100644
index 00000000..be1320f2
--- /dev/null
+++ b/src/Screens/UScreenSong.pas
@@ -0,0 +1,2019 @@
+unit UScreenSong;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ UMenu,
+ SDL,
+ UMusic,
+ UFiles,
+ UTime,
+ UDisplay,
+ USongs,
+ SysUtils,
+ UCommon,
+ ULog,
+ UThemes,
+ UTexture,
+ ULanguage,
+ USong,
+ UIni;
+
+type
+ TScreenSong = class(TMenu)
+ private
+ EqualizerData: TFFTData; // moved here to avoid stack overflows
+ EqualizerBands: array of Byte;
+ EqualizerTime: Cardinal;
+
+ procedure StartMusicPreview();
+ procedure StopMusicPreview();
+ public
+ TextArtist: integer;
+ TextTitle: integer;
+ TextNumber: integer;
+
+ //Video Icon Mod
+ VideoIcon: Cardinal;
+
+ TextCat: integer;
+ StaticCat: integer;
+
+ SongCurrent: real;
+ SongTarget: real;
+
+ HighSpeed: boolean;
+ CoverFull: boolean;
+ CoverTime: real;
+ MusicPreviewTimer: PSDL_TimerID;
+
+ CoverX: integer;
+ CoverY: integer;
+ CoverW: integer;
+ is_jump: boolean; // Jump to Song Mod
+ is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
+
+ //Party Mod
+ Mode: TSingMode;
+
+ //party Statics (Joker)
+ StaticTeam1Joker1: Cardinal;
+ StaticTeam1Joker2: Cardinal;
+ StaticTeam1Joker3: Cardinal;
+ StaticTeam1Joker4: Cardinal;
+ StaticTeam1Joker5: Cardinal;
+
+ StaticTeam2Joker1: Cardinal;
+ StaticTeam2Joker2: Cardinal;
+ StaticTeam2Joker3: Cardinal;
+ StaticTeam2Joker4: Cardinal;
+ StaticTeam2Joker5: Cardinal;
+
+ StaticTeam3Joker1: Cardinal;
+ StaticTeam3Joker2: Cardinal;
+ StaticTeam3Joker3: Cardinal;
+ StaticTeam3Joker4: Cardinal;
+ StaticTeam3Joker5: Cardinal;
+
+ StaticParty: array of Cardinal;
+ TextParty: array of Cardinal;
+ StaticNonParty: array of Cardinal;
+ TextNonParty: array of Cardinal;
+
+
+ constructor Create; override;
+ procedure SetScroll;
+ //procedure SetScroll1;
+ //procedure SetScroll2;
+ procedure SetScroll3;
+ procedure SetScroll4;
+ procedure SetScroll5;
+ procedure SetScroll6;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure GenerateThumbnails();
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure SelectNext;
+ procedure SelectPrev;
+ //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ procedure SkipTo(Target: Cardinal);
+ procedure FixSelected; //Show Wrong Song when Tabs on Fix
+ procedure FixSelected2; //Show Wrong Song when Tabs on Fix
+ procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
+ procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+ procedure HideCatTL;// Show Cat in Tob left
+ procedure Refresh; //Refresh Song Sorting
+ procedure DrawEqualizer;
+ procedure ChangeMusic;
+ //Party Mode
+ procedure SelectRandomSong;
+ procedure SetJoker;
+ procedure SetStatics;
+ //procedures for Menu
+ procedure StartSong;
+ procedure OpenEditor;
+ procedure DoJoker(Team: Byte);
+ procedure SelectPlayers;
+
+ procedure UnloadDetailedCover;
+
+ //Extensions
+ procedure DrawExtensions;
+ end;
+
+implementation
+
+uses
+ UGraphic,
+ UMain,
+ UCovers,
+ math,
+ gl,
+ USkins,
+ UDLLManager,
+ UParty,
+ UPlaylist,
+ UMenuButton,
+ UScreenSongMenu;
+
+// ***** Public methods ****** //
+
+//Show Wrong Song when Tabs on Fix
+procedure TScreenSong.FixSelected;
+var I, I2: Integer;
+begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongCurrent := I2;
+ SongTarget := I2;
+ end;
+end;
+
+procedure TScreenSong.FixSelected2;
+var I, I2: Integer;
+begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongTarget := I2;
+ end;
+end;
+//Show Wrong Song when Tabs on Fix End
+
+procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+begin
+ Text[TextCat].Text := Caption;
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := False;
+end;
+
+//Show Cat in Top Left Mod
+procedure TScreenSong.ShowCatTL(Cat: Integer);
+begin
+ //Change
+ Text[TextCat].Text := CatSongs.Song[Cat].Artist;
+ Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
+
+ //Show
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := True;
+end;
+
+procedure TScreenSong.HideCatTL;
+begin
+ //Hide
+ //Text[TextCat].Visible := false;
+ Static[StaticCat].Visible := false;
+ //New -> Show Text specified in Theme
+ Text[TextCat].Visible := True;
+ Text[TextCat].Text := Theme.Song.TextCat.Text;
+end;
+//Show Cat in Top Left Mod End
+
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSong.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+ I2: integer;
+ SDL_ModState: Word;
+ Letter: WideChar;
+begin
+ Result := true;
+
+ //Song Screen Extensions (Jumpto + Menu)
+ if (ScreenSongMenu.Visible) then
+ begin
+ Result := ScreenSongMenu.ParseInput(PressedKey, CharCode, PressedDown);
+ Exit;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ Result := ScreenSongJumpto.ParseInput(PressedKey, CharCode, PressedDown);
+ Exit;
+ end;
+
+ if (PressedDown) then
+ begin // Key Down
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ //Jump to Artist/Titel
+ if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then
+ begin
+ if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z')]) ) then
+ begin
+ Letter := WideCharUpperCase(CharCode)[1];
+ I2 := Length(CatSongs.Song);
+
+ //Jump To Titel
+ if (SDL_ModState = (KMOD_LALT or KMOD_LSHIFT)) then
+ begin
+ for I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and
+ (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end
+ //Jump to Artist
+ else if (SDL_ModState = KMOD_LALT) then
+ begin
+ for I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and
+ (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end;
+ end;
+
+ Exit;
+ end;
+
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+
+ 'M': //Show SongMenu
+ begin
+ if (Songs.SongList.Count > 0) then
+ begin
+ if (Mode = smNormal) then
+ begin
+ if (not CatSongs.Song[Interaction].Main) then // clicked on Song
+ begin
+ if CatSongs.CatNumShow = -3 then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end
+ else
+ begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ end //Party Mode -> Show Party Menu
+ else
+ begin
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+ Exit;
+ end;
+
+ 'P': //Show Playlist Menu
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ Exit;
+ end;
+
+ 'J': //Show Jumpto Menu
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ ScreenSongJumpto.Visible := True;
+ end;
+ Exit;
+ end;
+
+ 'E':
+ begin
+ OpenEditor;
+ Exit;
+ end;
+
+ 'R':
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ if (SDL_ModState = KMOD_LSHIFT) and (Ini.Tabs_at_startup = 1) then //Random Category
+ begin
+ I2 := 0; //Count Cats
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Inc(I2);
+ end;
+
+ I2 := Random (I2)+1; //Zufall
+
+ //Find Cat:
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Dec(I2);
+ if (I2<=0) then
+ begin
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ Interaction := I;
+
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+ break;
+ end;
+ end;
+ end
+ else if (SDL_ModState = KMOD_LCTRL) and (Ini.Tabs_at_startup = 1) then //random in All Categorys
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+
+ //In I is now the categorie in I2 the song
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Fix: Not Existing Song selected:
+ //if (I+1=I2) then Inc(I2);
+
+ //Choose Song
+ SkipTo(I2-I);
+ end
+ else //Random in one Category
+ begin
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ end;
+ Exit;
+ end;
+ end; // normal keys
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ if (Mode = smNormal) then
+ begin
+ //On Escape goto Cat-List Hack
+ if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow <> -1) then
+ begin
+ //Find Category
+ I := Interaction;
+ while not catsongs.Song[I].Main do
+ begin
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ break;
+ end;
+ if (I<= 1) then
+ Interaction := high(catsongs.Song)
+ else
+ Interaction := I - 1;
+
+ //Stop Music
+ StopMusicPreview();
+
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+ //SelectPrev;
+ //CatSongs.Song[0].Visible := False;
+ end
+ else
+ begin
+ //On Escape goto Cat-List Hack End
+ //Tabs off and in Search or Playlist -> Go back to Song view
+ if (CatSongs.CatNumShow < -1) then
+ begin
+ //Atm: Set Empty Filter
+ CatSongs.SetFilter('', 0);
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ Interaction := 0;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ ChangeMusic;
+ end
+ else
+ begin
+ StopMusicPreview();
+ AudioPlayback.PlaySound(SoundLib.Back);
+
+ FadeTo(@ScreenMain);
+ end;
+
+ end;
+ end
+ //When in party Mode then Ask before Close
+ else if (Mode = smPartyMode) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
+ end;
+ end;
+ SDLK_RETURN:
+ begin
+ if Songs.SongList.Count > 0 then
+ begin
+ {$IFDEF UseSerialPort}
+ // PortWriteB($378, 0);
+ {$ENDIF}
+ if CatSongs.Song[Interaction].Main then
+ begin // clicked on Category Button
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ //I := CatSongs.VisibleIndex(Interaction);
+ CatSongs.ClickCategoryButton(Interaction);
+ {I2 := CatSongs.VisibleIndex(Interaction);
+ SongCurrent := SongCurrent - I + I2;
+ SongTarget := SongTarget - I + I2; }
+
+ // SetScroll4;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ ChangeMusic;
+ end
+ else
+ begin // clicked on song
+ if (Mode = smNormal) then //Normal Mode -> Start Song
+ begin
+ //Do the Action that is specified in Ini
+ case Ini.OnSongClick of
+ 0: StartSong;
+ 1: SelectPlayers;
+ 2:begin
+ if (CatSongs.CatNumShow = -3) then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end;
+ end;
+ end
+ else if (Mode = smPartyMode) then //PartyMode -> Show Menu
+ begin
+ if (Ini.PartyPopup = 1) then
+ ScreenSongMenu.MenuShow(SM_Party_Main)
+ else
+ ScreenSong.StartSong;
+ end;
+ end;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ if (Mode = smNormal) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main do
+ begin
+ Inc (I);
+ if (I > high(catsongs.Song)) then
+ I := low(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ CatSongs.ClickCategoryButton(Interaction);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+
+ end;
+
+ //
+ //Cat Change Hack End}
+ end;
+ end;
+ end;
+ SDLK_UP:
+ begin
+ if (Mode = smNormal) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ I2 := 0;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main or (I2 = 0) do
+ begin
+ if catsongs.Song[I].Main then
+ Inc(I2);
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ I := high(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+ end;
+ end;
+ //Cat Change Hack End}
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Change);
+ SelectNext;
+ //InteractNext;
+ //SongTarget := Interaction;
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Light.LightOne(1, 200); //TODO: maybe Light Support as Plugin?
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ if (Songs.SongList.Count > 0)and (Mode = smNormal) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Change);
+ SelectPrev;
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Light.LightOne(0, 200); //TODO: maybe Light Support as Plugin?
+ end;
+ end;
+
+ SDLK_1:
+ begin //Joker // to-do : Party
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 1) and (PartySession.Teams.Teaminfo[0].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[0].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+
+ SDLK_2:
+ begin //Joker
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 2) and (PartySession.Teams.Teaminfo[1].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[1].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+
+ SDLK_3:
+ begin //Joker
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 3) and (PartySession.Teams.Teaminfo[2].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[2].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenSong.Create;
+var
+ i: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Song);
+
+ TextArtist := AddText(Theme.Song.TextArtist);
+ TextTitle := AddText(Theme.Song.TextTitle);
+ TextNumber := AddText(Theme.Song.TextNumber);
+
+ //Show Cat in Top Left mod
+ TextCat := AddText(Theme.Song.TextCat);
+ StaticCat := AddStatic(Theme.Song.StaticCat);
+
+ //Show Video Icon Mod
+ VideoIcon := AddStatic(Theme.Song.VideoIcon);
+
+ //Party Mode
+ StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
+ StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
+ StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
+ StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
+ StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
+
+ StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
+ StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
+ StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
+ StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
+ StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
+
+ StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
+ StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
+ StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
+ StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
+ StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
+
+ //Load Party or NonParty specific Statics and Texts
+ SetLength(StaticParty, Length(Theme.Song.StaticParty));
+ for i := 0 to High(Theme.Song.StaticParty) do
+ StaticParty[i] := AddStatic(Theme.Song.StaticParty[i]);
+
+ SetLength(TextParty, Length(Theme.Song.TextParty));
+ for i := 0 to High(Theme.Song.TextParty) do
+ TextParty[i] := AddText(Theme.Song.TextParty[i]);
+
+ SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
+ for i := 0 to High(Theme.Song.StaticNonParty) do
+ StaticNonParty[i] := AddStatic(Theme.Song.StaticNonParty[i]);
+
+ SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
+ for i := 0 to High(Theme.Song.TextNonParty) do
+ TextNonParty[i] := AddText(Theme.Song.TextNonParty[i]);
+
+ // Song List
+ //Songs.LoadSongList; // moved to the UltraStar unit
+ CatSongs.Refresh;
+
+ GenerateThumbnails();
+
+
+ // Randomize Patch
+ Randomize;
+ //Equalizer
+ SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
+ //ClearArray
+ For I := low(EqualizerBands) to high(EqualizerBands) do
+ EqualizerBands[I] := 3;
+
+ if (Length(CatSongs.Song) > 0) then
+ Interaction := 0;
+end;
+
+procedure TScreenSong.GenerateThumbnails();
+var
+ I: Integer;
+ CoverButtonIndex: integer;
+ CoverButton: TButton;
+ CoverName: string;
+ CoverTexture: TTexture;
+ Cover: TCover;
+ Song: TSong;
+begin
+ if (Length(CatSongs.Song) <= 0) then
+ Exit;
+
+ // set length of button array once instead for every song
+ SetButtonLength(Length(CatSongs.Song));
+
+ // create all buttons
+ for I := 0 to High(CatSongs.Song) do
+ begin
+ CoverButton := nil;
+
+ // create a clickable cover
+ CoverButtonIndex := AddButton(300 + I*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
+ if (CoverButtonIndex > -1) then
+ CoverButton := Button[CoverButtonIndex];
+ if (CoverButton = nil) then
+ Continue;
+
+ Song := CatSongs.Song[I];
+
+ // if cover-image is not found then show 'no cover'
+ if (not FileExists(Song.Path + Song.Cover)) then
+ Song.Cover := '';
+
+ if (Song.Cover = '') then
+ CoverName := Skin.GetTextureFileName('SongCover')
+ else
+ CoverName := Song.Path + Song.Cover;
+
+ // load cover and cache its texture
+ Cover := Covers.FindCover(CoverName);
+ if (Cover = nil) then
+ Cover := Covers.AddCover(CoverName);
+
+ // use the cached texture
+ // TODO: this is a workaround until the new song-loading works.
+ // The TCover object should be added to the song-object. The thumbnails
+ // should be loaded each time the song-screen is shown (it is real fast).
+ // This way, we will not waste that much memory and have a link between
+ // song and cover.
+ if (Cover <> nil) then
+ begin
+ CoverTexture := Cover.GetPreviewTexture();
+ Texture.AddTexture(CoverTexture, TEXTURE_TYPE_PLAIN, true);
+ CoverButton.Texture := CoverTexture;
+ end;
+
+ Cover.Free;
+ end;
+end;
+
+procedure TScreenSong.SetScroll;
+var
+ VS, B: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+ if VS > 0 then
+ begin
+ // Set Positions
+ case Theme.Song.Cover.Style of
+ 3: SetScroll3;
+ 5:begin
+ if VS > 5 then
+ SetScroll5
+ else
+ SetScroll4;
+ end;
+ 6: SetScroll6;
+ else SetScroll4;
+ end;
+
+ // Set visibility of video icon
+ Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
+
+ // Set texts
+ Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
+ Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
+ if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
+ begin
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
+ Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
+ end
+ else if (CatSongs.CatNumShow = -2) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (CatSongs.CatNumShow = -3) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (Ini.Tabs_at_startup = 1) then
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
+ else
+ Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
+ end
+ else
+ begin
+ Text[TextNumber].Text := '0/0';
+ Text[TextArtist].Text := '';
+ Text[TextTitle].Text := '';
+ for B := 0 to High(Button) do
+ Button[B].Visible := False;
+
+ end;
+end;
+
+(*
+procedure TScreenSong.SetScroll1;
+var
+ B: integer; // button
+ //BMin: integer; // button min // Auto Removed, Unused Variable
+ //BMax: integer; // button max // Auto Removed, Unused Variable
+ Src: integer;
+ //Dst: integer;
+ Count: integer; // Dst is not used. Count is used.
+ Ready: boolean;
+
+ VisCount: integer; // count of visible (or selectable) buttons
+ VisInt: integer; // visible position of interacted button
+ Typ: integer; // 0 when all songs fits the screen
+ Placed: integer; // number of placed visible buttons
+begin
+ //Src := 0;
+ //Dst := -1;
+ Count := 1;
+ Typ := 0;
+ Ready := false;
+ Placed := 0;
+
+ VisCount := 0;
+ for B := 0 to High(Button) do
+ if CatSongs.Song[B].Visible then Inc(VisCount);
+
+ VisInt := 0;
+ for B := 0 to Interaction-1 do
+ if CatSongs.Song[B].Visible then Inc(VisInt);
+
+
+ if VisCount <= 6 then begin
+ Typ := 0;
+ end else begin
+ if VisInt <= 3 then begin
+ Typ := 1;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if (VisCount - VisInt) <= 3 then begin
+ Typ := 2;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if not Ready then begin
+ Typ := 3;
+ Src := Interaction;
+ end;
+ end;
+
+
+
+ // hide all buttons
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := false;
+ Button[B].Selectable := CatSongs.Song[B].Visible;
+ end;
+
+ {
+ for B := Src to Dst do begin
+ //Button[B].Visible := true;
+ Button[B].Visible := CatSongs.Song[B].Visible;
+ Button[B].Selectable := Button[B].Visible;
+ Button[B].Y := 140 + (B-Src) * 60;
+ end;
+ }
+
+
+ if Typ = 0 then begin
+ for B := 0 to High(Button) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ end;
+ end;
+ end;
+
+ if Typ = 1 then begin
+ B := 0;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+ end;
+
+ if Typ = 2 then begin
+ B := High(Button);
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (6-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+ end;
+
+ if Typ = 3 then begin
+ B := Src;
+ Count := 4;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (3+Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+
+ B := Src-1;
+ Placed := 0;
+ Count := 3;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (2-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+
+ end;
+
+ if Length(Button) > 0 then
+ Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
+end;
+
+procedure TScreenSong.SetScroll2;
+var
+ B: integer;
+ //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ //Wsp2: real;
+begin
+ // liniowe
+ for B := 0 to High(Button) do
+ Button[B].X := 300 + (B - Interaction) * 260;
+
+ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;
+
+ // kolowe
+ {
+ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+ //Button[B].Y := 140 + 50 * ;
+ end;
+ }
+end;
+*)
+
+procedure TScreenSong.SetScroll3; // with slide
+var
+ B: integer;
+ //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ //Wsp2: real;
+begin
+ SongTarget := Interaction;
+
+ // liniowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].X := 300 + (B - SongCurrent) * 260;
+ if (Button[B].X < -Button[B].W) or (Button[B].X > 800) then
+ Button[B].Visible := False
+ else
+ Button[B].Visible := True;
+ end;
+
+ {
+ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;
+ }
+
+ // kolowe
+ {
+ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+ //Button[B].Y := 140 + 50 * ;
+ end;
+ }
+end;
+
+(**
+ * Rotation
+ *)
+procedure TScreenSong.SetScroll4;
+var
+ B: integer;
+ Angle: real;
+ Z, Z2: real;
+ VS: integer;
+begin
+ VS := CatSongs.VisibleSongs();
+
+ for B := 0 to High(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible;
+ if Button[B].Visible then
+ begin
+ // angle between the cover and selected song-cover in radians
+ Angle := 2*Pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS;
+
+ // calc z-position from angle
+ Z := (1 + cos(Angle)) / 2; // scaled to range [0..1]
+ Z2 := (1 + 2*Z) / 3; // scaled to range [1/3..1]
+
+ // adjust cover's width and height according its z-position
+ // Note: Theme.Song.Cover.W is not used as width and height are equal
+ // and Theme.Song.Cover.W is used as circle radius in Scroll5.
+ Button[B].W := Theme.Song.Cover.H * Z2;
+ Button[B].H := Button[B].W;
+
+ // set cover position
+ Button[B].X := Theme.Song.Cover.X +
+ (0.185 * Theme.Song.Cover.H * VS * sin(Angle)) * Z2 -
+ ((Button[B].H - Theme.Song.Cover.H)/2);
+ Button[B].Y := Theme.Song.Cover.Y +
+ (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7;
+ Button[B].Z := Z / 2 + 0.3;
+ end;
+ end;
+end;
+
+(**
+ * rotate
+ *)
+procedure TScreenSong.SetScroll5;
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ Padding: real;
+ X: Real;
+ {
+ Theme.Song.CoverW: circle radius
+ Theme.Song.CoverX: x-pos. of the left edge of the selected cover
+ Theme.Song.CoverY: y-pos. of the upper edge of the selected cover
+ Theme.Song.CoverH: cover height
+ }
+begin
+ VS := CatSongs.VisibleSongs();
+
+ // Update positions of all buttons
+ for B := 0 to High(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // adjust visibility
+ if Button[B].Visible then // Only change pos for visible buttons
+ begin
+ // Pos is the distance to the centered cover in the range [-VS/2..+VS/2]
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ // Avoid overlapping of the front covers.
+ // Use an alternate position for the five front covers.
+ if (Abs(Pos) < 2.5) then
+ begin
+ Angle := Pi * (Pos / 5); // Range: (-1/4*Pi .. +1/4*Pi)
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));
+ Button[B].W := Button[B].H;
+
+ //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Padding := (Button[B].H - Theme.Song.Cover.H)/2;
+ X := Sin(Angle*1.3) * 0.9;
+
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Padding;
+ Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+ end
+ else
+ begin
+ // Transform Pos to range [-1..-1/2, +1/2..+1]
+ if Pos < 0 then
+ Pos := Pos/VS - 0.5
+ else
+ Pos := Pos/VS + 0.5;
+
+ // angle in radians [-2Pi..-Pi, +Pi..+2Pi]
+ Angle := 2*Pi * Pos;
+
+ Button[B].H := 0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));
+ Button[B].W := Button[B].H;
+
+ Padding := (Button[B].H - Theme.Song.Cover.H)/2;
+
+ Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
+ Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ diff: real;
+ X: Real;
+ Wsp: real;
+ Z, Z2: real;
+begin
+ VS := CatSongs.VisibleSongs;
+ if VS <= 5 then
+ begin
+ // kolowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2;
+ Z2 := (1 + 2*Z) / 3;
+
+
+ Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z / 2 + 0.3;
+
+ Button[B].W := Theme.Song.Cover.H * Z2;
+
+ //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
+ Button[B].H := Button[B].W;
+ end;
+ end;
+ end
+ else
+ begin
+ //Change Pos of all Buttons
+ for B := low(Button) to high(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 2.5) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+ //Button[B].Visible := False;
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+
+ X := Sin(Angle*1.3)*0.9;
+
+ Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
+ end
+ else
+ begin {Behind the Front Covers}
+
+ // limit-bg-covers hack
+ if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
+ if VS > 25 then VS:=25;
+ // end of limit-bg-covers hack
+
+ if Pos < 0 then
+ Pos := (Pos - VS/2)/VS
+ else
+ Pos := (Pos + VS/2)/VS;
+
+ Angle := Pi * Pos*2;
+
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
+
+ Button[B].W := Button[B].H;
+
+ Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
+
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+procedure TScreenSong.onShow;
+begin
+ inherited;
+{**
+ * Pause background music, so we can play it again on scorescreen
+ *}
+ SoundLib.PauseBgMusic;
+
+ AudioPlayback.Stop;
+
+ if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
+ if Ini.Players = 4 then PlayersPlay := 6;
+
+ //Cat Mod etc
+ if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
+ begin
+ CatSongs.ShowCategoryList;
+ FixSelected;
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ end;
+
+ if Length(CatSongs.Song) > 0 then
+ begin
+ //Load Music only when Song Preview is activated
+ if ( Ini.PreviewVolume <> 0 ) then
+ StartMusicPreview();
+
+ SetScroll;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ end;
+
+ //Playlist Mode
+ if (Mode = smNormal) then
+ begin
+ //If Playlist Shown -> Select Next automatically
+ if (CatSongs.CatNumShow = -3) then
+ begin
+ SelectNext;
+ ChangeMusic;
+ end;
+ end
+ //Party Mode
+ else if (Mode = smPartyMode) then
+ begin
+ SelectRandomSong;
+ //Show Menu directly in PartyMode
+ //But only if selected in Options
+ if (Ini.PartyPopup = 1) then
+ begin
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+
+ SetJoker;
+ SetStatics;
+end;
+
+procedure TScreenSong.onHide;
+begin
+ // turn music volume to 100%
+ AudioPlayback.SetVolume(1.0);
+
+ // if preview is deactivated: load musicfile now
+ If (IPreviewVolumeVals[Ini.PreviewVolume] = 0) then
+ AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
+
+ // if hide then stop music (for party mode popup on exit)
+ if (Display.NextScreen <> @ScreenSing) and
+ (Display.NextScreen <> @ScreenSingModi) then
+ begin
+ StopMusicPreview();
+ end;
+end;
+
+procedure TScreenSong.DrawExtensions;
+begin
+ //Draw Song Menu
+ if (ScreenSongMenu.Visible) then
+ begin
+ ScreenSongMenu.Draw;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ ScreenSongJumpto.Draw;
+ end
+end;
+
+function TScreenSong.Draw: boolean;
+var
+ dx: real;
+ dt: real;
+ I: Integer;
+begin
+ dx := SongTarget-SongCurrent;
+ dt := TimeSkip * 7;
+
+ if dt > 1 then
+ dt := 1;
+
+ SongCurrent := SongCurrent + dx*dt;
+
+ {
+ if SongCurrent > Catsongs.VisibleSongs then begin
+ SongCurrent := SongCurrent - Catsongs.VisibleSongs;
+ SongTarget := SongTarget - Catsongs.VisibleSongs;
+ end;
+ }
+
+ //Log.BenchmarkStart(5);
+
+ SetScroll;
+
+ //Log.BenchmarkEnd(5);
+ //Log.LogBenchmark('SetScroll4', 5);
+
+ //Fading Functions, Only if Covertime is under 5 Seconds
+ if (CoverTime < 5) then
+ begin
+ // cover fade
+ if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then
+ begin
+ // load new texture
+ Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+ Button[Interaction].Texture.Alpha := 1;
+ Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+ Button[Interaction].Texture2.Alpha := 1;
+ end;
+
+ //Update Fading Time
+ CoverTime := CoverTime + TimeSkip;
+
+ //Update Fading Texture
+ Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
+ if Button[Interaction].Texture2.Alpha > 1 then
+ Button[Interaction].Texture2.Alpha := 1;
+
+ end;
+
+ //inherited Draw;
+ //heres a little Hack, that causes the Statics
+ //are Drawn after the Buttons because of some Blending Problems.
+ //This should cause no Problems because all Buttons on this screen
+ //Has Z Position.
+ //Draw BG
+ DrawBG;
+
+ //Instead of Draw FG Procedure:
+ //We draw Buttons for our own
+ for I := 0 to Length(Button) - 1 do
+ Button[I].Draw;
+
+ // Statics
+ for I := 0 to Length(Static) - 1 do
+ Static[I].Draw;
+
+ // and texts
+ for I := 0 to Length(Text) - 1 do
+ Text[I].Draw;
+
+
+ //Draw Equalizer
+ if Theme.Song.Equalizer.Visible then
+ DrawEqualizer;
+
+ DrawExtensions;
+
+ Result := true;
+end;
+
+procedure TScreenSong.SelectNext;
+var
+ Skip: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ // this 1 could be changed by CatSongs.FindNextVisible
+ while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do
+ Inc(Skip);
+
+ SongTarget := SongTarget + 1;//Skip;
+
+ Interaction := (Interaction + Skip) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget > VS-1 then begin
+ SongTarget := SongTarget - VS;
+ SongCurrent := SongCurrent - VS;
+ end;
+
+ end;
+
+ // Interaction -> Button, ktorego okladke przeczytamy
+ // show uncached texture
+ //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+end;
+
+procedure TScreenSong.SelectPrev;
+var
+ Skip: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
+ SongTarget := SongTarget - 1;//Skip;
+
+ Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget < 0 then begin
+ SongTarget := SongTarget + CatSongs.VisibleSongs;
+ SongCurrent := SongCurrent + CatSongs.VisibleSongs;
+ end;
+
+ // show uncached texture
+ //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+ end;
+end;
+
+(*
+procedure TScreenSong.UpdateLCD; //TODO: maybe LCD Support as Plugin?
+begin
+ LCD.HideCursor;
+ LCD.Clear;
+ LCD.WriteText(1, Text[TextArtist].Text);
+ LCD.WriteText(2, Text[TextTitle].Text);
+
+end;
+*)
+
+procedure TScreenSong.StartMusicPreview();
+var
+ Song: TSong;
+begin
+ AudioPlayback.Close();
+
+ Song := CatSongs.Song[Interaction];
+ if not assigned(Song) then
+ Exit;
+
+ if AudioPlayback.Open(Song.Path + Song.Mp3) then
+ begin
+ AudioPlayback.Position := AudioPlayback.Length / 4;
+ // set preview volume
+ if (Ini.PreviewFading = 0) then
+ begin
+ // music fade disabled: start with full volume
+ AudioPlayback.SetVolume(IPreviewVolumeVals[Ini.PreviewVolume]);
+ AudioPlayback.Play()
+ end
+ else
+ begin
+ // music fade enabled: start muted and fade-in
+ AudioPlayback.SetVolume(0);
+ AudioPlayback.FadeIn(Ini.PreviewFading, IPreviewVolumeVals[Ini.PreviewVolume]);
+ end;
+ end;
+end;
+
+procedure TScreenSong.StopMusicPreview();
+begin
+ // Cancel pending preview requests
+ SDL_RemoveTimer(MusicPreviewTimer);
+
+ // Stop preview of previous song
+ AudioPlayback.Stop;
+end;
+
+function MusicPreviewTimerCallback(interval: UInt32; param: Pointer): UInt32; cdecl;
+var
+ ScreenSong: TScreenSong;
+begin
+ ScreenSong := TScreenSong(param);
+ if (ScreenSong <> nil) then
+ ScreenSong.StartMusicPreview();
+ Result := 0;
+end;
+
+// Changes previewed song
+procedure TScreenSong.ChangeMusic;
+begin
+ StopMusicPreview();
+
+ // Preview song if activated and current selection is not a category cover
+ if (CatSongs.VisibleSongs > 0) and
+ (not CatSongs.Song[Interaction].Main) and
+ (Ini.PreviewVolume <> 0) then
+ begin
+ // Delay song fading to prevent the song from being played while scrolling
+ MusicPreviewTimer := SDL_AddTimer(200, MusicPreviewTimerCallback, Self);
+ end;
+end;
+
+procedure TScreenSong.SkipTo(Target: Cardinal);
+var
+ i: integer;
+begin
+ UnLoadDetailedCover;
+
+ Interaction := High(CatSongs.Song);
+ SongTarget := 0;
+
+ for i := 1 to Target+1 do
+ SelectNext;
+
+ FixSelected2;
+end;
+
+procedure TScreenSong.DrawEqualizer;
+var
+ I, J: Integer;
+ ChansPerBand: byte; // channels per band
+ MaxChannel: Integer;
+ CurBand: Integer; // current band
+ CurTime: Cardinal;
+ PosX, PosY: Integer;
+ Pos: Real;
+begin
+ // Nothing to do if no music is played or an equalizer bar consists of no block
+ if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then
+ Exit;
+
+ CurTime := SDL_GetTicks();
+
+ // Evaluate FFT-data every 44 ms
+ if (CurTime >= EqualizerTime) then
+ begin
+ EqualizerTime := CurTime + 44;
+ AudioPlayback.GetFFTData(EqualizerData);
+
+ Pos := 0;
+ // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz
+ ChansPerBand := ceil(92 / Theme.Song.Equalizer.Bands); // How much channels are used for one Band
+ MaxChannel := ChansPerBand * Theme.Song.Equalizer.Bands - 1;
+
+ // Change Lengths
+ for i := 0 to MaxChannel do
+ begin
+ // Gain higher freq. data so that the bars are visible
+ if i > 35 then
+ EqualizerData[i] := EqualizerData[i] * 8
+ else if i > 11 then
+ EqualizerData[i] := EqualizerData[i] * 4.5
+ else
+ EqualizerData[i] := EqualizerData[i] * 1.1;
+
+ // clamp data
+ if (EqualizerData[i] > 1) then
+ EqualizerData[i] := 1;
+
+ // Get max. pos
+ if (EqualizerData[i] * Theme.Song.Equalizer.Length > Pos) then
+ Pos := EqualizerData[i] * Theme.Song.Equalizer.Length;
+
+ // Check if this is the last channel in the band
+ if ((i+1) mod ChansPerBand = 0) then
+ begin
+ CurBand := i div ChansPerBand;
+
+ // Smooth delay if new equalizer is lower than the old one
+ if ((EqualizerBands[CurBand] > Pos) and (EqualizerBands[CurBand] > 1)) then
+ EqualizerBands[CurBand] := EqualizerBands[CurBand] - 1
+ else
+ EqualizerBands[CurBand] := Round(Pos);
+
+ Pos := 0;
+ end;
+ end;
+
+ end;
+
+ // Draw equalizer bands
+
+ // Setup OpenGL
+ glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ // Set position of the first equalizer bar
+ PosY := Theme.Song.Equalizer.Y;
+ PosX := Theme.Song.Equalizer.X;
+
+ // Draw bars for each band
+ for I := 0 to High(EqualizerBands) do
+ begin
+ // Reset to lower or left position depending on the drawing-direction
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ // FIXME: Is Theme.Song.Equalizer.Y the upper or lower coordinate?
+ PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
+ else // Horizontal bars
+ PosX := Theme.Song.Equalizer.X;
+
+ // Draw the bar as a stack of blocks
+ for J := 1 to EqualizerBands[I] do
+ begin
+ // Draw block
+ glBegin(GL_QUADS);
+ glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
+ glEnd;
+
+ // Calc position of the bar's next block
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
+ else // Horizontal bars
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
+ end;
+
+ // Calc position of the next bar
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
+ else // Horizontal bars
+ PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
+ end;
+end;
+
+procedure TScreenSong.SelectRandomSong;
+var
+ I, I2: Integer;
+begin
+ case PlaylistMan.Mode of
+ smNormal: //All Songs Just Select Random Song
+ begin
+ //When Tabs are activated then use Tab Method
+ if (Ini.Tabs_at_startup = 1) then
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+ //In I ist jetzt die Kategorie in I2 der Song
+ //I is the CatNum, I2 is the No of the Song within this Cat
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Choose Song
+ SkipTo(I2-I);
+ end
+ //When Tabs are deactivated use easy Method
+ else
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ smPartyMode: //One Category Select Category and Select Random Song
+ begin
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
+ ShowCatTL(PlaylistMan.CurPlayList);
+
+ SelectNext;
+ FixSelected2;
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ smPlaylistRandom: //Playlist: Select Playlist and Select Random Song
+ begin
+ PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ FixSelected2;
+ end;
+ end;
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+ SetScroll;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+end;
+
+procedure TScreenSong.SetJoker;
+begin
+ // If Party Mode
+ // to-do : Party
+ if Mode = smPartyMode then //Show Joker that are available
+ begin
+ (*
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
+ Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
+ Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
+ Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
+ Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
+ Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
+ Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
+ Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
+ Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
+ Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
+ Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
+ Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
+ Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+ *)
+ end
+ else
+ begin //Hide all
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+end;
+
+procedure TScreenSong.SetStatics;
+var
+ I: Integer;
+ Visible: Boolean;
+begin
+ //Set Visibility of Party Statics and Text
+ Visible := (Mode = smPartyMode);
+
+ for I := 0 to high(StaticParty) do
+ Static[StaticParty[I]].Visible := Visible;
+
+ for I := 0 to high(TextParty) do
+ Text[TextParty[I]].Visible := Visible;
+
+ //Set Visibility of Non Party Statics and Text
+ Visible := not Visible;
+
+ for I := 0 to high(StaticNonParty) do
+ Static[StaticNonParty[I]].Visible := Visible;
+
+ for I := 0 to high(TextNonParty) do
+ Text[TextNonParty[I]].Visible := Visible;
+end;
+
+//Procedures for Menu
+
+procedure TScreenSong.StartSong;
+begin
+ CatSongs.Selected := Interaction;
+ StopMusicPreview();
+
+ //Party Mode
+ if (Mode = smPartyMode) then
+ begin
+ FadeTo(@ScreenSingModi);
+ end
+ else
+ begin
+ FadeTo(@ScreenSing);
+ end;
+end;
+
+procedure TScreenSong.SelectPlayers;
+begin
+ CatSongs.Selected := Interaction;
+ StopMusicPreview();
+
+ ScreenName.Goto_SingScreen := True;
+ FadeTo(@ScreenName);
+end;
+
+procedure TScreenSong.OpenEditor;
+begin
+ if (Songs.SongList.Count > 0) and
+ (not CatSongs.Song[Interaction].Main) and
+ (Mode = smNormal) then
+ begin
+ StopMusicPreview();
+ AudioPlayback.PlaySound(SoundLib.Start);
+ CurrentSong := CatSongs.Song[Interaction];
+ FadeTo(@ScreenEditSub);
+ end;
+end;
+
+//Team No of Team (0-5)
+procedure TScreenSong.DoJoker (Team: Byte);
+begin
+ {
+ if (Mode = smPartyMode) and
+ (PartySession.Teams.NumTeams >= Team + 1) and
+ (PartySession.Teams.Teaminfo[Team].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[Team].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+ }
+end;
+
+//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
+procedure TScreenSong.UnloadDetailedCover;
+begin
+ CoverTime := 0;
+
+ // show cached texture
+ Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true);
+ Button[Interaction].Texture2.Alpha := 0;
+
+ if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
+ Texture.UnloadTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+end;
+
+procedure TScreenSong.Refresh;
+begin
+ {
+ CatSongs.Refresh;
+ CatSongs.ShowCategoryList;
+ Interaction := 0;
+ SelectNext;
+ FixSelected;
+ }
+end;
+
+end.
diff --git a/src/Screens/UScreenSongJumpto.pas b/src/Screens/UScreenSongJumpto.pas
new file mode 100644
index 00000000..89d198cc
--- /dev/null
+++ b/src/Screens/UScreenSongJumpto.pas
@@ -0,0 +1,212 @@
+unit UScreenSongJumpto;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenSongJumpto = class(TMenu)
+ private
+ //For ChangeMusic
+ LastPlayed: Integer;
+ VisibleBool: Boolean;
+ public
+ VisSongs: Integer;
+
+ constructor Create; override;
+
+ //Visible //Whether the Menu should be Drawn
+ //Whether the Menu should be Drawn
+ procedure SetVisible(Value: Boolean);
+ property Visible: Boolean read VisibleBool write SetVisible;
+
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+
+ procedure SetTextFound(const Count: Cardinal);
+ end;
+
+var
+ IType: Array [0..2] of String;
+ SelectType: Integer;
+
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, USongs, UScreenSong, ULog;
+
+function TScreenSongJumpto.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case CharCode of
+ '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"',
+ '[', '{', ';', ':':
+ begin
+ if Interaction = 0 then
+ begin
+ Button[0].Text[0].Text := Button[0].Text[0].Text + CharCode;
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ end;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_BACKSPACE:
+ begin
+ if (Interaction = 0) AND (Length(Button[0].Text[0].Text) > 0) then
+ begin
+ Button[0].Text[0].DeleteLastL;
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ end;
+ end;
+
+ SDLK_RETURN,
+ SDLK_ESCAPE:
+ begin
+ Visible := False;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ if (VisSongs = 0) AND (Length(Button[0].Text[0].Text) > 0) then
+ begin
+ ScreenSong.UnLoadDetailedCover;
+ Button[0].Text[0].Text := '';
+ CatSongs.SetFilter('', 0);
+ SetTextFound(0);
+ end;
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN:
+ begin
+ {SelectNext;
+ Button[0].Text[0].Selected := (Interaction = 0);}
+ end;
+
+ SDLK_UP:
+ begin
+ {SelectPrev;
+ Button[0].Text[0].Selected := (Interaction = 0); }
+ end;
+
+ SDLK_RIGHT:
+ begin
+ Interaction := 1;
+ InteractInc;
+ if (Length(Button[0].Text[0].Text) > 0) then
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ Interaction := 0;
+ end;
+ SDLK_LEFT:
+ begin
+ Interaction := 1;
+ InteractDec;
+ if (Length(Button[0].Text[0].Text) > 0) then
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ Interaction := 0;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenSongJumpto.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ AddText(Theme.SongJumpto.TextFound);
+
+ LoadFromTheme(Theme.SongJumpto);
+
+ AddButton(Theme.SongJumpto.ButtonSearchText);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, '');
+
+ SelectType := 0;
+ AddSelectSlide(Theme.SongJumpto.SelectSlideType, SelectType, Theme.SongJumpto.IType);
+
+
+ Interaction := 0;
+ LastPlayed := 0;
+end;
+
+procedure TScreenSongJumpto.SetVisible(Value: Boolean);
+begin
+//If change from unvisible to Visible then OnShow
+ if (VisibleBool = False) AND (Value = True) then
+ OnShow;
+
+ VisibleBool := Value;
+end;
+
+procedure TScreenSongJumpto.onShow;
+begin
+ inherited;
+
+ //Reset Screen if no Old Search is Displayed
+ if (CatSongs.CatNumShow <> -2) then
+ begin
+ SelectsS[0].SetSelectOpt(0);
+
+ Button[0].Text[0].Text := '';
+ Text[0].Text := Theme.SongJumpto.NoSongsFound;
+ end;
+
+ //Select Input
+ Interaction := 0;
+ Button[0].Text[0].Selected := True;
+
+ LastPlayed := ScreenSong.Interaction;
+end;
+
+function TScreenSongJumpto.Draw: boolean;
+begin
+ Result := inherited Draw;
+end;
+
+procedure TScreenSongJumpto.SetTextFound(const Count: Cardinal);
+begin
+ if (Count = 0) then
+ begin
+ Text[0].Text := Theme.SongJumpto.NoSongsFound;
+ if (Length(Button[0].Text[0].Text) = 0) then
+ ScreenSong.HideCatTL
+ else
+ ScreenSong.ShowCatTLCustom(Format(Theme.SongJumpto.CatText, [Button[0].Text[0].Text]));
+ end
+ else
+ begin
+ Text[0].Text := Format(Theme.SongJumpto.SongsFound, [Count]);
+
+ //Set CatTopLeftText
+ ScreenSong.ShowCatTLCustom(Format(Theme.SongJumpto.CatText, [Button[0].Text[0].Text]));
+ end;
+
+
+ //Set visSongs
+ VisSongs := Count;
+
+ //Fix SongSelection
+ ScreenSong.Interaction := high(CatSongs.Song);
+ ScreenSong.SelectNext;
+ ScreenSong.FixSelected;
+
+ //Play Correct Music
+ if (ScreenSong.Interaction <> LastPlayed) then
+ begin
+ LastPlayed := ScreenSong.Interaction;
+
+ ScreenSong.ChangeMusic;
+ end;
+end;
+
+end.
diff --git a/src/Screens/UScreenSongMenu.pas b/src/Screens/UScreenSongMenu.pas
new file mode 100644
index 00000000..74e2c3fc
--- /dev/null
+++ b/src/Screens/UScreenSongMenu.pas
@@ -0,0 +1,641 @@
+unit UScreenSongMenu;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ UDisplay,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes;
+
+type
+ TScreenSongMenu = class(TMenu)
+ private
+ CurMenu: Byte; //Num of the cur. Shown Menu
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+ procedure MenuShow(sMenu: Byte);
+ procedure HandleReturn;
+ end;
+
+const
+ SM_Main = 1;
+
+ SM_PlayList = 64 or 1;
+ SM_Playlist_Add = 64 or 2;
+ SM_Playlist_New = 64 or 3;
+
+ SM_Playlist_DelItem = 64 or 5;
+
+ SM_Playlist_Load = 64 or 8 or 1;
+ SM_Playlist_Del = 64 or 8 or 5;
+
+
+ SM_Party_Main = 128 or 1;
+ SM_Party_Joker = 128 or 2;
+
+var
+ ISelections: Array of String;
+ SelectValue: Integer;
+
+
+implementation
+
+uses UGraphic,
+ UMain,
+ UIni,
+ UTexture,
+ ULanguage,
+ UParty,
+ UPlaylist,
+ USongs;
+
+function TScreenSongMenu.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ if (PressedDown) then
+ begin // Key Down
+ if (CurMenu = SM_Playlist_New) AND (Interaction=0) then
+ begin
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ '0'..'9', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"':
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
+ exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_BACKSPACE:
+ begin
+ Button[Interaction].Text[0].DeleteLastL;
+ exit;
+ end;
+ end;
+ end;
+
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ Visible := False;
+ end;
+
+ SDLK_RETURN:
+ begin
+ HandleReturn;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT:
+ begin
+ if (Interaction=3) then
+ InteractInc;
+ end;
+ SDLK_LEFT:
+ begin
+ if (Interaction=3) then
+ InteractDec;
+ end;
+
+ SDLK_1:
+ begin //Jocker
+ //Use Joker
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(0)
+ end;
+ end;
+ end;
+ SDLK_2:
+ begin //Jocker
+ //Use Joker
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(1)
+ end;
+ end;
+ end;
+ SDLK_3:
+ begin //Jocker
+ //Use Joker
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(2)
+ end;
+ end;
+ end;
+ end; // case
+ end; // if
+end;
+
+constructor TScreenSongMenu.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ //Create Dummy SelectSlide Entrys
+ SetLength(ISelections, 1);
+ ISelections[0] := 'Dummy';
+
+
+ AddText(Theme.SongMenu.TextMenu);
+
+ LoadFromTheme(Theme.SongMenu);
+
+ AddButton(Theme.SongMenu.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddButton(Theme.SongMenu.Button2);
+ if (Length(Button[1].Text) = 0) then
+ AddButtonText(14, 20, 'Button 2');
+
+ AddButton(Theme.SongMenu.Button3);
+ if (Length(Button[2].Text) = 0) then
+ AddButtonText(14, 20, 'Button 3');
+
+ AddSelectSlide(Theme.SongMenu.SelectSlide3, SelectValue, ISelections);
+
+ AddButton(Theme.SongMenu.Button4);
+ if (Length(Button[3].Text) = 0) then
+ AddButtonText(14, 20, 'Button 4');
+
+
+ Interaction := 0;
+end;
+
+function TScreenSongMenu.Draw: boolean;
+begin
+ Result := inherited Draw;
+end;
+
+procedure TScreenSongMenu.onShow;
+begin
+ inherited;
+
+end;
+
+procedure TScreenSongMenu.MenuShow(sMenu: Byte);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+ Case sMenu of
+ SM_Main:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_MAIN');
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
+ end;
+
+ SM_PlayList:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST');
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DEL');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
+ end;
+
+ SM_Playlist_Add:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_ADD');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_NEW');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_EXISTING');
+
+ SetLength(ISelections, Length(PlaylistMan.Playlists));
+ PlaylistMan.GetNames(ISelections);
+
+ if (Length(ISelections)>=1) then
+ begin
+ UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
+ end
+ else
+ begin
+ Button[3].Visible := False;
+ SelectsS[0].Visible := False;
+ Button[2].Visible := True;
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
+ end;
+ end;
+
+ SM_Playlist_New:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_NEW');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_UNNAMED');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_CREATE');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+ SM_Playlist_DelItem:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DELITEM');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+ SM_Playlist_Load:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_LOAD');
+
+ //Show Delete Curent Playlist Button when Playlist is opened
+ Button[0].Visible := (CatSongs.CatNumShow = -3);
+
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DELCURRENT');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_LOAD');
+
+ SetLength(ISelections, Length(PlaylistMan.Playlists));
+ PlaylistMan.GetNames(ISelections);
+
+ if (Length(ISelections)>=1) then
+ begin
+ UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
+ Interaction := 3;
+ end
+ else
+ begin
+ Button[3].Visible := False;
+ SelectsS[0].Visible := False;
+ Button[2].Visible := True;
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
+ Interaction := 2;
+ end;
+ end;
+
+ SM_Playlist_Del:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DEL');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+
+ SM_Party_Main:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_MAIN');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ //Button[1].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
+ //Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYMODI');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
+ end;
+
+ SM_Party_Joker:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_JOKER');
+ // to-do : Party
+ {Button[0].Visible := (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0);
+ Button[1].Visible := (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0);
+ Button[2].Visible := (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0);}
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ {Button[0].Text[0].Text := String(PartySession.Teams.Teaminfo[0].Name);
+ Button[1].Text[0].Text := String(PartySession.Teams.Teaminfo[1].Name);
+ Button[2].Text[0].Text := String(PartySession.Teams.Teaminfo[2].Name);}
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+
+ //Set right Interaction
+ if (not Button[0].Visible) then
+ begin
+ if (not Button[1].Visible) then
+ begin
+ if (not Button[2].Visible) then
+ begin
+ Interaction := 4;
+ end
+ else Interaction := 2;
+ end
+ else Interaction := 1;
+ end;
+
+ end;
+ end;
+end;
+
+procedure TScreenSongMenu.HandleReturn;
+begin
+ Case CurMenu of
+ SM_Main:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 1: //Button 2
+ begin
+ //Select New Players then Sing:
+ ScreenSong.SelectPlayers;
+ Visible := False;
+ end;
+
+ 2: //Button 3
+ begin
+ //Show add to Playlist Menu
+ MenuShow(SM_Playlist_Add);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ ScreenSong.OpenEditor;
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_PlayList:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 1: //Button 2
+ begin
+ //Select New Players then Sing:
+ ScreenSong.SelectPlayers;
+ Visible := False;
+ end;
+
+ 2: //Button 3
+ begin
+ //Show add to Playlist Menu
+ MenuShow(SM_Playlist_DelItem);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ ScreenSong.OpenEditor;
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_Add:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ MenuShow(SM_Playlist_New);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ PlaylistMan.AddItem(ScreenSong.Interaction, SelectValue);
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_New:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Nothing, Button for Entering Name
+ end;
+
+ 2: //Button 3
+ begin
+ //Create Playlist and Add Song
+ PlaylistMan.AddItem(
+ ScreenSong.Interaction,
+ PlaylistMan.AddPlaylist(Button[0].Text[0].Text));
+ Visible := False;
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Cancel -> Go back to Add screen
+ MenuShow(SM_Playlist_Add);
+ end;
+
+ 4: //Button 4
+ begin
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_DelItem:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Delete
+ PlayListMan.DelItem(PlayListMan.GetIndexbySongID(ScreenSong.Interaction));
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ MenuShow(SM_Playlist);
+ end;
+ end;
+ end;
+
+ SM_Playlist_Load:
+ begin
+ Case Interaction of
+ 0: //Button 1 (Delete Playlist)
+ begin
+ MenuShow(SM_Playlist_Del);
+ end;
+ 4: //Button 4
+ begin
+ //Load Playlist
+ PlaylistMan.SetPlayList(SelectValue);
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_Del:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Delete
+ PlayListMan.DelPlaylist(PlaylistMan.CurPlayList);
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ MenuShow(SM_Playlist_Load);
+ end;
+ end;
+ end;
+
+ SM_Party_Main:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Start Singing
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ //Joker
+ MenuShow(SM_Party_Joker);
+ end;
+ end;
+ end;
+
+ SM_Party_Joker:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Joker Team 1
+ ScreenSong.DoJoker(0);
+ end;
+
+ 1: //Button 2
+ begin
+ //Joker Team 2
+ ScreenSong.DoJoker(1);
+ end;
+
+ 2: //Button 3
+ begin
+ //Joker Team 3
+ ScreenSong.DoJoker(2);
+ end;
+
+ 4: //Button 4
+ begin
+ //Cancel... (Fo back to old Menu)
+ MenuShow(SM_Party_Main);
+ end;
+ end;
+ end;
+ end;
+end;
+
+end.
+
diff --git a/src/Screens/UScreenStatDetail.pas b/src/Screens/UScreenStatDetail.pas
new file mode 100644
index 00000000..891b108d
--- /dev/null
+++ b/src/Screens/UScreenStatDetail.pas
@@ -0,0 +1,270 @@
+unit UScreenStatDetail;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UDisplay,
+ UMusic,
+ UIni,
+ UDataBase,
+ UThemes;
+
+type
+ TScreenStatDetail = class(TMenu)
+ public
+ Typ: TStatType;
+ Page: Cardinal;
+ Count: Byte;
+ Reversed: Boolean;
+
+ TotEntrys: Cardinal;
+ TotPages: Cardinal;
+
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+
+ procedure SetTitle;
+ Procedure SetPage(NewPage: Cardinal);
+ end;
+
+implementation
+
+uses
+ UGraphic,
+ ULanguage,
+ Math,
+ Classes,
+ ULog;
+
+function TScreenStatDetail.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenStatMain);
+ end;
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then begin
+ //Next Page
+ SetPage(Page+1);
+ end;
+
+ if Interaction = 1 then begin
+ //Previous Page
+ if (Page > 0) then
+ SetPage(Page-1);
+ end;
+
+ if Interaction = 2 then begin
+ //Reverse Order
+ Reversed := not Reversed;
+ SetPage(Page);
+ end;
+
+ if Interaction = 3 then begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenStatMain);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenStatDetail.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ for I := 0 to High(Theme.StatDetail.TextList) do
+ AddText(Theme.StatDetail.TextList[I]);
+
+ Count := Length(Theme.StatDetail.TextList);
+
+ AddText(Theme.StatDetail.TextDescription);
+ AddText(Theme.StatDetail.TextPage);
+
+ LoadFromTheme(Theme.StatDetail);
+
+ AddButton(Theme.StatDetail.ButtonNext);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_NEXT'));
+
+ AddButton(Theme.StatDetail.ButtonPrev);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_PREV'));
+
+ AddButton(Theme.StatDetail.ButtonReverse);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_REVERSE'));
+
+ AddButton(Theme.StatDetail.ButtonExit);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ Interaction := 0;
+ Typ := TStatType(0);
+end;
+
+procedure TScreenStatDetail.onShow;
+begin
+ inherited;
+
+ //Set Tot Entrys and PAges
+ TotEntrys := DataBase.GetTotalEntrys(Typ);
+ TotPages := Ceil(TotEntrys / Count);
+
+ //Show correct Title
+ SetTitle;
+
+ //Show First Page
+ Reversed := False;
+ SetPage(0);
+end;
+
+procedure TScreenStatDetail.SetTitle;
+begin
+ if Reversed then
+ Text[Count].Text := Theme.StatDetail.DescriptionR[Ord(Typ)]
+ else
+ Text[Count].Text := Theme.StatDetail.Description[Ord(Typ)];
+end;
+
+procedure TScreenStatDetail.SetPage(NewPage: Cardinal);
+var
+ StatList: TList;
+ I: Integer;
+ FormatStr: String;
+ PerPage: Byte;
+begin
+ // fetch statistics
+ StatList := Database.GetStats(Typ, Count, NewPage, Reversed);
+ if ((StatList <> nil) and (StatList.Count > 0)) then
+ begin
+ Page := NewPage;
+
+ // reset texts
+ for I := 0 to Count-1 do
+ Text[I].Text := '';
+
+ FormatStr := Theme.StatDetail.FormatStr[Ord(Typ)];
+
+ //refresh Texts
+ for I := 0 to StatList.Count-1 do
+ begin
+ try
+ case Typ of
+ stBestScores: begin //Best Scores
+ with TStatResultBestScores(StatList[I]) do
+ begin
+ //Set Texts
+ if (Score > 0) then
+ begin
+ Text[I].Text := Format(FormatStr,
+ [Singer, Score, Theme.ILevel[Difficulty], SongArtist, SongTitle]);
+ end;
+ end;
+ end;
+
+ stBestSingers: begin //Best Singers
+ with TStatResultBestSingers(StatList[I]) do
+ begin
+ //Set Texts
+ if (AverageScore > 0) then
+ Text[I].Text := Format(FormatStr, [Player, AverageScore]);
+ end;
+ end;
+
+ stMostSungSong: begin //Popular Songs
+ with TStatResultMostSungSong(StatList[I]) do
+ begin
+ //Set Texts
+ if (Artist <> '') then
+ Text[I].Text := Format(FormatStr, [Artist, Title, TimesSung]);
+ end;
+ end;
+
+ stMostPopBand: begin //Popular Bands
+ with TStatResultMostPopBand(StatList[I]) do
+ begin
+ //Set Texts
+ if (ArtistName <> '') then
+ Text[I].Text := Format(FormatStr, [ArtistName, TimesSungtot]);
+ end;
+ end;
+ end;
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString in UScreenStatDetail: ' + E.Message);
+ end;
+ end;
+
+ if (Page + 1 = TotPages) and (TotEntrys mod Count <> 0) then
+ PerPage := (TotEntrys mod Count)
+ else
+ PerPage := Count;
+
+ try
+ Text[Count+1].Text := Format(Theme.StatDetail.PageStr,
+ [Page + 1, TotPages, PerPage, TotEntrys]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString in UScreenStatDetail: ' + E.Message);
+ end;
+
+ //Show correct Title
+ SetTitle;
+ end;
+
+ Database.FreeStats(StatList);
+end;
+
+
+procedure TScreenStatDetail.SetAnimationProgress(Progress: real);
+var I: Integer;
+begin
+ for I := 0 to High(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenStatMain.pas b/src/Screens/UScreenStatMain.pas
new file mode 100644
index 00000000..bec9d312
--- /dev/null
+++ b/src/Screens/UScreenStatMain.pas
@@ -0,0 +1,301 @@
+unit UScreenStatMain;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UDisplay,
+ UMusic,
+ UIni,
+ UThemes;
+
+type
+ TScreenStatMain = class(TMenu)
+ private
+ //Some Stat Value that don't need to be calculated 2 times
+ SongsWithVid: Cardinal;
+ function FormatOverviewIntro(FormatStr: string): string;
+ function FormatSongOverview(FormatStr: string): string;
+ function FormatPlayerOverview(FormatStr: string): string;
+ public
+ TextOverview: integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+
+ procedure SetOverview;
+ end;
+
+implementation
+
+uses UGraphic,
+ UDataBase,
+ USongs,
+ USong,
+ ULanguage,
+ UCommon,
+ Classes,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ sysconst,
+ {$ENDIF}
+ ULog;
+
+function TScreenStatMain.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+ SDLK_RETURN:
+ begin
+ //Exit Button Pressed
+ if Interaction = 4 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end
+ else //One of the Stats Buttons Pressed
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ ScreenStatDetail.Typ := TStatType(Interaction);
+ FadeTo(@ScreenStatDetail);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenStatMain.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ TextOverview := AddText(Theme.StatMain.TextOverview);
+
+ LoadFromTheme(Theme.StatMain);
+
+ AddButton(Theme.StatMain.ButtonScores);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[0]);
+
+ AddButton(Theme.StatMain.ButtonSingers);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[1]);
+
+ AddButton(Theme.StatMain.ButtonSongs);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[2]);
+
+ AddButton(Theme.StatMain.ButtonBands);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[3]);
+
+ AddButton(Theme.StatMain.ButtonExit);
+ if (Length(Button[4].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[4]);
+
+ Interaction := 0;
+
+ //Set Songs with Vid
+ SongsWithVid := 0;
+ For I := 0 to Songs.SongList.Count -1 do
+ if (TSong(Songs.SongList[I]).Video <> '') then
+ Inc(SongsWithVid);
+end;
+
+procedure TScreenStatMain.onShow;
+begin
+ inherited;
+
+ //Set Overview Text:
+ SetOverview;
+end;
+
+function TScreenStatMain.FormatOverviewIntro(FormatStr: string): string;
+var
+ Year, Month, Day: Word;
+begin
+ {Format:
+ %0:d Ultrastar Version
+ %1:d Day of Reset
+ %2:d Month of Reset
+ %3:d Year of Reset}
+
+ Result := '';
+
+ try
+ DecodeDate(Database.GetStatReset(), Year, Month, Day);
+ Result := Format(FormatStr, [Language.Translate('US_VERSION'), Day, Month, Year]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_INTRO": ' + E.Message);
+ end;
+end;
+
+function TScreenStatMain.FormatSongOverview(FormatStr: string): string;
+var
+ CntSongs, CntSungSongs, CntVidSongs: Integer;
+ MostPopSongArtist, MostPopSongTitle: String;
+ StatList: TList;
+ MostSungSong: TStatResultMostSungSong;
+begin
+ {Format:
+ %0:d Count Songs
+ %1:d Count of Sung Songs
+ %2:d Count of UnSung Songs
+ %3:d Count of Songs with Video
+ %4:s Name of the most popular Song}
+
+ CntSongs := Songs.SongList.Count;
+ CntSungSongs := Database.GetTotalEntrys(stMostSungSong);
+ CntVidSongs := SongsWithVid;
+
+ StatList := Database.GetStats(stMostSungSong, 1, 0, False);
+ if ((StatList <> nil) and (StatList.Count > 0)) then
+ begin
+ MostSungSong := StatList[0];
+ MostPopSongArtist := MostSungSong.Artist;
+ MostPopSongTitle := MostSungSong.Title;
+ end
+ else
+ begin
+ MostPopSongArtist := '-';
+ MostPopSongTitle := '-';
+ end;
+ Database.FreeStats(StatList);
+
+ Result := '';
+
+ try
+ Result := Format(FormatStr, [
+ CntSongs, CntSungSongs, CntSongs-CntSungSongs, CntVidSongs,
+ MostPopSongArtist, MostPopSongTitle]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_SONG": ' + E.Message);
+ end;
+end;
+
+function TScreenStatMain.FormatPlayerOverview(FormatStr: string): string;
+var
+ CntPlayers: Integer;
+ BestScoreStat: TStatResultBestScores;
+ BestSingerStat: TStatResultBestSingers;
+ BestPlayer, BestScorePlayer: String;
+ BestPlayerScore, BestScore: Integer;
+ SingerStats, ScoreStats: TList;
+begin
+ {Format:
+ %0:d Count Players
+ %1:s Best Player
+ %2:d Best Players Score
+ %3:s Best Score Player
+ %4:d Best Score}
+
+ CntPlayers := Database.GetTotalEntrys(stBestSingers);
+
+ SingerStats := Database.GetStats(stBestSingers, 1, 0, False);
+ if ((SingerStats <> nil) and (SingerStats.Count > 0)) then
+ begin
+ BestSingerStat := SingerStats[0];
+ BestPlayer := BestSingerStat.Player;
+ BestPlayerScore := BestSingerStat.AverageScore;
+ end
+ else
+ begin
+ BestPlayer := '-';
+ BestPlayerScore := 0;
+ end;
+ Database.FreeStats(SingerStats);
+
+ ScoreStats := Database.GetStats(stBestScores, 1, 0, False);
+ if ((ScoreStats <> nil) and (ScoreStats.Count > 0)) then
+ begin
+ BestScoreStat := ScoreStats[0];
+ BestScorePlayer := BestScoreStat.Singer;
+ BestScore := BestScoreStat.Score;
+ end
+ else
+ begin
+ BestScorePlayer := '-';
+ BestScore := 0;
+ end;
+ Database.FreeStats(ScoreStats);
+
+ Result := '';
+
+ try
+ Result := Format(Formatstr, [
+ CntPlayers, BestPlayer, BestPlayerScore,
+ BestScorePlayer, BestScore]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_PLAYER": ' + E.Message);
+ end;
+end;
+
+procedure TScreenStatMain.SetOverview;
+var
+ Overview: String;
+begin
+ // Format overview
+ Overview := FormatOverviewIntro(Language.Translate('STAT_OVERVIEW_INTRO')) + '\n \n' +
+ FormatSongOverview(Language.Translate('STAT_OVERVIEW_SONG')) + '\n \n' +
+ FormatPlayerOverview(Language.Translate('STAT_OVERVIEW_PLAYER'));
+ Text[0].Text := Overview;
+end;
+
+
+procedure TScreenStatMain.SetAnimationProgress(Progress: real);
+var I: Integer;
+begin
+ For I := 0 to high(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/src/Screens/UScreenTop5.pas b/src/Screens/UScreenTop5.pas
new file mode 100644
index 00000000..f4be431f
--- /dev/null
+++ b/src/Screens/UScreenTop5.pas
@@ -0,0 +1,175 @@
+unit UScreenTop5;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, USongs, UThemes;
+
+type
+ TScreenTop5 = class(TMenu)
+ public
+ TextLevel: integer;
+ TextArtistTitle: integer;
+
+ StaticNumber: array[1..5] of integer;
+ TextNumber: array[1..5] of integer;
+ TextName: array[1..5] of integer;
+ TextScore: array[1..5] of integer;
+
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+ end;
+
+implementation
+
+uses UGraphic, UDataBase, UMain, UIni;
+
+function TScreenTop5.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE,
+ SDLK_RETURN:
+ begin
+ if (not Fadeout) then begin
+ FadeTo(@ScreenSong);
+ Fadeout := true;
+ end;
+ end;
+ SDLK_SYSREQ:
+ begin
+ Display.SaveScreenShot;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenTop5.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Top5);
+
+
+ TextLevel := AddText(Theme.Top5.TextLevel);
+ TextArtistTitle := AddText(Theme.Top5.TextArtistTitle);
+
+ for I := 0 to 4 do
+ StaticNumber[I+1] := AddStatic( Theme.Top5.StaticNumber[I] );
+
+ for I := 0 to 4 do
+ TextNumber[I+1] := AddText(Theme.Top5.TextNumber[I]);
+ for I := 0 to 4 do
+ TextName[I+1] := AddText(Theme.Top5.TextName[I]);
+ for I := 0 to 4 do
+ TextScore[I+1] := AddText(Theme.Top5.TextScore[I]);
+
+end;
+
+procedure TScreenTop5.onShow;
+var
+ I: integer;
+ PMax: integer;
+begin
+ inherited;
+
+ Fadeout := false;
+
+ //ReadScore(CurrentSong);
+
+ PMax := Ini.Players;
+ if PMax = 4 then PMax := 5;
+ for I := 0 to PMax do
+ DataBase.AddScore(CurrentSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalInt));
+
+ DataBase.WriteScore(CurrentSong);
+ DataBase.ReadScore(CurrentSong);
+
+ Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
+
+ for I := 1 to Length(CurrentSong.Score[Ini.Difficulty]) do begin
+ Static[StaticNumber[I]].Visible := true;
+ Text[TextNumber[I]].Visible := true;
+ Text[TextName[I]].Visible := true;
+ Text[TextScore[I]].Visible := true;
+
+ Text[TextName[I]].Text := CurrentSong.Score[Ini.Difficulty, I-1].Name;
+ Text[TextScore[I]].Text := IntToStr(CurrentSong.Score[Ini.Difficulty, I-1].Score);
+ end;
+
+ for I := Length(CurrentSong.Score[Ini.Difficulty])+1 to 5 do begin
+ Static[StaticNumber[I]].Visible := false;
+ Text[TextNumber[I]].Visible := false;
+ Text[TextName[I]].Visible := false;
+ Text[TextScore[I]].Visible := false;
+ end;
+
+ Text[TextLevel].Text := IDifficulty[Ini.Difficulty];
+end;
+
+function TScreenTop5.Draw: boolean;
+//var
+{ Min: real;
+ Max: real;
+ Wsp: real;
+ Wsp2: real;
+ Pet: integer;}
+
+{ Item: integer;
+ P: integer;
+ C: integer;}
+begin
+ // Singstar - let it be...... with 6 statics
+(* if PlayersPlay = 6 then begin
+ for Item := 4 to 6 do begin
+ if ScreenAct = 1 then P := Item-4;
+ if ScreenAct = 2 then P := Item-1;
+
+ FillPlayer(Item, P);
+
+{ if ScreenAct = 1 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P1Dark');
+ end;
+
+ if ScreenAct = 2 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P4Dark');
+ end; }
+
+ end;
+ end; *)
+
+ Result := inherited Draw;
+end;
+
+end.
diff --git a/src/Screens/UScreenWelcome.pas b/src/Screens/UScreenWelcome.pas
new file mode 100644
index 00000000..613f3a80
--- /dev/null
+++ b/src/Screens/UScreenWelcome.pas
@@ -0,0 +1,122 @@
+unit UScreenWelcome;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, SysUtils, UThemes;
+
+type
+ TScreenWelcome = class(TMenu)
+ public
+ Animation: real;
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UTime, USkins, UTexture;
+
+function TScreenWelcome.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Result := False;
+ end;
+ SDLK_RETURN:
+ begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenWelcome.Create;
+begin
+ inherited Create;
+ AddStatic(-10, -10, 0, 0, 1, 1, 1, Skin.GetTextureFileName('ButtonAlt'), TEXTURE_TYPE_TRANSPARENT);
+ AddStatic(-500, 440, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 472, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 504, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 536, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 568, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ Animation := 0;
+ Fadeout := false;
+end;
+
+procedure TScreenWelcome.onShow;
+begin
+ inherited;
+
+ CountSkipTimeSet;
+end;
+
+function TScreenWelcome.Draw: boolean;
+var
+ Min: real;
+ Max: real;
+ Wsp: real;
+ Pet: integer;
+begin
+ // star animation
+ Animation := Animation + TimeSkip*1000;
+
+ // draw nothing
+ Min := 0; Max := 1000;
+ if (Animation >= Min) and (Animation < Max) then begin
+ end;
+
+ // popup
+ Min := 1000; Max := 1120;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.X := 600;
+ Static[0].Texture.Y := 600 - Wsp * 230;
+ Static[0].Texture.W := 200;
+ Static[0].Texture.H := Wsp * 230;
+ end;
+
+ // bounce
+ Min := 1120; Max := 1200;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.Y := 370 + Wsp * 50;
+ Static[0].Texture.H := 230 - Wsp * 50;
+ end;
+
+ // run
+ Min := 1500; Max := 3500;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[0].Texture.X := 600 - Wsp * 1400;
+ Static[0].Texture.H := 180;
+
+
+ for Pet := 1 to 5 do begin
+ Static[Pet].Texture.X := 770 - Wsp * 1400;
+ Static[Pet].Texture.W := 150 + Wsp * 200;
+ Static[Pet].Texture.Alpha := Wsp * 0.5;
+ end;
+ end;
+
+ Min := 3500;
+ if (Animation >= Min) and (not Fadeout) then begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+
+ Result := inherited Draw;
+end;
+
+end.
diff --git a/src/UltraStar-linux.lpi b/src/UltraStar-linux.lpi
new file mode 100644
index 00000000..d3866f94
--- /dev/null
+++ b/src/UltraStar-linux.lpi
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UltraStar.dpr b/src/UltraStar.dpr
new file mode 100644
index 00000000..c39f596c
--- /dev/null
+++ b/src/UltraStar.dpr
@@ -0,0 +1,294 @@
+program UltraStar;
+
+{$IFDEF MSWINDOWS}
+ {$R 'UltraStar.res' 'UltraStar.rc'}
+{$ENDIF}
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+//{$DEFINE CONSOLE}
+
+// TODO: check if this is needed for MacOSX too
+{$IFDEF MSWINDOWS}
+ // Set global application-type (GUI/CONSOLE) switch for Windows.
+ // CONSOLE is the default for FPC, GUI for Delphi, so we have
+ // to specify one of the two in any case.
+ {$IFDEF CONSOLE}
+ {$APPTYPE CONSOLE}
+ {$ELSE}
+ {$APPTYPE GUI}
+ {$ENDIF}
+{$ENDIF}
+
+uses
+ {$IFDEF Unix}
+ cthreads, // THIS MUST be the first used unit in FPC if Threads are used!!
+ // (see http://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial)
+ {$IFNDEF DARWIN}
+ cwstring, // Enable Unicode support. MacOSX misses some references to iconv.
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFNDEF FPC}
+ ctypes in 'lib\ctypes\ctypes.pas', // FPC compatibility types for C libs
+ {$ENDIF}
+
+ //------------------------------
+ //Includes - 3rd Party Libraries
+ //------------------------------
+ moduleloader in 'lib\JEDI-SDL\SDL\Pas\moduleloader.pas',
+ gl in 'lib\JEDI-SDL\OpenGL\Pas\gl.pas',
+ glu in 'lib\JEDI-SDL\OpenGL\Pas\glu.pas',
+ glext in 'lib\JEDI-SDL\OpenGL\Pas\glext.pas',
+ sdl in 'lib\JEDI-SDL\SDL\Pas\sdl.pas',
+ sdl_image in 'lib\JEDI-SDL\SDL_Image\Pas\sdl_image.pas',
+ //sdl_ttf in 'lib\JEDI-SDL\SDL_ttf\Pas\sdl_ttf.pas',
+ sdlutils in 'lib\JEDI-SDL\SDL\Pas\sdlutils.pas',
+ UMediaCore_SDL in 'Classes\UMediaCore_SDL.pas',
+
+ zlib in 'lib\zlib\zlib.pas',
+ png in 'lib\libpng\png.pas',
+
+ {$IFDEF UseBass}
+ bass in 'lib\bass\delphi\bass.pas',
+ UAudioCore_Bass in 'Classes\UAudioCore_Bass.pas',
+ {$ENDIF}
+ {$IFDEF UsePortaudio}
+ portaudio in 'lib\portaudio\delphi\portaudio.pas',
+ UAudioCore_Portaudio in 'Classes\UAudioCore_Portaudio.pas',
+ {$ENDIF}
+ {$IFDEF UsePortmixer}
+ portmixer in 'lib\portmixer\delphi\portmixer.pas',
+ {$ENDIF}
+
+ {$IFDEF UseFFmpeg}
+ avcodec in 'lib\ffmpeg\avcodec.pas',
+ avformat in 'lib\ffmpeg\avformat.pas',
+ avutil in 'lib\ffmpeg\avutil.pas',
+ rational in 'lib\ffmpeg\rational.pas',
+ opt in 'lib\ffmpeg\opt.pas',
+ avio in 'lib\ffmpeg\avio.pas',
+ mathematics in 'lib\ffmpeg\mathematics.pas',
+ UMediaCore_FFmpeg in 'Classes\UMediaCore_FFmpeg.pas',
+ {$IFDEF UseSWScale}
+ swscale in 'lib\ffmpeg\swscale.pas',
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF UseSRCResample}
+ samplerate in 'lib\samplerate\samplerate.pas',
+ {$ENDIF}
+
+ {$IFDEF UseProjectM}
+ projectM in 'lib\projectM\projectM.pas',
+ {$ENDIF}
+
+ {$IFDEF MSWINDOWS}
+ {$IFDEF FPC}
+ // FPC compatibility file for Allocate/DeallocateHWnd
+ WinAllocation in 'lib\other\WinAllocation.pas',
+ {$ENDIF}
+
+ midiout in 'lib\midi\midiout.pas',
+ CIRCBUF in 'lib\midi\CIRCBUF.PAS',
+ MidiType in 'lib\midi\MidiType.PAS',
+ MidiDefs in 'lib\midi\MidiDefs.PAS',
+ MidiCons in 'lib\midi\MidiCons.PAS',
+ MidiFile in 'lib\midi\MidiFile.PAS',
+ Delphmcb in 'lib\midi\Delphmcb.PAS',
+
+ DirWatch in 'lib\other\DirWatch.pas',
+ {$ENDIF}
+
+ {$IFDEF DARWIN}
+ PseudoThread in 'MacOSX/Wrapper/PseudoThread.pas',
+ {$ENDIF}
+
+ SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
+ SQLite3 in 'lib\SQLite\SQLite3.pas',
+
+
+ //------------------------------
+ //Includes - Menu System
+ //------------------------------
+ UDisplay in 'Menu\UDisplay.pas',
+ UMenu in 'Menu\UMenu.pas',
+ UMenuStatic in 'Menu\UMenuStatic.pas',
+ UMenuText in 'Menu\UMenuText.pas',
+ UMenuButton in 'Menu\UMenuButton.pas',
+ UMenuInteract in 'Menu\UMenuInteract.pas',
+ UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas',
+ UDrawTexture in 'Menu\UDrawTexture.pas',
+ UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas',
+
+ //------------------------------
+ //Includes - Classes
+ //------------------------------
+ UConfig in 'Classes\UConfig.pas',
+
+ UCommon in 'Classes\UCommon.pas',
+ UGraphic in 'Classes\UGraphic.pas',
+ UTexture in 'Classes\UTexture.pas',
+ ULanguage in 'Classes\ULanguage.pas',
+ UMain in 'Classes\UMain.pas',
+ UDraw in 'Classes\UDraw.pas',
+ URecord in 'Classes\URecord.pas',
+ UTime in 'Classes\UTime.pas',
+ TextGL in 'Classes\TextGL.pas',
+ USong in 'Classes\USong.pas',
+ UXMLSong in 'Classes\UXMLSong.pas',
+ USongs in 'Classes\USongs.pas',
+ UIni in 'Classes\UIni.pas',
+ UImage in 'Classes\UImage.pas',
+ ULyrics in 'Classes\ULyrics.pas',
+ UEditorLyrics in 'Classes\UEditorLyrics.pas',
+ USkins in 'Classes\USkins.pas',
+ UThemes in 'Classes\UThemes.pas',
+ ULog in 'Classes\ULog.pas',
+ UJoystick in 'Classes\UJoystick.pas',
+ //ULCD in 'Classes\ULCD.pas',
+ //ULight in 'Classes\ULight.pas',
+ UDataBase in 'Classes\UDataBase.pas',
+ UCovers in 'Classes\UCovers.pas',
+ UCatCovers in 'Classes\UCatCovers.pas',
+ UFiles in 'Classes\UFiles.pas',
+ UGraphicClasses in 'Classes\UGraphicClasses.pas',
+ UDLLManager in 'Classes\UDLLManager.pas',
+ UPlaylist in 'Classes\UPlaylist.pas',
+ UCommandLine in 'Classes\UCommandLine.pas',
+ URingBuffer in 'Classes\URingBuffer.pas',
+ UTextClasses in 'Classes\UTextClasses.pas',
+ USingScores in 'Classes\USingScores.pas',
+ USingNotes in 'Classes\USingNotes.pas',
+
+ UModules in 'Classes\UModules.pas', //List of Modules to Load
+ UHooks in 'Classes\UHooks.pas', //Hook Managing
+ UServices in 'Classes\UServices.pas', //Service Managing
+ UCore in 'Classes\UCore.pas', //Core, Maybe remove this
+ UCoreModule in 'Classes\UCoreModule.pas', //^
+ UPluginInterface in 'Classes\UPluginInterface.pas', //Interface offered by Core to Plugins
+ uPluginLoader in 'Classes\uPluginLoader.pas', //New Plugin Loader Module
+
+ UParty in 'Classes\UParty.pas', // TODO: rewrite Party Manager as Module, reomplent ability to offer party Mody by Plugin
+ UPlatform in 'Classes\UPlatform.pas',
+{$IFDEF MSWINDOWS}
+ UPlatformWindows in 'Classes\UPlatformWindows.pas',
+{$ENDIF}
+{$IFDEF LINUX}
+ UPlatformLinux in 'Classes\UPlatformLinux.pas',
+{$ENDIF}
+{$IFDEF DARWIN}
+ UPlatformMacOSX in 'Classes/UPlatformMacOSX.pas',
+{$ENDIF}
+
+ //------------------------------
+ //Includes - Media
+ //------------------------------
+
+ UMusic in 'Classes\UMusic.pas',
+ UAudioPlaybackBase in 'Classes\UAudioPlaybackBase.pas',
+{$IF Defined(UsePortaudioPlayback) or Defined(UseSDLPlayback)}
+ UFFT in 'lib\fft\UFFT.pas',
+ UAudioPlayback_Softmixer in 'Classes\UAudioPlayback_SoftMixer.pas',
+{$IFEND}
+ UAudioConverter in 'Classes\UAudioConverter.pas',
+
+ //******************************
+ //Pluggable media modules
+ // The modules are prioritized as in the include list below.
+ // This means the first entry has highest priority, the last lowest.
+ //******************************
+
+ // TODO : these all should be moved to a media folder
+
+{$IFDEF UseFFmpegVideo}
+ UVideo in 'Classes\UVideo.pas',
+{$ENDIF}
+{$IFDEF UseProjectM}
+ // must be after UVideo, so it will not be the default video module
+ UVisualizer in 'Classes\UVisualizer.pas',
+{$ENDIF}
+{$IFDEF UseBASSInput}
+ UAudioInput_Bass in 'Classes\UAudioInput_Bass.pas',
+{$ENDIF}
+{$IFDEF UseBASSDecoder}
+ // prefer Bass to FFmpeg if possible
+ UAudioDecoder_Bass in 'Classes\UAudioDecoder_Bass.pas',
+{$ENDIF}
+{$IFDEF UseBASSPlayback}
+ UAudioPlayback_Bass in 'Classes\UAudioPlayback_Bass.pas',
+{$ENDIF}
+{$IFDEF UseSDLPlayback}
+ UAudioPlayback_SDL in 'Classes\UAudioPlayback_SDL.pas',
+{$ENDIF}
+{$IFDEF UsePortaudioInput}
+ UAudioInput_Portaudio in 'Classes\UAudioInput_Portaudio.pas',
+{$ENDIF}
+{$IFDEF UsePortaudioPlayback}
+ UAudioPlayback_Portaudio in 'Classes\UAudioPlayback_Portaudio.pas',
+{$ENDIF}
+{$IFDEF UseFFmpegDecoder}
+ UAudioDecoder_FFmpeg in 'Classes\UAudioDecoder_FFmpeg.pas',
+{$ENDIF}
+ // fallback dummy, must be last
+ UMedia_dummy in 'Classes\UMedia_dummy.pas',
+
+
+ //------------------------------
+ //Includes - Screens
+ //------------------------------
+ UScreenLoading in 'Screens\UScreenLoading.pas',
+ UScreenWelcome in 'Screens\UScreenWelcome.pas',
+ UScreenMain in 'Screens\UScreenMain.pas',
+ UScreenName in 'Screens\UScreenName.pas',
+ UScreenLevel in 'Screens\UScreenLevel.pas',
+ UScreenSong in 'Screens\UScreenSong.pas',
+ UScreenSing in 'Screens\UScreenSing.pas',
+ UScreenScore in 'Screens\UScreenScore.pas',
+ UScreenOptions in 'Screens\UScreenOptions.pas',
+ UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas',
+ UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas',
+ UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas',
+ UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas',
+ UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas',
+ UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas',
+ UScreenOptionsAdvanced in 'Screens\UScreenOptionsAdvanced.pas',
+ UScreenEditSub in 'Screens\UScreenEditSub.pas',
+ UScreenEdit in 'Screens\UScreenEdit.pas',
+ UScreenEditConvert in 'Screens\UScreenEditConvert.pas',
+ UScreenEditHeader in 'Screens\UScreenEditHeader.pas',
+ UScreenOpen in 'Screens\UScreenOpen.pas',
+ UScreenTop5 in 'Screens\UScreenTop5.pas',
+ UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
+ UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
+ UScreenStatMain in 'Screens\UScreenStatMain.pas',
+ UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
+ UScreenCredits in 'Screens\UScreenCredits.pas',
+ UScreenPopup in 'Screens\UScreenPopup.pas',
+
+ //Includes - Screens PartyMode
+ UScreenSingModi in 'Screens\UScreenSingModi.pas',
+ UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas',
+ UScreenPartyScore in 'Screens\UScreenPartyScore.pas',
+ UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas',
+ UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas',
+ UScreenPartyWin in 'Screens\UScreenPartyWin.pas',
+
+
+ //------------------------------
+ //Includes - Modi SDK
+ //------------------------------
+ ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', //Old SDK, will be deleted soon
+ UPluginDefs in '..\..\Modis\SDK\UPluginDefs.pas', //New SDK, not only Modis
+ UPartyDefs in '..\..\Modis\SDK\UPartyDefs.pas', //Headers to register Party Modes
+
+ SysUtils;
+
+begin
+ Main;
+end.
+
diff --git a/src/UltraStar.lpi b/src/UltraStar.lpi
new file mode 100644
index 00000000..e21d8786
--- /dev/null
+++ b/src/UltraStar.lpi
@@ -0,0 +1,598 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UltraStar.lpr b/src/UltraStar.lpr
new file mode 100644
index 00000000..66badecb
--- /dev/null
+++ b/src/UltraStar.lpr
@@ -0,0 +1,19 @@
+// ***************************************************************************
+//
+// Developers PLEASE NOTE !!!!!!!
+//
+// As of september 2007, I am working towards porting Ultrastar-DX to run
+// on Linux. I will be modifiying the source to make it compile in lazarus
+// on windows & linux and I will make sure that it compiles in delphi still
+// To help me in this endevour, please can you make a point of remembering
+// that linux is CASE SENSATIVE, and file / unit names must be as per
+// the filename exactly.
+//
+// EG : opengl12.pas must not be OpenGL in the uses cluase.
+//
+// thanks for your help...
+//
+// ***************************************************************************
+
+{$I UltraStar.dpr}
+
diff --git a/src/UltraStar.rc b/src/UltraStar.rc
new file mode 100644
index 00000000..f0f3b242
--- /dev/null
+++ b/src/UltraStar.rc
@@ -0,0 +1,38 @@
+Font TEX "../../Resources/Fonts/Normal/eurostar_regular.png"
+Font FNT "../../Resources/Fonts/Normal/eurostar_regular.dat"
+
+FontB TEX "../../Resources/Fonts/Bold/eurostar_regular_bold.png"
+FontB FNT "../../Resources/Fonts/Bold/eurostar_regular_bold.dat"
+
+FontO TEX "../../Resources/Fonts/Outline 1/Outline 1.png"
+FontO FNT "../../Resources/Fonts/Outline 1/Outline 1.dat"
+
+FontO2 TEX "../../Resources/Fonts/Outline 2/Outline 2.png"
+FontO2 FNT "../../Resources/Fonts/Outline 2/Outline 2.dat"
+
+MAINICON ICON "../../Resources/Graphics/ustar-icon_v01.ico"
+WINDOWICON TEX "../../Resources/Graphics/ustar-icon.png"
+
+CRDTS_BG TEX "../../Resources/Graphics/credits_v5_bg.png"
+CRDTS_OVL TEX "../../Resources/Graphics/credits_v5_overlay.png"
+CRDTS_blindguard TEX "../../Resources/Graphics/names_blindguard.png"
+CRDTS_blindy TEX "../../Resources/Graphics/names_blindy.png"
+CRDTS_canni TEX "../../Resources/Graphics/names_canni.png"
+CRDTS_commandio TEX "../../Resources/Graphics/names_commandio.png"
+CRDTS_lazyjoker TEX "../../Resources/Graphics/names_lazyjoker.png"
+CRDTS_mog TEX "../../Resources/Graphics/names_mog.png"
+CRDTS_mota TEX "../../Resources/Graphics/names_mota.png"
+CRDTS_skillmaster TEX "../../Resources/Graphics/names_skillmaster.png"
+CRDTS_whiteshark TEX "../../Resources/Graphics/names_whiteshark.png"
+INTRO_L01 TEX "../../Resources/Graphics/intro-l-01.png"
+INTRO_L02 TEX "../../Resources/Graphics/intro-l-02.png"
+INTRO_L03 TEX "../../Resources/Graphics/intro-l-03.png"
+INTRO_L04 TEX "../../Resources/Graphics/intro-l-04.png"
+INTRO_L05 TEX "../../Resources/Graphics/intro-l-05.png"
+INTRO_L06 TEX "../../Resources/Graphics/intro-l-06.png"
+INTRO_L07 TEX "../../Resources/Graphics/intro-l-07.png"
+INTRO_L08 TEX "../../Resources/Graphics/intro-l-08.png"
+INTRO_L09 TEX "../../Resources/Graphics/intro-l-09.png"
+OUTRO_BG TEX "../../Resources/Graphics/outro-bg.png"
+OUTRO_ESC TEX "../../Resources/Graphics/outro-esc.png"
+OUTRO_EXD TEX "../../Resources/Graphics/outro-exit-dark.png"
diff --git a/src/UnitTests/switches.inc b/src/UnitTests/switches.inc
new file mode 100644
index 00000000..e69de29b
diff --git a/src/UnitTests/test_libraries.lpi b/src/UnitTests/test_libraries.lpi
new file mode 100644
index 00000000..cc3a6ddf
--- /dev/null
+++ b/src/UnitTests/test_libraries.lpi
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UnitTests/test_libraries.lpr b/src/UnitTests/test_libraries.lpr
new file mode 100644
index 00000000..3e3ae380
--- /dev/null
+++ b/src/UnitTests/test_libraries.lpr
@@ -0,0 +1,31 @@
+program Test_Libraries;
+
+{$mode objfpc}{$H+}
+
+uses
+ Classes,
+ consoletestrunner,
+ TestSQLLite,
+ SQLite3 in '../lib/SQLite/SQLite3.pas',
+
+ SQLiteTable3 in '../lib/SQLite/SQLiteTable3.pas';
+
+type
+
+ { TLazTestRunner }
+
+ TMyTestRunner = class(TTestRunner)
+ protected
+ // override the protected methods of TTestRunner to customize its behavior
+ end;
+
+var
+ Application: TMyTestRunner;
+
+begin
+ Application := TMyTestRunner.Create(nil);
+ Application.Initialize;
+ Application.Title := 'FPCUnit Console test runner';
+ Application.Run;
+ Application.Free;
+end.
diff --git a/src/UnitTests/testsqllite.pas b/src/UnitTests/testsqllite.pas
new file mode 100644
index 00000000..b1b682d2
--- /dev/null
+++ b/src/UnitTests/testsqllite.pas
@@ -0,0 +1,84 @@
+unit TestSQLLite;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, fpcunit, testutils, testregistry, SQLiteTable3, unix;
+
+type
+
+ TTest_SqlLite= class(TTestCase)
+ private
+ fSQLLite : TSQLiteDatabase;
+ fFileName : string;
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+ published
+ procedure Test_Random_TableExists;
+ procedure Test_Delete_NonExistant_Table;
+ procedure Test_TableExists_On_0Length_File;
+ end;
+
+implementation
+
+procedure TTest_SqlLite.Test_Random_TableExists;
+begin
+ deletefile( fFileName );
+ fSQLLite := TSQLiteDatabase.Create( fFileName );
+
+ // Test if some random table exists
+ check( not fSQLLite.TableExists( 'testTable'+floattostr(now()) ) , 'Randomly Named Table Should NOT Exists (In an empty database file)' );
+end;
+
+procedure TTest_SqlLite.Test_Delete_NonExistant_Table;
+var
+ lSQL : String;
+begin
+ deletefile( fFileName );
+ fSQLLite := TSQLiteDatabase.Create( fFileName );
+ try
+ lSQL := 'DROP TABLE testtable';
+ fSQLLite.execsql( lSQL );
+ except
+ exit;
+ end;
+
+ Fail('SQLLite did not except when trying to delete a non existant table' );
+end;
+
+procedure TTest_SqlLite.Test_TableExists_On_0Length_File;
+var
+ lSQL : String;
+begin
+ deletefile( fFileName );
+ shell('cat /dev/null > '+fFileName);
+
+ if not fileexists( fFileName ) then
+ Fail('0 Length file was not created... oops' );
+
+ fSQLLite := TSQLiteDatabase.Create( fFileName );
+
+ check( not fSQLLite.TableExists( 'testTable' ) , 'Randomly Named Table Should NOT Exists' );
+end;
+
+
+procedure TTest_SqlLite.SetUp;
+begin
+ fFileName := 'test.db';
+// fSQLLite := TSQLiteDatabase.Create( fFileName );
+end;
+
+
+procedure TTest_SqlLite.TearDown;
+begin
+ freeandnil( fSQLLite );
+end;
+
+initialization
+
+ RegisterTest(TTest_SqlLite);
+end.
+
diff --git a/src/autogen.sh b/src/autogen.sh
new file mode 100755
index 00000000..3f598d0b
--- /dev/null
+++ b/src/autogen.sh
@@ -0,0 +1 @@
+aclocal -I m4 && autoconf
diff --git a/src/bamboo-build-lin-laz.bat b/src/bamboo-build-lin-laz.bat
new file mode 100644
index 00000000..bcaca539
--- /dev/null
+++ b/src/bamboo-build-lin-laz.bat
@@ -0,0 +1,4 @@
+clear
+fpc -S2cgi -OG1 -gl -vewnhi -l -Filib/JEDI-SDLv1.0/SDL/Pas/ -Fu/usr/lib/lazarus/components/images/lib/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/gtk2/ -Fu/usr/lib/lazarus/packager/units/i386-linux/ -Fu. -oUltraStar -dLCL -dLCLgtk2 UltraStar.lpr
+
+#mv ./UltraStar /home/jay/src/ultrastardx/output/
diff --git a/src/bamboo-build-lin-laz.sh b/src/bamboo-build-lin-laz.sh
new file mode 100644
index 00000000..ad8ef19f
--- /dev/null
+++ b/src/bamboo-build-lin-laz.sh
@@ -0,0 +1,6 @@
+svn update
+
+clear
+fpc -S2cgi -OG1 -gl -vewnhi -l -Filib/JEDI-SDLv1.0/SDL/Pas/ -Fu/usr/lib/lazarus/components/images/lib/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/ -Fu/usr/lib/lazarus/lcl/units/i386-linux/gtk2/ -Fu/usr/lib/lazarus/packager/units/i386-linux/ -Fu. -oUltraStar -dLCL -dLCLgtk2 UltraStar.lpr
+
+#mv ./UltraStar /home/jay/src/ultrastardx/output/
diff --git a/src/bamboo-build-win-delphi.bat b/src/bamboo-build-win-delphi.bat
new file mode 100644
index 00000000..8a6be942
--- /dev/null
+++ b/src/bamboo-build-win-delphi.bat
@@ -0,0 +1,9 @@
+"C:\Program Files\Borland\BDS\4.0\Bin\brc32.exe" -r ./UltraStar.rc
+
+"C:\Program Files\Borland\BDS\4.0\Bin\dcc32.exe" -U"lib\JEDI-SDL\SDL\Pas" -O"lib\JEDI-SDL\SDL\Pas" -I"lib\JEDI-SDL\SDL\Pas" -R"lib\JEDI-SDL\SDL\Pas" UltraStar.dpr
+cp UltraStar.exe ..\..\
+
+rem cd ..\..\Installer
+rem "C:\Program Files\NSIS\makeNSIS.exe" UltraStarDeluxe.nsi
+
+rem cd ..\Game\Code
\ No newline at end of file
diff --git a/src/bamboo-build-win-laz.bat b/src/bamboo-build-win-laz.bat
new file mode 100644
index 00000000..1d096004
--- /dev/null
+++ b/src/bamboo-build-win-laz.bat
@@ -0,0 +1,3 @@
+USDXResCompiler.exe UltraStar.rc
+
+C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fuc:\lazarus\components\jpeg\lib\i386-win32\ -Fuc:\lazarus\components\images\lib\i386-win32\ -Fuc:\lazarus\lcl\units\i386-win32\ -Fuc:\lazarus\lcl\units\i386-win32\win32\ -Fuc:\lazarus\packager\units\i386-win32\ -Fu. -oUltraStar.exe -dLCL -dLCLwin32 UltraStar.lpr
diff --git a/src/build.bat b/src/build.bat
new file mode 100644
index 00000000..59f465d5
--- /dev/null
+++ b/src/build.bat
@@ -0,0 +1,4 @@
+C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fu..\..\..\..\..\lazarus\components\jpeg\lib\i386-win32\ -Fu..\..\..\..\..\lazarus\components\images\lib\i386-win32\ -Fu..\..\..\..\..\lazarus\lcl\units\i386-win32\ -Fu..\..\..\..\..\lazarus\lcl\units\i386-win32\win32\ -Fu..\..\..\..\..\lazarus\packager\units\i386-win32\ -Fu. -oUltraStar.exe -dLCL -dLCLwin32 UltraStar.lpr
+rem C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe -S2cgi -OG1 -gl -vewnhi -l -Filib\JEDI-SDLv1.0\SDL\Pas\ -Fu. -oUltraStar.exe UltraStar.lpr
+
+move UltraStar.exe ..\..\
\ No newline at end of file
diff --git a/src/clean.bat b/src/clean.bat
new file mode 100644
index 00000000..ef4ca243
--- /dev/null
+++ b/src/clean.bat
@@ -0,0 +1,7 @@
+@ECHO OFF
+set OBJ_PATH=build\win32\fpc
+del %OBJ_PATH%\*.o
+del %OBJ_PATH%\*.ppu
+del %OBJ_PATH%\*.a
+del %OBJ_PATH%\*.rst
+del %OBJ_PATH%\*.compiled
diff --git a/src/config-darwin.inc b/src/config-darwin.inc
new file mode 100644
index 00000000..6b73ee24
--- /dev/null
+++ b/src/config-darwin.inc
@@ -0,0 +1,59 @@
+{*****************************************************************
+ * Configuration file for UltraStar-Deluxe 1.1-alpha
+ * config-darwin.inc. Generated from config.inc.in by configure.
+ *****************************************************************}
+
+{* Paths *}
+
+{$DEFINE UseLocalDirs}
+{$IF (not Defined(UseLocalDirs)) and Defined(IncludeConstants)}
+ PathSuffix = WideString('UltraStarDeluxe');
+ LogPath = WideString('/var/log/'+PathSuffix);
+ SharedPath = WideString('/usr/local/share/'+PathSuffix);
+{$IFEND}
+
+{* Libraries *}
+
+{$DEFINE HaveFFMpeg}
+{$IF Defined(HaveFFMpeg) and Defined(IncludeConstants)}
+ av__codec = 'libavcodec';
+ LIBAVCODEC_VERSION_MAJOR = 51;
+ LIBAVCODEC_VERSION_MINOR = 49;
+ LIBAVCODEC_VERSION_RELEASE = 0;
+
+ av__format = 'libavformat';
+ LIBAVFORMAT_VERSION_MAJOR = 52;
+ LIBAVFORMAT_VERSION_MINOR = 2;
+ LIBAVFORMAT_VERSION_RELEASE = 0;
+
+ av__util = 'libavutil';
+ LIBAVUTIL_VERSION_MAJOR = 49;
+ LIBAVUTIL_VERSION_MINOR = 6;
+ LIBAVUTIL_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$DEFINE HaveSWScale}
+{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
+ sw__scale = 'libswscale';
+ LIBSWSCALE_VERSION_MAJOR = 0;
+ LIBSWSCALE_VERSION_MINOR = 5;
+ LIBSWSCALE_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$UNDEF HaveProjectM}
+{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
+ ProjectM_DataDir = '';
+ PROJECTM_VERSION_MAJOR = 0;
+ PROJECTM_VERSION_MINOR = 0;
+ PROJECTM_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$DEFINE HavePortaudio}
+{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
+ PORTAUDIO_VERSION_MAJOR = 19;
+ PORTAUDIO_VERSION_MINOR = 0;
+ PORTAUDIO_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$UNDEF HavePortmixer}
+
diff --git a/src/config-win.inc b/src/config-win.inc
new file mode 100644
index 00000000..e3ca8840
--- /dev/null
+++ b/src/config-win.inc
@@ -0,0 +1,56 @@
+{*****************************************************************
+ * Configuration file for UltraStar Deluxe 1.1
+ *****************************************************************}
+
+{* Libraries *}
+
+{$DEFINE HaveFFmpeg}
+{$IF Defined(HaveFFmpeg) and Defined(IncludeConstants)}
+ av__codec = 'avcodec-51';
+ LIBAVCODEC_VERSION_MAJOR = 51;
+ LIBAVCODEC_VERSION_MINOR = 16;
+ LIBAVCODEC_VERSION_RELEASE = 0;
+
+ av__format = 'avformat-50';
+ LIBAVFORMAT_VERSION_MAJOR = 50;
+ LIBAVFORMAT_VERSION_MINOR = 5;
+ LIBAVFORMAT_VERSION_RELEASE = 0;
+
+ av__util = 'avutil-49';
+ LIBAVUTIL_VERSION_MAJOR = 49;
+ LIBAVUTIL_VERSION_MINOR = 0;
+ LIBAVUTIL_VERSION_RELEASE = 1;
+{$IFEND}
+
+{$UNDEF HaveSWScale}
+{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
+ sw__scale = 'swscale-0';
+ LIBSWSCALE_VERSION_MAJOR = 0;
+ LIBSWSCALE_VERSION_MINOR = 5;
+ LIBSWSCALE_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$DEFINE HaveProjectM}
+{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
+ ProjectM_DataDir = 'Visuals\projectM';
+ PROJECTM_VERSION_MAJOR = 1;
+ PROJECTM_VERSION_MINOR = 10;
+ PROJECTM_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$UNDEF HavePortaudio}
+{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
+ PORTAUDIO_VERSION_MAJOR = 19;
+ PORTAUDIO_VERSION_MINOR = 0;
+ PORTAUDIO_VERSION_RELEASE = 0;
+{$IFEND}
+
+{$UNDEF HavePortmixer}
+
+{$UNDEF HaveLibsamplerate}
+{$IF Defined(HaveLibsamplerate) and Defined(IncludeConstants)}
+ LIBSAMPLERATE_VERSION_MAJOR = 0;
+ LIBSAMPLERATE_VERSION_MINOR = 1;
+ LIBSAMPLERATE_VERSION_RELEASE = 3;
+{$IFEND}
+
diff --git a/src/config.inc.in b/src/config.inc.in
new file mode 100644
index 00000000..6bdf26b5
--- /dev/null
+++ b/src/config.inc.in
@@ -0,0 +1,58 @@
+{*****************************************************************
+ * Configuration file for @PACKAGE_STRING@
+ * @configure_input@
+ *****************************************************************}
+
+{* Paths *}
+
+{$@DEFINE_USE_LOCAL_DIRS@ UseLocalDirs}
+{$IF (not Defined(UseLocalDirs)) and Defined(IncludeConstants)}
+ PathSuffix = WideString('@suffix@');
+ SharedPath = WideString('@sharerootdir@/'+PathSuffix);
+{$IFEND}
+
+{* Libraries *}
+
+{$@DEFINE_HAVE_FFMPEG@ HaveFFmpeg}
+{$IF Defined(HaveFFmpeg) and Defined(IncludeConstants)}
+ av__codec = 'libavcodec';
+ LIBAVCODEC_VERSION_MAJOR = @libavcodec_VERSION_MAJOR@;
+ LIBAVCODEC_VERSION_MINOR = @libavcodec_VERSION_MINOR@;
+ LIBAVCODEC_VERSION_RELEASE = @libavcodec_VERSION_RELEASE@;
+
+ av__format = 'libavformat';
+ LIBAVFORMAT_VERSION_MAJOR = @libavformat_VERSION_MAJOR@;
+ LIBAVFORMAT_VERSION_MINOR = @libavformat_VERSION_MINOR@;
+ LIBAVFORMAT_VERSION_RELEASE = @libavformat_VERSION_RELEASE@;
+
+ av__util = 'libavutil';
+ LIBAVUTIL_VERSION_MAJOR = @libavutil_VERSION_MAJOR@;
+ LIBAVUTIL_VERSION_MINOR = @libavutil_VERSION_MINOR@;
+ LIBAVUTIL_VERSION_RELEASE = @libavutil_VERSION_RELEASE@;
+{$IFEND}
+
+{$@DEFINE_HAVE_SWSCALE@ HaveSWScale}
+{$IF Defined(HaveSWScale) and Defined(IncludeConstants)}
+ sw__scale = 'libswscale';
+ LIBSWSCALE_VERSION_MAJOR = @libswscale_VERSION_MAJOR@;
+ LIBSWSCALE_VERSION_MINOR = @libswscale_VERSION_MINOR@;
+ LIBSWSCALE_VERSION_RELEASE = @libswscale_VERSION_RELEASE@;
+{$IFEND}
+
+{$@DEFINE_HAVE_PROJECTM@ HaveProjectM}
+{$IF Defined(HaveProjectM) and Defined(IncludeConstants)}
+ ProjectM_DataDir = '@libprojectM_DATADIR@';
+ PROJECTM_VERSION_MAJOR = @libprojectM_VERSION_MAJOR@;
+ PROJECTM_VERSION_MINOR = @libprojectM_VERSION_MINOR@;
+ PROJECTM_VERSION_RELEASE = @libprojectM_VERSION_RELEASE@;
+{$IFEND}
+
+{$@DEFINE_HAVE_PORTAUDIO@ HavePortaudio}
+{$IF Defined(HavePortaudio) and Defined(IncludeConstants)}
+ PORTAUDIO_VERSION_MAJOR = @portaudio_VERSION_MAJOR@;
+ PORTAUDIO_VERSION_MINOR = @portaudio_VERSION_MINOR@;
+ PORTAUDIO_VERSION_RELEASE = @portaudio_VERSION_RELEASE@;
+{$IFEND}
+
+{$@DEFINE_HAVE_PORTMIXER@ HavePortmixer}
+
diff --git a/src/configure.ac b/src/configure.ac
new file mode 100644
index 00000000..4f1344f5
--- /dev/null
+++ b/src/configure.ac
@@ -0,0 +1,494 @@
+#
+# ultrastardx configure.ac script
+#
+# by UltraStar Deluxe Team
+#
+# Execute "autogen.sh" to create the configure script.
+#
+
+# Require autoconf >= 2.61
+AC_PREREQ(2.61)
+
+# Init autoconf
+AC_INIT([ultrastardx],
+ [1.1-alpha],
+ [http://sourceforge.net/tracker/?group_id=191560&atid=937872])
+# specify the website here
+PACKAGE_WEBSITE="http://www.ultrastardeluxe.org/"
+AC_SUBST(PACKAGE_WEBSITE)
+# specify the IRC-channel here
+PACKAGE_IRC="#ultrastardx at quakenet.org"
+AC_SUBST(PACKAGE_IRC)
+
+# Specify a source-file so autoconf can check if the source-dir exists
+AC_CONFIG_SRCDIR(UltraStar.dpr)
+
+# This one is not used by autoconf at the moment.
+# When it is used maybe we don't need aclocal's -I parameter anymore.
+AC_CONFIG_MACRO_DIR(m4)
+
+# show features and packages in one list
+AC_PRESERVE_HELP_ORDER
+
+# set root directory (= trunk dir)
+# ..resolved: used by configure.ac
+usdxroot=../..
+# ..unresolved: used by .in files
+usdxrootdir=\${top_srcdir}/../..
+AC_SUBST(usdxrootdir)
+
+# set sharerootdir to the resolved dataroot-dir for the config-*.inc file.
+# Pascal cannot handle shell-variables like ${prefix}
+AC_DEFINE_DIR(sharerootdir, datarootdir)
+
+# -----------------------------------------
+# find tools
+# -----------------------------------------
+
+# options for make command
+AC_PROG_MAKE_SET
+# find tool for ln -s (e.g. uses cp -p for FAT-filesystems)
+AC_LN_S
+# find a program for recursive dir creation
+AC_PROG_MKDIR_P
+# find the best install tool
+AC_PROG_INSTALL
+# some other useful tools
+#AC_PROG_AWK
+AC_PROG_SED
+AC_PROG_GREP
+#AC_PROG_EGREP
+
+# -----------------------------------------
+# macro declarations
+# -----------------------------------------
+
+# AC_TRIM(STRING)
+# removes surrounding whitespace
+# -------------------------------------------
+AC_DEFUN([AC_TRIM],
+[echo "[$1]" | $SED 's/^[[ \t]]*//' | $SED 's/[[ \t]]*$//'
+])
+
+# AC_SUBST_DEFINE(DEFINE_SUFFIX, IS_DEFINED)
+# used to enable/disable pascal defines
+AC_DEFUN([AC_SUBST_DEFINE],
+[
+ if [[ x$2 = xyes ]]; then
+ DEFINE_[$1]=DEFINE
+ else
+ DEFINE_[$1]=UNDEF
+ fi
+ AC_SUBST(DEFINE_[$1])
+])
+
+# AC_SUBST_COMMENT(DEFINE_SUFFIX, IS_ENABLED)
+# used to enable/disable lines in a Makefile
+AC_DEFUN([AC_SUBST_COMMENT],
+[
+ if [[ x$2 = xyes ]]; then
+ COMMENT_[$1]=""
+ else
+ COMMENT_[$1]="#"
+ fi
+ AC_SUBST(COMMENT_[$1])
+])
+
+# AC_SPLIT_VERSION(VARIABLE_PREFIX, VERSION)
+# Splits version number ("major.minor.release") into its components.
+# Sets
+# [$VARIABLE_PREFIX]_VERSION_MAJOR
+# [$VARIABLE_PREFIX]_VERSION_MINOR
+# [$VARIABLE_PREFIX]_VERSION_RELEASE
+# This function calls
+# AC_SUBST([$VARIABLE_PREFIX]_VERSION_type] for each type
+AC_DEFUN([AC_SPLIT_VERSION],
+[
+ version=[$2]
+
+ # strip leading non-numeric tokens
+ # (necessary for some ffmpeg-packages in ubuntu)
+ # example: 0d.51.1.0 -> 51.1.0
+ version=`echo $version | $SED 's/^[[^.]]*[[^0-9.]][[^.]]*\.//'`
+
+ # replace "." and "-" with " " and ignore trailing tokens.
+ # 1.23.4-r2 will be splitted to [maj=1, min=23, rel=4].
+ # In addition we delete every character which is not 0-9.
+ # 1.3a4-r32 will be [maj=1, min=34, rel=32].
+ read major minor release ignore <@)
+ else
+ [$1][_VERSION]="0.0.0"
+ fi
+ AC_SPLIT_VERSION([$1], $[$1][_VERSION])
+])
+
+# PKG_HAVE(VARIABLE_PREFIX, MODULE, [REQUIRED])
+# Checks with pkg-config if a package exists and retrieves information
+# about it.
+# Parameters:
+# - VARIABLE_PREFIX: the prefix for the variables storing information about the package.
+# - MODULE: package name according to pkg-config
+# - REQUIRED: if true, the configure-script is aborted if the package was not found
+# Uses:
+# with_[$VARIABLE_PREFIX]: whether and how the package should be checked for
+# "check": check for the package but do not abort if it does not exist (default)
+# "no": do not check for the package (sets _HAVE to "no" and _VERSION to "0.0.0")
+# "yes": check for the package and abort if it does not exist
+# "nocheck": do not check for the package (sets _HAVE to "yes")
+# Sets:
+# [$VARIABLE_PREFIX]_HAVE # package is available (values: "yes"|"no")
+# [$VARIABLE_PREFIX]_LIBS # linker flags (e.g. -Lmylibdir -lmylib)
+# [$VARIABLE_PREFIX]_LIBDIRS # library dirs (e.g. -Lmylibdir)
+AC_DEFUN([PKG_HAVE],
+[
+ have_lib="no"
+ AC_MSG_CHECKING([for $2])
+ if test x"$with_[$1]" = xnocheck; then
+ # do not call pkg-config, use user settings
+ have_lib="yes"
+ elif test x"$with_[$1]" != xno; then
+ # check if package exists
+ PKG_CHECK_EXISTS([$2], [
+ have_lib="yes"
+ [$1][_LIBS]=`$PKG_CONFIG --libs --silence-errors "$2"`
+ [$1][_LIBDIRS]=`$PKG_CONFIG --libs-only-L --silence-errors "$2"`
+ [$1][_LIBDIRS]=`AC_TRIM($[$1][_LIBDIRS])`
+ # add library directories to LIBS (ignore *_LIBS for now)
+ if test -n "$[$1][_LIBDIRS]"; then
+ LIBS="$LIBS $[$1][_LIBDIRS]"
+ fi
+ ])
+ fi
+ if test x$have_lib = xyes; then
+ [$1][_HAVE]="yes"
+ if test -n "$[$1][_LIBDIRS]"; then
+ # show additional lib-dirs
+ AC_MSG_RESULT(yes [(]$[$1][_LIBDIRS][)])
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ else
+ [$1][_HAVE]="no"
+ AC_MSG_RESULT(no)
+
+ # check if package is required
+ if test x$3 = xyes -o x"$with_[$1]" = xyes ; then
+ # print error message and quit
+ err_msg=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ AC_MSG_ERROR(
+[
+
+$err_msg
+
+Alternatively, you may set --with-[$1]=nocheck and the environment
+variables [$1]_[[...]] (see configure --help)
+to appropriate values to avoid the need to call pkg-config.
+
+See the pkg-config man page for more details.
+])
+ fi
+ fi
+])
+
+
+# -----------------------------------------
+# define switches
+# -----------------------------------------
+
+# print library options header
+AC_ARG_WITH([cfg-dummy1], [
+External Libraries:])
+
+# add portmixer option
+AC_ARG_WITH([portmixer],
+ [AS_HELP_STRING([--with-portmixer],
+ [enable portmixer audio-mixer support @<:@default=check@:>@])],
+ [with_portmixer=$withval], [with_portmixer="check"])
+
+# add projectM option
+AC_ARG_WITH([libprojectM],
+ [AS_HELP_STRING([--with-libprojectM],
+ [enable projectM visualization support @<:@default=no@:>@])],
+ [with_libprojectM=$withval], [with_libprojectM="no"])
+
+# print path options header
+AC_ARG_WITH([cfg-dummy2], [
+Additional directories:])
+
+# add suffix option
+AC_ARG_WITH([suffix],
+ [AS_HELP_STRING([--with-suffix=SUFFIX],
+ [path suffix @<:@default=ultrastardx@:>@])],
+ [suffix=$withval], [suffix="ultrastardx"])
+if [[ x$suffix = xno -o x$suffix = xyes ]] ; then
+ AC_MSG_ERROR([Invalid suffix.]);
+fi
+AC_SUBST(suffix)
+
+# print misc options header
+AC_ARG_WITH([cfg-dummy3], [
+Development options:])
+
+LOCAL_BUILD="no"
+
+# add global option
+AC_ARG_ENABLE(global,
+ [AS_HELP_STRING([--enable-global],
+ [install into global folders (PREFIX/...) @<:@default=yes@:>@])],
+ [test $enableval = "no" && LOCAL_BUILD="yes"], [])
+
+# add local option
+AC_ARG_ENABLE(local,
+ [AS_HELP_STRING([--enable-local],
+ [install into local folders (../../...) (same as --disable-global) @<:@default=no@:>@]))],
+ [test $enableval = "yes" && LOCAL_BUILD="yes"], [])
+
+# add dev_layout option
+AC_ARG_ENABLE(dev-build,
+ [AS_HELP_STRING([--enable-dev-build],
+ [development build (implies local) @<:@default=no@:>@])],
+ [enable_dev_build=$enableval], [enable_dev_build="no"])
+if [[ x$enable_dev_build = xyes ]]; then
+ LOCAL_BUILD="yes"
+fi
+
+# set default Makefile install-target according to local/global build-type
+AC_SUBST_DEFINE(USE_LOCAL_DIRS, $LOCAL_BUILD)
+if [[ x$LOCAL_BUILD = xyes ]]; then
+ AC_SUBST(install_type, ["local"])
+else
+ AC_SUBST(install_type, ["global"])
+fi
+
+
+# -----------------------------------------
+# check for compilers
+# -----------------------------------------
+
+# find and test the freepascal compiler
+# sets PFLAGS, FPC_VERSION, FPC_DEBUG, etc.
+AC_PROG_FPC
+# FPC_VERSION is already defined by FPC, use
+# PPC as prefix instead.
+AC_SPLIT_VERSION(PPC, $FPC_VERSION)
+
+# find and test the C compiler (for C-libs and wrappers)
+AC_PROG_CC
+AC_LANG([C])
+
+# find and test the C++ compiler (for C-libs and wrappers)
+AC_PROG_CXX
+AC_LANG([C++])
+
+AC_PROG_RANLIB
+
+# find pkg-config
+PKG_PROG_PKG_CONFIG()
+if [[ x$PKG_CONFIG = x ]]; then
+ AC_MSG_ERROR([
+!!! pkg-config was not found on your system.
+!!! It is needed to determine the versions of your libraries.
+!!! Install it and try again.])
+fi
+
+
+# -----------------------------------------
+# check for OS
+# -----------------------------------------
+
+if [[ x$FPC_PLATFORM = xdarwin ]]; then
+ AC_MSG_CHECKING([for Mac OS X version])
+ MACOSX_VERSION=`sw_vers -productVersion`
+ AC_SPLIT_VERSION(MACOSX, $MACOSX_VERSION)
+ AC_MSG_RESULT(@<:@$MACOSX_VERSION@:>@)
+fi
+
+# -----------------------------------------
+# check for libraries
+# -----------------------------------------
+
+# libpng
+PKG_HAVE([libpng], [libpng], yes)
+
+# find sdl
+PKG_HAVE([sdl], [sdl], yes)
+
+# find sqlite3
+PKG_HAVE([sqlite3], [sqlite3], yes)
+
+# find FFMpeg
+# Note: do not use the min/max version parameters with ffmpeg
+# otherwise it might fail in ubuntu due to a wrong version number
+# format in ffmpeg's .pc-files.
+# For example: 0d.51.1.2 instead of the correct 51.1.2.
+# A check for version >=52.0.0 will return version 0d.51.1.2
+# although it is lower because pkg-config is confused by the 0d.
+# Use [mylib]_VERSION_INT for version-checking instead
+PKG_HAVE([libavcodec], [libavcodec], yes)
+PKG_VERSION([libavcodec], [libavcodec])
+AC_CHECK_LIB([avcodec], [avcodec_decode_audio], [HAVE_AVCODEC_DECODE_AUDIO="yes"])
+AC_CHECK_LIB([avcodec], [avcodec_decode_audio2], [HAVE_AVCODEC_DECODE_AUDIO2="yes"])
+AC_CHECK_LIB([avcodec], [img_convert], [HAVE_IMG_CONVERT="yes"])
+PKG_HAVE([libavformat], [libavformat], yes)
+PKG_VERSION([libavformat], [libavformat])
+PKG_HAVE([libavutil], [libavutil], yes)
+PKG_VERSION([libavutil], [libavutil])
+if [[ x$libavcodec_HAVE = xyes -a x$libavformat_HAVE = xyes -a x$libavutil_HAVE = xyes ]]; then
+ ffmpeg_HAVE=yes
+else
+ ffmpeg_HAVE=no
+fi
+AC_SUBST_DEFINE(HAVE_FFMPEG, $ffmpeg_HAVE)
+
+# find FFMpeg's swscale lib (just if FFMpeg is compiled in GPL mode)
+PKG_HAVE([libswscale], [libswscale], no)
+PKG_VERSION([libswscale], [libswscale])
+AC_SUBST_DEFINE(HAVE_SWSCALE, $libswscale_HAVE)
+
+
+# find projectM version
+libprojectM_PKG="libprojectM >= 0.98"
+PKG_HAVE([libprojectM], [$libprojectM_PKG], no)
+PKG_VERSION([libprojectM], [$libprojectM_PKG])
+AC_SUBST_DEFINE(HAVE_PROJECTM, $libprojectM_HAVE)
+# get projectM include-dir
+PKG_VALUE([libprojectM], [INCLUDEDIR], [variable=includedir], [$libprojectM_PKG],
+ [C-Header include-dir (e.g. /usr/include)])
+# get projectM data-dir (for preset- and font-dir)
+PKG_VALUE([libprojectM], [DATADIR], [variable=pkgdatadir], [$libprojectM_PKG],
+ [projectM data-directory for presets etc. (e.g. /usr/share/projectM)])
+# check if we need the c-wrapper
+if [[ "$libprojectM_VERSION_MAJOR" -ge 1 ]]; then
+ libprojectM_NEEDS_CWRAPPER=yes
+else
+ libprojectM_NEEDS_CWRAPPER=no
+fi
+AC_SUBST_COMMENT(PROJECTM_CWRAPPER, $libprojectM_NEEDS_CWRAPPER)
+
+# find portaudio
+PKG_HAVE([portaudio], [portaudio-2.0], yes)
+PKG_VERSION([portaudio], [portaudio-2.0])
+AC_SUBST_DEFINE(HAVE_PORTAUDIO, $portaudio_HAVE)
+# find portmixer
+PKG_HAVE([portmixer], [portmixer], no)
+AC_SUBST_DEFINE(HAVE_PORTMIXER, $portmixer_HAVE)
+
+# determine linker-flags
+#LDFLAGS=
+#LIBS=
+AC_SUBST(LDFLAGS)
+AC_SUBST(LIBS)
+
+# -----------------------------------------
+# create output files
+# -----------------------------------------
+
+AC_CONFIG_FILES([config-$FPC_PLATFORM.inc:config.inc.in])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([$usdxroot/Tools/ResourceExtractor/Makefile])
+if [[ x$libprojectM_NEEDS_CWRAPPER = xyes ]]; then
+ AC_CONFIG_FILES([lib/projectM/cwrapper/Makefile])
+fi
+AC_OUTPUT
+
+# -----------------------------------------
+# show results
+# -----------------------------------------
+
+AC_MSG_NOTICE([
+
+!!!
+!!! Configuration of $PACKAGE_NAME $PACKAGE_VERSION done!
+!!!
+!!! Type "make" to compile and
+!!! "make install" to install it afterwards.
+!!!
+!!! For further information on $PACKAGE_NAME visit:
+!!! $PACKAGE_WEBSITE
+!!!
+!!! IMPORTANT:
+!!! This is an UNSUPPORTED ALPHA release for developers only.
+!!!
+!!! DO NOT EXPECT THE MAKEFILE OR THE PROGRAM ITSELF TO WORK
+!!!
+!!! If you want to contribute, visit the IRC-Channel instead:
+!!! $PACKAGE_IRC
+!!!
+!!! PLEASE DO NOT SEND BUGREPORTS FOR THIS VERSION.
+!!!
+])
+
+# TODO: insert this in the public beta release
+#!!! In case you find a bug send a bugreport to:
+#!!! $PACKAGE_BUGREPORT
+#!!! You might as well ask for help at the IRC-Channel
+#!!! $PACKAGE_IRC
+
+
diff --git a/src/developer_changelog.txt b/src/developer_changelog.txt
new file mode 100644
index 00000000..47a38aa1
--- /dev/null
+++ b/src/developer_changelog.txt
@@ -0,0 +1,10 @@
+Basic functionalty change log...
+------------------------------------------------------------------------------------
+developers, please update this document with functional changes
+( that have an effect on the user )
+so the packager can easily see whats been changed when doing a release changelog.
+------------------------------------------------------------------------------------
+
+
+2007-Sep-05 JayBinks Ultrastar-DX now has basic navigation compatibility with Windows Media Center Remote controls ( and possibly others ).
+ ( Requires SDL.dll version 1.2 at shipping )
\ No newline at end of file
diff --git a/src/install-sh b/src/install-sh
new file mode 100755
index 00000000..a5897de6
--- /dev/null
+++ b/src/install-sh
@@ -0,0 +1,519 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-12-25.00
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/src/lazres-UltraStar.bat b/src/lazres-UltraStar.bat
new file mode 100644
index 00000000..39fc6a06
--- /dev/null
+++ b/src/lazres-UltraStar.bat
@@ -0,0 +1,2 @@
+C:\lazarus\tools\lazres.exe UltraStar.lrs "..\Fonts\Normal\eurostar_regular.png" "..\Fonts\Normal\eurostar_regular.dat" "..\Fonts\Bold\eurostar_regular_bold.png" "..\Fonts\Bold\eurostar_regular_bold.dat" "..\Fonts\Outline 1\Outline 1.PNG" "..\Fonts\Outline 1\Outline 1.dat" "..\Fonts\Outline 2\Outline 2.PNG" "..\Fonts\Outline 2\Outline 2.dat" "..\Graphics\ustar-icon_v01.ico" "..\Graphics\credits_v5_bg.png" "..\Graphics\credits_v5_overlay.png" "..\Graphics\names_blindguard.png" "..\Graphics\names_blindy.png" "..\Graphics\names_canni.png" "..\Graphics\names_commandio.png" "..\Graphics\names_lazyjoker.png" "..\Graphics\names_mog.png" "..\Graphics\names_mota.png" "..\Graphics\names_skillmaster.png" "..\Graphics\names_whiteshark.png" "..\Graphics\intro-l-01.png" "..\Graphics\intro-l-02.png" "..\Graphics\intro-l-03.png" "..\Graphics\intro-l-04.png" "..\Graphics\intro-l-05.png" "..\Graphics\intro-l-06.png" "..\Graphics\intro-l-07.png" "..\Graphics\intro-l-08.png" "..\Graphics\intro-l-09.png" "..\Graphics\outro-bg.png" "..\Graphics\outro-esc.png" "..\Graphics\outro-exit-dark.png"
+
diff --git a/src/lib/FreeImage/FreeBitmap.pas b/src/lib/FreeImage/FreeBitmap.pas
new file mode 100644
index 00000000..4e5f50a4
--- /dev/null
+++ b/src/lib/FreeImage/FreeBitmap.pas
@@ -0,0 +1,1742 @@
+unit FreeBitmap;
+
+// ==========================================================
+//
+// Delphi wrapper for FreeImage 3
+//
+// Design and implementation by
+// - Anatoliy Pulyaevskiy (xvel84@rambler.ru)
+//
+// Contributors:
+// - Enzo Costantini (enzocostantini@libero.it)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+//
+// ==========================================================
+//
+// From begining all code of this file is based on C++ wrapper to
+// FreeImage - FreeImagePlus.
+//
+// ==========================================================
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+ {$H+} // use AnsiString
+{$ENDIF}
+
+interface
+
+uses
+ SysUtils, Classes, Windows, FreeImage;
+
+type
+ { TFreeObject }
+
+ TFreeObject = class(TObject)
+ public
+ function IsValid: Boolean; virtual;
+ end;
+
+ { TFreeTag }
+
+ TFreeTag = class(TFreeObject)
+ private
+ // fields
+ FTag: PFITAG;
+
+ // getters & setters
+ function GetCount: Cardinal;
+ function GetDescription: string;
+ function GetID: Word;
+ function GetKey: string;
+ function GetLength: Cardinal;
+ function GetTagType: FREE_IMAGE_MDTYPE;
+ function GetValue: Pointer;
+ procedure SetCount(const Value: Cardinal);
+ procedure SetDescription(const Value: string);
+ procedure SetID(const Value: Word);
+ procedure SetKey(const Value: string);
+ procedure SetLength(const Value: Cardinal);
+ procedure SetTagType(const Value: FREE_IMAGE_MDTYPE);
+ procedure SetValue(const Value: Pointer);
+ public
+ // construction & destruction
+ constructor Create(ATag: PFITAG = nil); virtual;
+ destructor Destroy; override;
+
+ // methods
+ function Clone: TFreeTag;
+ function IsValid: Boolean; override;
+ function ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar = nil): string;
+
+ // properties
+ property Key: string read GetKey write SetKey;
+ property Description: string read GetDescription write SetDescription;
+ property ID: Word read GetID write SetID;
+ property TagType: FREE_IMAGE_MDTYPE read GetTagType write SetTagType;
+ property Count: Cardinal read GetCount write SetCount;
+ property Length: Cardinal read GetLength write SetLength;
+ property Value: Pointer read GetValue write SetValue;
+ property Tag: PFITAG read FTag;
+ end;
+
+ { forward declarations }
+
+ TFreeBitmap = class;
+ TFreeMemoryIO = class;
+
+ { TFreeBitmap }
+
+ TFreeBitmapChangingEvent = procedure(Sender: TFreeBitmap; var OldDib, NewDib: PFIBITMAP; var Handled: Boolean) of object;
+
+ TFreeBitmap = class(TFreeObject)
+ private
+ // fields
+ FDib: PFIBITMAP;
+ FOnChange: TNotifyEvent;
+ FOnChanging: TFreeBitmapChangingEvent;
+
+ procedure SetDib(Value: PFIBITMAP);
+ protected
+ function DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean; dynamic;
+ function Replace(NewDib: PFIBITMAP): Boolean; dynamic;
+ public
+ constructor Create(ImageType: FREE_IMAGE_TYPE = FIT_BITMAP; Width: Integer = 0; Height: Integer = 0; Bpp: Integer = 0);
+ destructor Destroy; override;
+ function SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height, Bpp: Integer; RedMask: Cardinal = 0; GreenMask: Cardinal = 0; BlueMask: Cardinal = 0): Boolean;
+ procedure Change; dynamic;
+ procedure Assign(Source: TFreeBitmap);
+ function CopySubImage(Left, Top, Right, Bottom: Integer; Dest: TFreeBitmap): Boolean;
+ function PasteSubImage(Src: TFreeBitmap; Left, Top: Integer; Alpha: Integer = 256): Boolean;
+ procedure Clear; virtual;
+ function Load(const FileName: string; Flag: Integer = 0): Boolean;
+ function LoadU(const FileName: WideString; Flag: Integer = 0): Boolean;
+ function LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
+ function LoadFromMemory(MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
+ function LoadFromStream(Stream: TStream; Flag: Integer = 0): Boolean;
+ // save functions
+ function CanSave(fif: FREE_IMAGE_FORMAT): Boolean;
+ function Save(const FileName: string; Flag: Integer = 0): Boolean;
+ function SaveU(const FileName: WideString; Flag: Integer = 0): Boolean;
+ function SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
+ function SaveToMemory(fif: FREE_IMAGE_FORMAT; MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
+ function SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream; Flag: Integer = 0): Boolean;
+ // image information
+ function GetImageType: FREE_IMAGE_TYPE;
+ function GetWidth: Integer;
+ function GetHeight: Integer;
+ function GetScanWidth: Integer;
+ function IsValid: Boolean; override;
+ function GetInfo: PBitmapInfo;
+ function GetInfoHeader: PBitmapInfoHeader;
+ function GetImageSize: Cardinal;
+ function GetBitsPerPixel: Integer;
+ function GetLine: Integer;
+ function GetHorizontalResolution: Double;
+ function GetVerticalResolution: Double;
+ procedure SetHorizontalResolution(Value: Double);
+ procedure SetVerticalResolution(Value: Double);
+ // palette operations
+ function GetPalette: PRGBQUAD;
+ function GetPaletteSize: Integer;
+ function GetColorsUsed: Integer;
+ function GetColorType: FREE_IMAGE_COLOR_TYPE;
+ function IsGrayScale: Boolean;
+ // pixels access
+ function AccessPixels: PByte;
+ function GetScanLine(ScanLine: Integer): PByte;
+ function GetPixelIndex(X, Y: Cardinal; var Value: PByte): Boolean;
+ function GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
+ function SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean;
+ function SetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
+ // convertion
+ function ConvertToStandardType(ScaleLinear: Boolean): Boolean;
+ function ConvertToType(ImageType: FREE_IMAGE_TYPE; ScaleLinear: Boolean): Boolean;
+ function Threshold(T: Byte): Boolean;
+ function ConvertTo4Bits: Boolean;
+ function ConvertTo8Bits: Boolean;
+ function ConvertTo16Bits555: Boolean;
+ function ConvertTo16Bits565: Boolean;
+ function ConvertTo24Bits: Boolean;
+ function ConvertTo32Bits: Boolean;
+ function ConvertToGrayscale: Boolean;
+ function ColorQuantize(Algorithm: FREE_IMAGE_QUANTIZE): Boolean;
+ function Dither(Algorithm: FREE_IMAGE_DITHER): Boolean;
+ function ConvertToRGBF: Boolean;
+ function ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam, SecondParam: Double): Boolean;
+ // transparency
+ function IsTransparent: Boolean;
+ function GetTransparencyCount: Cardinal;
+ function GetTransparencyTable: PByte;
+ procedure SetTransparencyTable(Table: PByte; Count: Integer);
+ function HasFileBkColor: Boolean;
+ function GetFileBkColor(var BkColor: PRGBQuad): Boolean;
+ function SetFileBkColor(BkColor: PRGBQuad): Boolean;
+ // channel processing routines
+ function GetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+ function SetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+ function SplitChannels(RedChannel, GreenChannel, BlueChannel: TFreeBitmap): Boolean;
+ function CombineChannels(Red, Green, Blue: TFreeBitmap): Boolean;
+ // rotation and flipping
+ function RotateEx(Angle, XShift, YShift, XOrigin, YOrigin: Double; UseMask: Boolean): Boolean;
+ function Rotate(Angle: Double): Boolean;
+ function FlipHorizontal: Boolean;
+ function FlipVertical: Boolean;
+ // color manipulation routines
+ function Invert: Boolean;
+ function AdjustCurve(Lut: PByte; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+ function AdjustGamma(Gamma: Double): Boolean;
+ function AdjustBrightness(Percentage: Double): Boolean;
+ function AdjustContrast(Percentage: Double): Boolean;
+ function GetHistogram(Histo: PDWORD; Channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): Boolean;
+ // upsampling / downsampling
+ procedure MakeThumbnail(const Width, Height: Integer; DestBitmap: TFreeBitmap);
+ function Rescale(NewWidth, NewHeight: Integer; Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap = nil): Boolean;
+ // metadata routines
+ function FindFirstMetadata(Model: FREE_IMAGE_MDMODEL; var Tag: TFreeTag): PFIMETADATA;
+ function FindNextMetadata(MDHandle: PFIMETADATA; var Tag: TFreeTag): Boolean;
+ procedure FindCloseMetadata(MDHandle: PFIMETADATA);
+ function SetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; Tag: TFreeTag): Boolean;
+ function GetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; var Tag: TFreeTag): Boolean;
+ function GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal;
+
+ // properties
+ property Dib: PFIBITMAP read FDib write SetDib;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property OnChanging: TFreeBitmapChangingEvent read FOnChanging write FOnChanging;
+ end;
+
+ { TFreeWinBitmap }
+
+
+ { TFreeMemoryIO }
+
+ TFreeMemoryIO = class(TFreeObject)
+ private
+ FHMem: PFIMEMORY;
+ public
+ // construction and destruction
+ constructor Create(Data: PByte = nil; SizeInBytes: DWORD = 0);
+ destructor Destroy; override;
+
+ function GetFileType: FREE_IMAGE_FORMAT;
+ function Read(fif: FREE_IMAGE_FORMAT; Flag: Integer = 0): PFIBITMAP;
+ function Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; Flag: Integer = 0): Boolean;
+ function Tell: Longint;
+ function Seek(Offset: Longint; Origin: Word): Boolean;
+ function Acquire(var Data: PByte; var SizeInBytes: DWORD): Boolean;
+ // overriden methods
+ function IsValid: Boolean; override;
+ end;
+
+ { TFreeMultiBitmap }
+
+ TFreeMultiBitmap = class(TFreeObject)
+ private
+ FMPage: PFIMULTIBITMAP;
+ FMemoryCache: Boolean;
+ public
+ // constructor and destructor
+ constructor Create(KeepCacheInMemory: Boolean = False);
+ destructor Destroy; override;
+
+ // methods
+ function Open(const FileName: string; CreateNew, ReadOnly: Boolean; Flags: Integer = 0): Boolean;
+ function Close(Flags: Integer = 0): Boolean;
+ function GetPageCount: Integer;
+ procedure AppendPage(Bitmap: TFreeBitmap);
+ procedure InsertPage(Page: Integer; Bitmap: TFreeBitmap);
+ procedure DeletePage(Page: Integer);
+ function MovePage(Target, Source: Integer): Boolean;
+ procedure LockPage(Page: Integer; DestBitmap: TFreeBitmap);
+ procedure UnlockPage(Bitmap: TFreeBitmap; Changed: Boolean);
+ function GetLockedPageNumbers(var Pages: Integer; var Count: Integer): Boolean;
+ // overriden methods
+ function IsValid: Boolean; override;
+
+ // properties
+ // change of this property influences only on the next opening of a file
+ property MemoryCache: Boolean read FMemoryCache write FMemoryCache;
+ end;
+
+implementation
+
+const
+ ThumbSize = 150;
+
+// marker used for clipboard copy / paste
+
+procedure SetFreeImageMarker(bmih: PBitmapInfoHeader; dib: PFIBITMAP);
+begin
+ // Windows constants goes from 0L to 5L
+ // Add $FF to avoid conflicts
+ bmih.biCompression := $FF + FreeImage_GetImageType(dib);
+end;
+
+function GetFreeImageMarker(bmih: PBitmapInfoHeader): FREE_IMAGE_TYPE;
+begin
+ Result := FREE_IMAGE_TYPE(bmih.biCompression - $FF);
+end;
+
+{ TFreePersistent }
+
+function TFreeObject.IsValid: Boolean;
+begin
+ Result := False
+end;
+
+{ TFreeBitmap }
+
+function TFreeBitmap.AccessPixels: PByte;
+begin
+ Result := FreeImage_GetBits(FDib)
+end;
+
+function TFreeBitmap.AdjustBrightness(Percentage: Double): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_AdjustBrightness(FDib, Percentage);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.AdjustContrast(Percentage: Double): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_AdjustContrast(FDib, Percentage);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.AdjustCurve(Lut: PByte;
+ Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_AdjustCurve(FDib, Lut, Channel);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.AdjustGamma(Gamma: Double): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_AdjustGamma(FDib, Gamma);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+procedure TFreeBitmap.Assign(Source: TFreeBitmap);
+var
+ SourceBmp: TFreeBitmap;
+ Clone: PFIBITMAP;
+begin
+ if Source = nil then
+ begin
+ Clear;
+ Exit;
+ end;
+
+ if Source is TFreeBitmap then
+ begin
+ SourceBmp := TFreeBitmap(Source);
+ if SourceBmp <> Self then
+ begin
+ if SourceBmp.IsValid then
+ begin
+ Clone := FreeImage_Clone(SourceBmp.FDib);
+ Replace(Clone);
+ end
+ else
+ Clear;
+ end;
+ end;
+end;
+
+function TFreeBitmap.CanSave(fif: FREE_IMAGE_FORMAT): Boolean;
+var
+ ImageType: FREE_IMAGE_TYPE;
+ Bpp: Word;
+begin
+ Result := False;
+ if not IsValid then Exit;
+
+ if fif <> FIF_UNKNOWN then
+ begin
+ // check that the dib can be saved in this format
+ ImageType := FreeImage_GetImageType(FDib);
+ if ImageType = FIT_BITMAP then
+ begin
+ // standard bitmap type
+ Bpp := FreeImage_GetBPP(FDib);
+ Result := FreeImage_FIFSupportsWriting(fif)
+ and FreeImage_FIFSupportsExportBPP(fif, Bpp);
+ end
+ else // special bitmap type
+ Result := FreeImage_FIFSupportsExportType(fif, ImageType);
+ end;
+end;
+
+procedure TFreeBitmap.Change;
+begin
+ if Assigned(FOnChange) then FOnChange(Self)
+end;
+
+procedure TFreeBitmap.Clear;
+begin
+ if FDib <> nil then
+ begin
+ FreeImage_Unload(FDib);
+ FDib := nil;
+ Change;
+ end;
+end;
+
+function TFreeBitmap.ColorQuantize(
+ Algorithm: FREE_IMAGE_QUANTIZE): Boolean;
+var
+ dib8: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib8 := FreeImage_ColorQuantize(FDib, Algorithm);
+ Result := Replace(dib8);
+ end
+ else
+ Result := False;
+end;
+
+function TFreeBitmap.CombineChannels(Red, Green,
+ Blue: TFreeBitmap): Boolean;
+var
+ Width, Height: Integer;
+begin
+ if FDib = nil then
+ begin
+ Width := Red.GetWidth;
+ Height := Red.GetHeight;
+ FDib := FreeImage_Allocate(Width, Height, 24, FI_RGBA_RED_MASK,
+ FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ end;
+
+ if FDib <> nil then
+ begin
+ Result := FreeImage_SetChannel(FDib, Red.FDib, FICC_RED) and
+ FreeImage_SetChannel(FDib, Green.FDib, FICC_GREEN) and
+ FreeImage_SetChannel(FDib, Blue.FDib, FICC_BLUE);
+
+ Change
+ end
+ else
+ Result := False;
+end;
+
+function TFreeBitmap.ConvertTo16Bits555: Boolean;
+var
+ dib16_555: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib16_555 := FreeImage_ConvertTo16Bits555(FDib);
+ Result := Replace(dib16_555);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ConvertTo16Bits565: Boolean;
+var
+ dib16_565: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib16_565 := FreeImage_ConvertTo16Bits565(FDib);
+ Result := Replace(dib16_565);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ConvertTo24Bits: Boolean;
+var
+ dibRGB: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dibRGB := FreeImage_ConvertTo24Bits(FDib);
+ Result := Replace(dibRGB);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ConvertTo32Bits: Boolean;
+var
+ dib32: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib32 := FreeImage_ConvertTo32Bits(FDib);
+ Result := Replace(dib32);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ConvertTo4Bits: Boolean;
+var
+ dib4: PFIBITMAP;
+begin
+ Result := False;
+ if IsValid then
+ begin
+ dib4 := FreeImage_ConvertTo4Bits(FDib);
+ Result := Replace(dib4);
+ end;
+end;
+
+function TFreeBitmap.ConvertTo8Bits: Boolean;
+var
+ dib8: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib8 := FreeImage_ConvertTo8Bits(FDib);
+ Result := Replace(dib8);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ConvertToGrayscale: Boolean;
+var
+ dib8: PFIBITMAP;
+begin
+ Result := False;
+
+ if IsValid then
+ begin
+ dib8 := FreeImage_ConvertToGreyscale(FDib);
+ Result := Replace(dib8);
+ end
+end;
+
+function TFreeBitmap.ConvertToRGBF: Boolean;
+var
+ ImageType: FREE_IMAGE_TYPE;
+ NewDib: PFIBITMAP;
+begin
+ Result := False;
+ if not IsValid then Exit;
+
+ ImageType := GetImageType;
+
+ if (ImageType = FIT_BITMAP) then
+ begin
+ if GetBitsPerPixel < 24 then
+ if not ConvertTo24Bits then
+ Exit
+ end;
+ NewDib := FreeImage_ConvertToRGBF(FDib);
+ Result := Replace(NewDib);
+end;
+
+function TFreeBitmap.ConvertToStandardType(ScaleLinear: Boolean): Boolean;
+var
+ dibStandard: PFIBITMAP;
+begin
+ if IsValid then
+ begin
+ dibStandard := FreeImage_ConvertToStandardType(FDib, ScaleLinear);
+ Result := Replace(dibStandard);
+ end
+ else
+ Result := False;
+end;
+
+function TFreeBitmap.ConvertToType(ImageType: FREE_IMAGE_TYPE;
+ ScaleLinear: Boolean): Boolean;
+var
+ dib: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib := FreeImage_ConvertToType(FDib, ImageType, ScaleLinear);
+ Result := Replace(dib)
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.CopySubImage(Left, Top, Right, Bottom: Integer;
+ Dest: TFreeBitmap): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Dest.FDib := FreeImage_Copy(FDib, Left, Top, Right, Bottom);
+ Result := Dest.IsValid;
+ end else
+ Result := False;
+end;
+
+constructor TFreeBitmap.Create(ImageType: FREE_IMAGE_TYPE; Width, Height,
+ Bpp: Integer);
+begin
+ inherited Create;
+
+ FDib := nil;
+ if (Width > 0) and (Height > 0) and (Bpp > 0) then
+ SetSize(ImageType, Width, Height, Bpp);
+end;
+
+destructor TFreeBitmap.Destroy;
+begin
+ if FDib <> nil then
+ FreeImage_Unload(FDib);
+ inherited;
+end;
+
+function TFreeBitmap.Dither(Algorithm: FREE_IMAGE_DITHER): Boolean;
+var
+ dib: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib := FreeImage_Dither(FDib, Algorithm);
+ Result := Replace(dib);
+ end
+ else
+ Result := False;
+end;
+
+function TFreeBitmap.DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean;
+begin
+ Result := False;
+ if (OldDib <> NewDib) and Assigned(FOnChanging) then
+ FOnChanging(Self, OldDib, NewDib, Result);
+end;
+
+procedure TFreeBitmap.FindCloseMetadata(MDHandle: PFIMETADATA);
+begin
+ FreeImage_FindCloseMetadata(MDHandle);
+end;
+
+function TFreeBitmap.FindFirstMetadata(Model: FREE_IMAGE_MDMODEL;
+ var Tag: TFreeTag): PFIMETADATA;
+begin
+ Result := FreeImage_FindFirstMetadata(Model, FDib, Tag.FTag);
+end;
+
+function TFreeBitmap.FindNextMetadata(MDHandle: PFIMETADATA;
+ var Tag: TFreeTag): Boolean;
+begin
+ Result := FreeImage_FindNextMetadata(MDHandle, Tag.FTag);
+end;
+
+function TFreeBitmap.FlipHorizontal: Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_FlipHorizontal(FDib);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.FlipVertical: Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_FlipVertical(FDib);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.GetBitsPerPixel: Integer;
+begin
+ Result := FreeImage_GetBPP(FDib)
+end;
+
+function TFreeBitmap.GetChannel(Bitmap: TFreeBitmap;
+ Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Bitmap.Dib := FreeImage_GetChannel(FDib, Channel);
+ Result := Bitmap.IsValid;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.GetColorsUsed: Integer;
+begin
+ Result := FreeImage_GetColorsUsed(FDib)
+end;
+
+function TFreeBitmap.GetColorType: FREE_IMAGE_COLOR_TYPE;
+begin
+ Result := FreeImage_GetColorType(FDib);
+end;
+
+function TFreeBitmap.GetFileBkColor(var BkColor: PRGBQuad): Boolean;
+begin
+ Result := FreeImage_GetBackgroundColor(FDib, BkColor)
+end;
+
+function TFreeBitmap.GetHeight: Integer;
+begin
+ Result := FreeImage_GetHeight(FDib)
+end;
+
+function TFreeBitmap.GetHistogram(Histo: PDWORD;
+ Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+begin
+ if FDib <> nil then
+ Result := FreeImage_GetHistogram(FDib, Histo, Channel)
+ else
+ Result := False
+end;
+
+function TFreeBitmap.GetHorizontalResolution: Double;
+begin
+ Result := FreeImage_GetDotsPerMeterX(FDib) / 100
+end;
+
+function TFreeBitmap.GetImageSize: Cardinal;
+begin
+ Result := FreeImage_GetDIBSize(FDib);
+end;
+
+function TFreeBitmap.GetImageType: FREE_IMAGE_TYPE;
+begin
+ Result := FreeImage_GetImageType(FDib);
+end;
+
+function TFreeBitmap.GetInfo: PBitmapInfo;
+begin
+ Result := FreeImage_GetInfo(FDib^)
+end;
+
+function TFreeBitmap.GetInfoHeader: PBITMAPINFOHEADER;
+begin
+ Result := FreeImage_GetInfoHeader(FDib)
+end;
+
+function TFreeBitmap.GetLine: Integer;
+begin
+ Result := FreeImage_GetLine(FDib)
+end;
+
+function TFreeBitmap.GetMetadata(Model: FREE_IMAGE_MDMODEL;
+ const Key: string; var Tag: TFreeTag): Boolean;
+begin
+ Result := FreeImage_GetMetaData(Model, FDib, PChar(Key), Tag.FTag);
+end;
+
+function TFreeBitmap.GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal;
+begin
+ Result := FreeImage_GetMetadataCount(Model, FDib);
+end;
+
+function TFreeBitmap.GetPalette: PRGBQUAD;
+begin
+ Result := FreeImage_GetPalette(FDib)
+end;
+
+function TFreeBitmap.GetPaletteSize: Integer;
+begin
+ Result := FreeImage_GetColorsUsed(FDib) * SizeOf(RGBQUAD)
+end;
+
+function TFreeBitmap.GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean;
+begin
+ Result := FreeImage_GetPixelColor(FDib, X, Y, Value)
+end;
+
+function TFreeBitmap.GetPixelIndex(X, Y: Cardinal;
+ var Value: PByte): Boolean;
+begin
+ Result := FreeImage_GetPixelIndex(FDib, X, Y, Value)
+end;
+
+function TFreeBitmap.GetScanLine(ScanLine: Integer): PByte;
+var
+ H: Integer;
+begin
+ H := FreeImage_GetHeight(FDib);
+ if ScanLine < H then
+ Result := FreeImage_GetScanLine(FDib, ScanLine)
+ else
+ Result := nil;
+end;
+
+function TFreeBitmap.GetScanWidth: Integer;
+begin
+ Result := FreeImage_GetPitch(FDib)
+end;
+
+function TFreeBitmap.GetTransparencyCount: Cardinal;
+begin
+ Result := FreeImage_GetTransparencyCount(FDib)
+end;
+
+function TFreeBitmap.GetTransparencyTable: PByte;
+begin
+ Result := FreeImage_GetTransparencyTable(FDib)
+end;
+
+function TFreeBitmap.GetVerticalResolution: Double;
+begin
+ Result := FreeImage_GetDotsPerMeterY(Fdib) / 100
+end;
+
+function TFreeBitmap.GetWidth: Integer;
+begin
+ Result := FreeImage_GetWidth(FDib)
+end;
+
+function TFreeBitmap.HasFileBkColor: Boolean;
+begin
+ Result := FreeImage_HasBackgroundColor(FDib)
+end;
+
+function TFreeBitmap.Invert: Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_Invert(FDib);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.IsGrayScale: Boolean;
+begin
+ Result := (FreeImage_GetBPP(FDib) = 8)
+ and (FreeImage_GetColorType(FDib) = FIC_PALETTE);
+end;
+
+function TFreeBitmap.IsTransparent: Boolean;
+begin
+ Result := FreeImage_IsTransparent(FDib);
+end;
+
+function TFreeBitmap.IsValid: Boolean;
+begin
+ Result := FDib <> nil
+end;
+
+function TFreeBitmap.Load(const FileName: string; Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+
+ // check the file signature and get its format
+ fif := FreeImage_GetFileType(PChar(Filename), 0);
+ if fif = FIF_UNKNOWN then
+ // no signature?
+ // try to guess the file format from the file extention
+ fif := FreeImage_GetFIFFromFilename(PChar(FileName));
+
+ // check that the plugin has reading capabilities ...
+ if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then
+ begin
+ // free the previous dib
+ if FDib <> nil then
+ FreeImage_Unload(dib);
+
+ // load the file
+ FDib := FreeImage_Load(fif, PChar(FileName), Flag);
+
+ Change;
+ Result := IsValid;
+ end else
+ Result := False;
+end;
+
+function TFreeBitmap.LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle;
+ Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+ // check the file signature and get its format
+ fif := FreeImage_GetFileTypeFromHandle(IO, Handle, 16);
+ if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
+ begin
+ // free the previous dib
+ if FDib <> nil then
+ FreeImage_Unload(FDib);
+
+ // load the file
+ FDib := FreeImage_LoadFromHandle(fif, IO, Handle, Flag);
+
+ Change;
+ Result := IsValid;
+ end else
+ Result := False;
+end;
+
+function TFreeBitmap.LoadFromMemory(MemIO: TFreeMemoryIO;
+ Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+
+ // check the file signature and get its format
+ fif := MemIO.GetFileType;
+ if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
+ begin
+ // free the previous dib
+ if FDib <> nil then
+ FreeImage_Unload(FDib);
+
+ // load the file
+ FDib := MemIO.Read(fif, Flag);
+
+ Result := IsValid;
+ Change;
+ end else
+ Result := False;
+end;
+
+function TFreeBitmap.LoadFromStream(Stream: TStream;
+ Flag: Integer): Boolean;
+var
+ MemIO: TFreeMemoryIO;
+ Data: PByte;
+ MemStream: TMemoryStream;
+ Size: Cardinal;
+begin
+ Size := Stream.Size;
+
+ MemStream := TMemoryStream.Create;
+ try
+ MemStream.CopyFrom(Stream, Size);
+ Data := MemStream.Memory;
+
+ MemIO := TFreeMemoryIO.Create(Data, Size);
+ try
+ Result := LoadFromMemory(MemIO);
+ finally
+ MemIO.Free;
+ end;
+ finally
+ MemStream.Free;
+ end;
+end;
+
+function TFreeBitmap.LoadU(const FileName: WideString;
+ Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+
+ // check the file signature and get its format
+ fif := FreeImage_GetFileTypeU(PWideChar(Filename), 0);
+ if fif = FIF_UNKNOWN then
+ // no signature?
+ // try to guess the file format from the file extention
+ fif := FreeImage_GetFIFFromFilenameU(PWideChar(FileName));
+
+ // check that the plugin has reading capabilities ...
+ if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then
+ begin
+ // free the previous dib
+ if FDib <> nil then
+ FreeImage_Unload(dib);
+
+ // load the file
+ FDib := FreeImage_LoadU(fif, PWideChar(FileName), Flag);
+
+ Change;
+ Result := IsValid;
+ end else
+ Result := False;
+end;
+
+procedure TFreeBitmap.MakeThumbnail(const Width, Height: Integer;
+ DestBitmap: TFreeBitmap);
+type
+ PRGB24 = ^TRGB24;
+ TRGB24 = packed record
+ B: Byte;
+ G: Byte;
+ R: Byte;
+ end;
+var
+ x, y, ix, iy: integer;
+ x1, x2, x3: integer;
+
+ xscale, yscale: single;
+ iRed, iGrn, iBlu, iRatio: Longword;
+ p, c1, c2, c3, c4, c5: TRGB24;
+ pt, pt1: PRGB24;
+ iSrc, iDst, s1: integer;
+ i, j, r, g, b, tmpY: integer;
+
+ RowDest, RowSource, RowSourceStart: integer;
+ w, h: Integer;
+ dxmin, dymin: integer;
+ ny1, ny2, ny3: integer;
+ dx, dy: integer;
+ lutX, lutY: array of integer;
+
+ SrcBmp, DestBmp: PFIBITMAP;
+begin
+ if not IsValid then Exit;
+
+ if (GetWidth <= ThumbSize) and (GetHeight <= ThumbSize) then
+ begin
+ DestBitmap.Assign(Self);
+ Exit;
+ end;
+
+ w := Width;
+ h := Height;
+
+ // prepare bitmaps
+ if GetBitsPerPixel <> 24 then
+ SrcBmp := FreeImage_ConvertTo24Bits(FDib)
+ else
+ SrcBmp := FDib;
+ DestBmp := FreeImage_Allocate(w, h, 24);
+ Assert(DestBmp <> nil, 'TFreeBitmap.MakeThumbnail error');
+
+{ iDst := (w * 24 + 31) and not 31;
+ iDst := iDst div 8; //BytesPerScanline
+ iSrc := (GetWidth * 24 + 31) and not 31;
+ iSrc := iSrc div 8;
+}
+ // BytesPerScanline
+ iDst := FreeImage_GetPitch(DestBmp);
+ iSrc := FreeImage_GetPitch(SrcBmp);
+
+ xscale := 1 / (w / FreeImage_GetWidth(SrcBmp));
+ yscale := 1 / (h / FreeImage_GetHeight(SrcBmp));
+
+ // X lookup table
+ SetLength(lutX, w);
+ x1 := 0;
+ x2 := trunc(xscale);
+ for x := 0 to w - 1 do
+ begin
+ lutX[x] := x2 - x1;
+ x1 := x2;
+ x2 := trunc((x + 2) * xscale);
+ end;
+
+ // Y lookup table
+ SetLength(lutY, h);
+ x1 := 0;
+ x2 := trunc(yscale);
+ for x := 0 to h - 1 do
+ begin
+ lutY[x] := x2 - x1;
+ x1 := x2;
+ x2 := trunc((x + 2) * yscale);
+ end;
+
+ Dec(w);
+ Dec(h);
+ RowDest := integer(FreeImage_GetScanLine(DestBmp, 0));
+ RowSourceStart := integer(FreeImage_GetScanLine(SrcBmp, 0));
+ RowSource := RowSourceStart;
+
+ for y := 0 to h do
+ // resampling
+ begin
+ dy := lutY[y];
+ x1 := 0;
+ x3 := 0;
+ for x := 0 to w do // loop through row
+ begin
+ dx:= lutX[x];
+ iRed:= 0;
+ iGrn:= 0;
+ iBlu:= 0;
+ RowSource := RowSourceStart;
+ for iy := 1 to dy do
+ begin
+ pt := PRGB24(RowSource + x1);
+ for ix := 1 to dx do
+ begin
+ iRed := iRed + pt.R;
+ iGrn := iGrn + pt.G;
+ iBlu := iBlu + pt.B;
+ inc(pt);
+ end;
+ RowSource := RowSource + iSrc;
+ end;
+ iRatio := 65535 div (dx * dy);
+ pt1 := PRGB24(RowDest + x3);
+ pt1.R := (iRed * iRatio) shr 16;
+ pt1.G := (iGrn * iRatio) shr 16;
+ pt1.B := (iBlu * iRatio) shr 16;
+ x1 := x1 + 3 * dx;
+ inc(x3,3);
+ end;
+ RowDest := RowDest + iDst;
+ RowSourceStart := RowSource;
+ end; // resampling
+
+ if FreeImage_GetHeight(DestBmp) >= 3 then
+ // Sharpening...
+ begin
+ s1 := integer(FreeImage_GetScanLine(DestBmp, 0));
+ iDst := integer(FreeImage_GetScanLine(DestBmp, 1)) - s1;
+ ny1 := Integer(s1);
+ ny2 := ny1 + iDst;
+ ny3 := ny2 + iDst;
+ for y := 1 to FreeImage_GetHeight(DestBmp) - 2 do
+ begin
+ for x := 0 to FreeImage_GetWidth(DestBmp) - 3 do
+ begin
+ x1 := x * 3;
+ x2 := x1 + 3;
+ x3 := x1 + 6;
+
+ c1 := pRGB24(ny1 + x1)^;
+ c2 := pRGB24(ny1 + x3)^;
+ c3 := pRGB24(ny2 + x2)^;
+ c4 := pRGB24(ny3 + x1)^;
+ c5 := pRGB24(ny3 + x3)^;
+
+ r := (c1.R + c2.R + (c3.R * -12) + c4.R + c5.R) div -8;
+ g := (c1.G + c2.G + (c3.G * -12) + c4.G + c5.G) div -8;
+ b := (c1.B + c2.B + (c3.B * -12) + c4.B + c5.B) div -8;
+
+ if r < 0 then r := 0 else if r > 255 then r := 255;
+ if g < 0 then g := 0 else if g > 255 then g := 255;
+ if b < 0 then b := 0 else if b > 255 then b := 255;
+
+ pt1 := pRGB24(ny2 + x2);
+ pt1.R := r;
+ pt1.G := g;
+ pt1.B := b;
+ end;
+ inc(ny1, iDst);
+ inc(ny2, iDst);
+ inc(ny3, iDst);
+ end;
+ end; // sharpening
+
+ if SrcBmp <> FDib then
+ FreeImage_Unload(SrcBmp);
+ DestBitmap.Replace(DestBmp);
+end;
+
+function TFreeBitmap.PasteSubImage(Src: TFreeBitmap; Left, Top,
+ Alpha: Integer): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_Paste(FDib, Src.Dib, Left, Top, Alpha);
+ Change;
+ end else
+ Result := False;
+end;
+
+function TFreeBitmap.Replace(NewDib: PFIBITMAP): Boolean;
+begin
+ Result := False;
+ if NewDib = nil then Exit;
+
+ if not DoChanging(FDib, NewDib) and IsValid then
+ FreeImage_Unload(FDib);
+
+ FDib := NewDib;
+ Result := True;
+ Change;
+end;
+
+function TFreeBitmap.Rescale(NewWidth, NewHeight: Integer;
+ Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap): Boolean;
+var
+ Bpp: Integer;
+ DstDib: PFIBITMAP;
+begin
+ Result := False;
+
+ if FDib <> nil then
+ begin
+ Bpp := FreeImage_GetBPP(FDib);
+
+ if Bpp < 8 then
+ if not ConvertToGrayscale then Exit
+ else
+ if Bpp = 16 then
+ // convert to 24-bit
+ if not ConvertTo24Bits then Exit;
+
+ // perform upsampling / downsampling
+ DstDib := FreeImage_Rescale(FDib, NewWidth, NewHeight, Filter);
+ if Dest = nil then
+ Result := Replace(DstDib)
+ else
+ Result := Dest.Replace(DstDib)
+ end
+end;
+
+function TFreeBitmap.Rotate(Angle: Double): Boolean;
+var
+ Bpp: Integer;
+ Rotated: PFIBITMAP;
+begin
+ Result := False;
+ if IsValid then
+ begin
+ Bpp := FreeImage_GetBPP(FDib);
+ if Bpp in [1, 8, 24, 32] then
+ begin
+ Rotated := FreeImage_RotateClassic(FDib, Angle);
+ Result := Replace(Rotated);
+ end
+ end;
+end;
+
+function TFreeBitmap.RotateEx(Angle, XShift, YShift, XOrigin,
+ YOrigin: Double; UseMask: Boolean): Boolean;
+var
+ Rotated: PFIBITMAP;
+begin
+ Result := False;
+ if FDib <> nil then
+ begin
+ if FreeImage_GetBPP(FDib) >= 8 then
+ begin
+ Rotated := FreeImage_RotateEx(FDib, Angle, XShift, YShift, XOrigin, YOrigin, UseMask);
+ Result := Replace(Rotated);
+ end
+ end;
+end;
+
+function TFreeBitmap.Save(const FileName: string; Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+ Result := False;
+
+ // try to guess the file format from the file extension
+ fif := FreeImage_GetFIFFromFilename(PChar(Filename));
+ if CanSave(fif) then
+ Result := FreeImage_Save(fif, FDib, PChar(FileName), Flag);
+end;
+
+function TFreeBitmap.SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO;
+ Handle: fi_handle; Flag: Integer): Boolean;
+begin
+ Result := False;
+ if CanSave(fif) then
+ Result := FreeImage_SaveToHandle(fif, FDib, IO, Handle, Flag)
+end;
+
+function TFreeBitmap.SaveToMemory(fif: FREE_IMAGE_FORMAT;
+ MemIO: TFreeMemoryIO; Flag: Integer): Boolean;
+begin
+ Result := False;
+
+ if CanSave(fif) then
+ Result := MemIO.Write(fif, FDib, Flag)
+end;
+
+function TFreeBitmap.SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream;
+ Flag: Integer): Boolean;
+var
+ MemIO: TFreeMemoryIO;
+ Data: PByte;
+ Size: Cardinal;
+begin
+ MemIO := TFreeMemoryIO.Create;
+ try
+ Result := SaveToMemory(fif, MemIO, Flag);
+ if Result then
+ begin
+ MemIO.Acquire(Data, Size);
+ Stream.WriteBuffer(Data^, Size);
+ end;
+ finally
+ MemIO.Free;
+ end;
+end;
+
+function TFreeBitmap.SaveU(const FileName: WideString;
+ Flag: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+ Result := False;
+
+ // try to guess the file format from the file extension
+ fif := FreeImage_GetFIFFromFilenameU(PWideChar(Filename));
+ if CanSave(fif) then
+ Result := FreeImage_SaveU(fif, FDib, PWideChar(FileName), Flag);
+end;
+
+function TFreeBitmap.SetChannel(Bitmap: TFreeBitmap;
+ Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ Result := FreeImage_SetChannel(FDib, Bitmap.FDib, Channel);
+ Change;
+ end
+ else
+ Result := False
+end;
+
+procedure TFreeBitmap.SetDib(Value: PFIBITMAP);
+begin
+ Replace(Value);
+end;
+
+function TFreeBitmap.SetFileBkColor(BkColor: PRGBQuad): Boolean;
+begin
+ Result := FreeImage_SetBackgroundColor(FDib, BkColor);
+ Change;
+end;
+
+procedure TFreeBitmap.SetHorizontalResolution(Value: Double);
+begin
+ if IsValid then
+ begin
+ FreeImage_SetDotsPerMeterX(FDib, Trunc(Value * 100 + 0.5));
+ Change;
+ end;
+end;
+
+function TFreeBitmap.SetMetadata(Model: FREE_IMAGE_MDMODEL;
+ const Key: string; Tag: TFreeTag): Boolean;
+begin
+ Result := FreeImage_SetMetadata(Model, FDib, PChar(Key), Tag.Tag);
+end;
+
+function TFreeBitmap.SetPixelColor(X, Y: Cardinal;
+ Value: PRGBQUAD): Boolean;
+begin
+ Result := FreeImage_SetPixelColor(FDib, X, Y, Value);
+ Change;
+end;
+
+function TFreeBitmap.SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean;
+begin
+ Result := FreeImage_SetPixelIndex(FDib, X, Y, Value);
+ Change;
+end;
+
+function TFreeBitmap.SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height,
+ Bpp: Integer; RedMask, GreenMask, BlueMask: Cardinal): Boolean;
+var
+ Pal: PRGBQuad;
+ I: Cardinal;
+begin
+ Result := False;
+
+ if FDib <> nil then
+ FreeImage_Unload(FDib);
+
+ FDib := FreeImage_Allocate(Width, Height, Bpp, RedMask, GreenMask, BlueMask);
+ if FDib = nil then Exit;
+
+ if ImageType = FIT_BITMAP then
+ case Bpp of
+ 1, 4, 8:
+ begin
+ Pal := FreeImage_GetPalette(FDib);
+ for I := 0 to FreeImage_GetColorsUsed(FDib) - 1 do
+ begin
+ Pal.rgbBlue := I;
+ Pal.rgbGreen := I;
+ Pal.rgbRed := I;
+ Inc(Pal, SizeOf(RGBQUAD));
+ end;
+ end;
+ end;
+
+ Result := True;
+ Change;
+end;
+
+procedure TFreeBitmap.SetTransparencyTable(Table: PByte; Count: Integer);
+begin
+ FreeImage_SetTransparencyTable(FDib, Table, Count);
+ Change;
+end;
+
+procedure TFreeBitmap.SetVerticalResolution(Value: Double);
+begin
+ if IsValid then
+ begin
+ FreeImage_SetDotsPerMeterY(FDib, Trunc(Value * 100 + 0.5));
+ Change;
+ end;
+end;
+
+function TFreeBitmap.SplitChannels(RedChannel, GreenChannel,
+ BlueChannel: TFreeBitmap): Boolean;
+begin
+ if FDib <> nil then
+ begin
+ RedChannel.FDib := FreeImage_GetChannel(FDib, FICC_RED);
+ GreenChannel.FDib := FreeImage_GetChannel(FDib, FICC_GREEN);
+ BlueChannel.FDib := FreeImage_GetChannel(FDib, FICC_BLUE);
+ Result := RedChannel.IsValid and GreenChannel.IsValid and BlueChannel.IsValid;
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.Threshold(T: Byte): Boolean;
+var
+ dib1: PFIBITMAP;
+begin
+ if FDib <> nil then
+ begin
+ dib1 := FreeImage_Threshold(FDib, T);
+ Result := Replace(dib1);
+ end
+ else
+ Result := False
+end;
+
+function TFreeBitmap.ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam,
+ SecondParam: Double): Boolean;
+var
+ NewDib: PFIBITMAP;
+begin
+ Result := False;
+ if not IsValid then Exit;
+
+ NewDib := FreeImage_ToneMapping(Fdib, TMO, FirstParam, SecondParam);
+ Result := Replace(NewDib);
+end;
+
+
+{ TFreeMultiBitmap }
+
+procedure TFreeMultiBitmap.AppendPage(Bitmap: TFreeBitmap);
+begin
+ if IsValid then
+ FreeImage_AppendPage(FMPage, Bitmap.FDib);
+end;
+
+function TFreeMultiBitmap.Close(Flags: Integer): Boolean;
+begin
+ Result := FreeImage_CloseMultiBitmap(FMPage, Flags);
+ FMPage := nil;
+end;
+
+constructor TFreeMultiBitmap.Create(KeepCacheInMemory: Boolean);
+begin
+ inherited Create;
+ FMemoryCache := KeepCacheInMemory;
+end;
+
+procedure TFreeMultiBitmap.DeletePage(Page: Integer);
+begin
+ if IsValid then
+ FreeImage_DeletePage(FMPage, Page);
+end;
+
+destructor TFreeMultiBitmap.Destroy;
+begin
+ if FMPage <> nil then Close;
+ inherited;
+end;
+
+function TFreeMultiBitmap.GetLockedPageNumbers(var Pages,
+ Count: Integer): Boolean;
+begin
+ Result := False;
+ if not IsValid then Exit;
+ Result := FreeImage_GetLockedPageNumbers(FMPage, Pages, Count)
+end;
+
+function TFreeMultiBitmap.GetPageCount: Integer;
+begin
+ Result := 0;
+ if IsValid then
+ Result := FreeImage_GetPageCount(FMPage)
+end;
+
+procedure TFreeMultiBitmap.InsertPage(Page: Integer; Bitmap: TFreeBitmap);
+begin
+ if IsValid then
+ FreeImage_InsertPage(FMPage, Page, Bitmap.FDib);
+end;
+
+function TFreeMultiBitmap.IsValid: Boolean;
+begin
+ Result := FMPage <> nil
+end;
+
+procedure TFreeMultiBitmap.LockPage(Page: Integer; DestBitmap: TFreeBitmap);
+begin
+ if not IsValid then Exit;
+
+ if Assigned(DestBitmap) then
+ begin
+ DestBitmap.Replace(FreeImage_LockPage(FMPage, Page));
+ end;
+end;
+
+function TFreeMultiBitmap.MovePage(Target, Source: Integer): Boolean;
+begin
+ Result := False;
+ if not IsValid then Exit;
+ Result := FreeImage_MovePage(FMPage, Target, Source);
+end;
+
+function TFreeMultiBitmap.Open(const FileName: string; CreateNew,
+ ReadOnly: Boolean; Flags: Integer): Boolean;
+var
+ fif: FREE_IMAGE_FORMAT;
+begin
+ Result := False;
+
+ // try to guess the file format from the filename
+ fif := FreeImage_GetFIFFromFilename(PChar(FileName));
+
+ // check for supported file types
+ if (fif <> FIF_UNKNOWN) and (not fif in [FIF_TIFF, FIF_ICO, FIF_GIF]) then
+ Exit;
+
+ // open the stream
+ FMPage := FreeImage_OpenMultiBitmap(fif, PChar(FileName), CreateNew, ReadOnly, FMemoryCache, Flags);
+
+ Result := FMPage <> nil;
+end;
+
+procedure TFreeMultiBitmap.UnlockPage(Bitmap: TFreeBitmap;
+ Changed: Boolean);
+begin
+ if IsValid then
+ begin
+ FreeImage_UnlockPage(FMPage, Bitmap.FDib, Changed);
+ // clear the image so that it becomes invalid.
+ // don't use Bitmap.Clear method because it calls FreeImage_Unload
+ // just clear the pointer
+ Bitmap.FDib := nil;
+ Bitmap.Change;
+ end;
+end;
+
+{ TFreeMemoryIO }
+
+function TFreeMemoryIO.Acquire(var Data: PByte;
+ var SizeInBytes: DWORD): Boolean;
+begin
+ Result := FreeImage_AcquireMemory(FHMem, Data, SizeInBytes);
+end;
+
+constructor TFreeMemoryIO.Create(Data: PByte; SizeInBytes: DWORD);
+begin
+ inherited Create;
+ FHMem := FreeImage_OpenMemory(Data, SizeInBytes);
+end;
+
+destructor TFreeMemoryIO.Destroy;
+begin
+ FreeImage_CloseMemory(FHMem);
+ inherited;
+end;
+
+function TFreeMemoryIO.GetFileType: FREE_IMAGE_FORMAT;
+begin
+ Result := FreeImage_GetFileTypeFromMemory(FHMem);
+end;
+
+function TFreeMemoryIO.IsValid: Boolean;
+begin
+ Result := FHMem <> nil
+end;
+
+function TFreeMemoryIO.Read(fif: FREE_IMAGE_FORMAT;
+ Flag: Integer): PFIBITMAP;
+begin
+ Result := FreeImage_LoadFromMemory(fif, FHMem, Flag)
+end;
+
+function TFreeMemoryIO.Seek(Offset: Longint; Origin: Word): Boolean;
+begin
+ Result := FreeImage_SeekMemory(FHMem, Offset, Origin)
+end;
+
+function TFreeMemoryIO.Tell: Longint;
+begin
+ Result := FreeImage_TellMemory(FHMem)
+end;
+
+function TFreeMemoryIO.Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP;
+ Flag: Integer): Boolean;
+begin
+ Result := FreeImage_SaveToMemory(fif, dib, FHMem, Flag)
+end;
+
+{ TFreeTag }
+
+function TFreeTag.Clone: TFreeTag;
+var
+ CloneTag: PFITAG;
+begin
+ Result := nil;
+ if not IsValid then Exit;
+
+ CloneTag := FreeImage_CloneTag(FTag);
+ Result := TFreeTag.Create(CloneTag);
+end;
+
+constructor TFreeTag.Create(ATag: PFITAG);
+begin
+ inherited Create;
+
+ if ATag <> nil then
+ FTag := ATag
+ else
+ FTag := FreeImage_CreateTag;
+end;
+
+destructor TFreeTag.Destroy;
+begin
+ if IsValid then
+ FreeImage_DeleteTag(FTag);
+
+ inherited;
+end;
+
+function TFreeTag.GetCount: Cardinal;
+begin
+ Result := 0;
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagCount(FTag);
+end;
+
+function TFreeTag.GetDescription: string;
+begin
+ Result := '';
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagDescription(FTag);
+end;
+
+function TFreeTag.GetID: Word;
+begin
+ Result := 0;
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagID(FTag);
+end;
+
+function TFreeTag.GetKey: string;
+begin
+ Result := '';
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagKey(FTag);
+end;
+
+function TFreeTag.GetLength: Cardinal;
+begin
+ Result := 0;
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagLength(FTag);
+end;
+
+function TFreeTag.GetTagType: FREE_IMAGE_MDTYPE;
+begin
+ Result := FIDT_NOTYPE;
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagType(FTag);
+end;
+
+function TFreeTag.GetValue: Pointer;
+begin
+ Result := nil;
+ if not IsValid then Exit;
+
+ Result := FreeImage_GetTagValue(FTag);
+end;
+
+function TFreeTag.IsValid: Boolean;
+begin
+ Result := FTag <> nil;
+end;
+
+procedure TFreeTag.SetCount(const Value: Cardinal);
+begin
+ if IsValid then
+ FreeImage_SetTagCount(FTag, Value);
+end;
+
+procedure TFreeTag.SetDescription(const Value: string);
+begin
+ if IsValid then
+ FreeImage_SetTagDescription(FTag, PChar(Value));
+end;
+
+procedure TFreeTag.SetID(const Value: Word);
+begin
+ if IsValid then
+ FreeImage_SetTagID(FTag, Value);
+end;
+
+procedure TFreeTag.SetKey(const Value: string);
+begin
+ if IsValid then
+ FreeImage_SetTagKey(FTag, PChar(Value));
+end;
+
+procedure TFreeTag.SetLength(const Value: Cardinal);
+begin
+ if IsValid then
+ FreeImage_SetTagLength(FTag, Value);
+end;
+
+procedure TFreeTag.SetTagType(const Value: FREE_IMAGE_MDTYPE);
+begin
+ if IsValid then
+ FreeImage_SetTagType(FTag, Value);
+end;
+
+procedure TFreeTag.SetValue(const Value: Pointer);
+begin
+ if IsValid then
+ FreeImage_SetTagValue(FTag, Value);
+end;
+
+function TFreeTag.ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar): string;
+begin
+ Result := FreeImage_TagToString(Model, FTag, Make);
+end;
+
+end.
diff --git a/src/lib/FreeImage/FreeImage.pas b/src/lib/FreeImage/FreeImage.pas
new file mode 100644
index 00000000..de05aca1
--- /dev/null
+++ b/src/lib/FreeImage/FreeImage.pas
@@ -0,0 +1,773 @@
+unit FreeImage;
+
+{$I switches.inc}
+
+
+// ==========================================================
+// Delphi wrapper for FreeImage 3
+//
+// Design and implementation by
+// - Simon Beavis
+// - Peter Byström
+// - Anatoliy Pulyaevskiy (xvel84@rambler.ru)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+interface
+
+uses
+ {$IFDEF MSWINDOWS}
+ Windows,
+ {$ENDIF}
+ ctypes;
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+ {$PACKENUM 4} (* use 4-byte enums *)
+ {$PACKRECORDS C} (* C/C++-compatible record packing *)
+{$ELSE}
+ {$MINENUMSIZE 4} (* use 4-byte enums *)
+{$ENDIF}
+
+{$IFDEF MSWINDOWS}
+ {$DEFINE DLL_STDCALL}
+{$ELSE}
+ {$DEFINE DLL_CDECL}
+{$ENDIF}
+
+const
+{$IFDEF MSWINDOWS}
+ FIDLL = 'freeimage.dll';
+{$ENDIF}
+{$IFDEF LINUX}
+ FIDLL = 'libfreeimage.so';
+{$ENDIF}
+{$IFDEF DARWIN}
+ FIDLL = 'libfreeimage.dylib';
+{$ENDIF}
+
+{$IFNDEF MSWINDOWS}
+type
+ // define portable types for 32-bit / 64-bit OS
+ BOOL = cint32;
+ BYTE = cuint8;
+ WORD = cuint16;
+ DWORD = cuint32;
+ LONG = cint32;
+{$ENDIF}
+
+// --------------------------------------------------------------------------
+// Bitmap types -------------------------------------------------------------
+// --------------------------------------------------------------------------
+
+type
+ FIBITMAP = record
+ data : Pointer;
+ end;
+ PFIBITMAP = ^FIBITMAP;
+
+ FIMULTIBITMAP = record
+ data : Pointer;
+ end;
+ PFIMULTIBITMAP = ^FIMULTIBITMAP;
+
+// --------------------------------------------------------------------------
+// Indexes for byte arrays, masks and shifts for treating pixels as words ---
+// These coincide with the order of RGBQUAD and RGBTRIPLE -------------------
+// Little Endian (x86 / MS Windows, Linux) : BGR(A) order -------------------
+// --------------------------------------------------------------------------
+
+const
+ FI_RGBA_RED = 2;
+ FI_RGBA_GREEN = 1;
+ FI_RGBA_BLUE = 0;
+ FI_RGBA_ALPHA = 3;
+ FI_RGBA_RED_MASK = $00FF0000;
+ FI_RGBA_GREEN_MASK = $0000FF00;
+ FI_RGBA_BLUE_MASK = $000000FF;
+ FI_RGBA_ALPHA_MASK = $FF000000;
+ FI_RGBA_RED_SHIFT = 16;
+ FI_RGBA_GREEN_SHIFT = 8;
+ FI_RGBA_BLUE_SHIFT = 0;
+ FI_RGBA_ALPHA_SHIFT = 24;
+
+// --------------------------------------------------------------------------
+// The 16bit macros only include masks and shifts, --------------------------
+// since each color element is not byte aligned -----------------------------
+// --------------------------------------------------------------------------
+
+const
+ FI16_555_RED_MASK = $7C00;
+ FI16_555_GREEN_MASK = $03E0;
+ FI16_555_BLUE_MASK = $001F;
+ FI16_555_RED_SHIFT = 10;
+ FI16_555_GREEN_SHIFT = 5;
+ FI16_555_BLUE_SHIFT = 0;
+ FI16_565_RED_MASK = $F800;
+ FI16_565_GREEN_MASK = $07E0;
+ FI16_565_BLUE_MASK = $001F;
+ FI16_565_RED_SHIFT = 11;
+ FI16_565_GREEN_SHIFT = 5;
+ FI16_565_BLUE_SHIFT = 0;
+
+// --------------------------------------------------------------------------
+// ICC profile support ------------------------------------------------------
+// --------------------------------------------------------------------------
+
+const
+ FIICC_DEFAULT = $0;
+ FIICC_COLOR_IS_CMYK = $1;
+
+type
+ FIICCPROFILE = record
+ flags : WORD; // info flag
+ size : DWORD; // profile's size measured in bytes
+ data : Pointer; // points to a block of contiguous memory containing the profile
+ end;
+ PFIICCPROFILE = ^FIICCPROFILE;
+
+// --------------------------------------------------------------------------
+// Important enums ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+type
+ FREE_IMAGE_FORMAT = cint;
+ FREE_IMAGE_TYPE = cint;
+ FREE_IMAGE_COLOR_TYPE = cint;
+ FREE_IMAGE_QUANTIZE = cint;
+ FREE_IMAGE_DITHER = cint;
+ FREE_IMAGE_FILTER = cint;
+ FREE_IMAGE_COLOR_CHANNEL = cint;
+ FREE_IMAGE_MDTYPE = cint;
+ FREE_IMAGE_MDMODEL = cint;
+ FREE_IMAGE_JPEG_OPERATION = cint;
+ FREE_IMAGE_TMO = cint;
+
+const
+ // I/O image format identifiers.
+ FIF_UNKNOWN = FREE_IMAGE_FORMAT(-1);
+ FIF_BMP = FREE_IMAGE_FORMAT(0);
+ FIF_ICO = FREE_IMAGE_FORMAT(1);
+ FIF_JPEG = FREE_IMAGE_FORMAT(2);
+ FIF_JNG = FREE_IMAGE_FORMAT(3);
+ FIF_KOALA = FREE_IMAGE_FORMAT(4);
+ FIF_LBM = FREE_IMAGE_FORMAT(5);
+ FIF_IFF = FIF_LBM;
+ FIF_MNG = FREE_IMAGE_FORMAT(6);
+ FIF_PBM = FREE_IMAGE_FORMAT(7);
+ FIF_PBMRAW = FREE_IMAGE_FORMAT(8);
+ FIF_PCD = FREE_IMAGE_FORMAT(9);
+ FIF_PCX = FREE_IMAGE_FORMAT(10);
+ FIF_PGM = FREE_IMAGE_FORMAT(11);
+ FIF_PGMRAW = FREE_IMAGE_FORMAT(12);
+ FIF_PNG = FREE_IMAGE_FORMAT(13);
+ FIF_PPM = FREE_IMAGE_FORMAT(14);
+ FIF_PPMRAW = FREE_IMAGE_FORMAT(15);
+ FIF_RAS = FREE_IMAGE_FORMAT(16);
+ FIF_TARGA = FREE_IMAGE_FORMAT(17);
+ FIF_TIFF = FREE_IMAGE_FORMAT(18);
+ FIF_WBMP = FREE_IMAGE_FORMAT(19);
+ FIF_PSD = FREE_IMAGE_FORMAT(20);
+ FIF_CUT = FREE_IMAGE_FORMAT(21);
+ FIF_XBM = FREE_IMAGE_FORMAT(22);
+ FIF_XPM = FREE_IMAGE_FORMAT(23);
+ FIF_DDS = FREE_IMAGE_FORMAT(24);
+ FIF_GIF = FREE_IMAGE_FORMAT(25);
+ FIF_HDR = FREE_IMAGE_FORMAT(26);
+ FIF_FAXG3 = FREE_IMAGE_FORMAT(27);
+ FIF_SGI = FREE_IMAGE_FORMAT(28);
+
+ // Image type used in FreeImage.
+ FIT_UNKNOWN = FREE_IMAGE_TYPE(0); // unknown type
+ FIT_BITMAP = FREE_IMAGE_TYPE(1); // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
+ FIT_UINT16 = FREE_IMAGE_TYPE(2); // array of unsigned short: unsigned 16-bit
+ FIT_INT16 = FREE_IMAGE_TYPE(3); // array of short: signed 16-bit
+ FIT_UINT32 = FREE_IMAGE_TYPE(4); // array of unsigned long: unsigned 32-bit
+ FIT_INT32 = FREE_IMAGE_TYPE(5); // array of long: signed 32-bit
+ FIT_FLOAT = FREE_IMAGE_TYPE(6); // array of float: 32-bit IEEE floating point
+ FIT_DOUBLE = FREE_IMAGE_TYPE(7); // array of double: 64-bit IEEE floating point
+ FIT_COMPLEX = FREE_IMAGE_TYPE(8); // array of FICOMPLEX: 2 x 64-bit IEEE floating point
+ FIT_RGB16 = FREE_IMAGE_TYPE(9); // 48-bit RGB image: 3 x 16-bit
+ FIT_RGBA16 = FREE_IMAGE_TYPE(10); // 64-bit RGBA image: 4 x 16-bit
+ FIT_RGBF = FREE_IMAGE_TYPE(11); // 96-bit RGB float image: 3 x 32-bit IEEE floating point
+ FIT_RGBAF = FREE_IMAGE_TYPE(12); // 128-bit RGBA float image: 4 x 32-bit IEEE floating point
+
+ // Image color type used in FreeImage.
+ FIC_MINISWHITE = FREE_IMAGE_COLOR_TYPE(0); // min value is white
+ FIC_MINISBLACK = FREE_IMAGE_COLOR_TYPE(1); // min value is black
+ FIC_RGB = FREE_IMAGE_COLOR_TYPE(2); // RGB color model
+ FIC_PALETTE = FREE_IMAGE_COLOR_TYPE(3); // color map indexed
+ FIC_RGBALPHA = FREE_IMAGE_COLOR_TYPE(4); // RGB color model with alpha channel
+ FIC_CMYK = FREE_IMAGE_COLOR_TYPE(5); // CMYK color model
+
+ // Color quantization algorithms. Constants used in FreeImage_ColorQuantize.
+ FIQ_WUQUANT = FREE_IMAGE_QUANTIZE(0); // Xiaolin Wu color quantization algorithm
+ FIQ_NNQUANT = FREE_IMAGE_QUANTIZE(1); // NeuQuant neural-net quantization algorithm by Anthony Dekker
+
+ // Dithering algorithms. Constants used FreeImage_Dither.
+ FID_FS = FREE_IMAGE_DITHER(0); // Floyd & Steinberg error diffusion
+ FID_BAYER4x4 = FREE_IMAGE_DITHER(1); // Bayer ordered dispersed dot dithering (order 2 dithering matrix)
+ FID_BAYER8x8 = FREE_IMAGE_DITHER(2); // Bayer ordered dispersed dot dithering (order 3 dithering matrix)
+ FID_CLUSTER6x6 = FREE_IMAGE_DITHER(3); // Ordered clustered dot dithering (order 3 - 6x6 matrix)
+ FID_CLUSTER8x8 = FREE_IMAGE_DITHER(4); // Ordered clustered dot dithering (order 4 - 8x8 matrix)
+ FID_CLUSTER16x16 = FREE_IMAGE_DITHER(5); // Ordered clustered dot dithering (order 8 - 16x16 matrix)
+
+ // Lossless JPEG transformations Constants used in FreeImage_JPEGTransform
+ FIJPEG_OP_NONE = FREE_IMAGE_JPEG_OPERATION(0); // no transformation
+ FIJPEG_OP_FLIP_H = FREE_IMAGE_JPEG_OPERATION(1); // horizontal flip
+ FIJPEG_OP_FLIP_V = FREE_IMAGE_JPEG_OPERATION(2); // vertical flip
+ FIJPEG_OP_TRANSPOSE = FREE_IMAGE_JPEG_OPERATION(3); // transpose across UL-to-LR axis
+ FIJPEG_OP_TRANSVERSE = FREE_IMAGE_JPEG_OPERATION(4); // transpose across UR-to-LL axis
+ FIJPEG_OP_ROTATE_90 = FREE_IMAGE_JPEG_OPERATION(5); // 90-degree clockwise rotation
+ FIJPEG_OP_ROTATE_180 = FREE_IMAGE_JPEG_OPERATION(6); // 180-degree rotation
+ FIJPEG_OP_ROTATE_270 = FREE_IMAGE_JPEG_OPERATION(7); // 270-degree clockwise (or 90 ccw)
+
+ // Tone mapping operators. Constants used in FreeImage_ToneMapping.
+ FITMO_DRAGO03 = FREE_IMAGE_TMO(0); // Adaptive logarithmic mapping (F. Drago, 2003)
+ FITMO_REINHARD05 = FREE_IMAGE_TMO(1); // Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005)
+
+ // Upsampling / downsampling filters. Constants used in FreeImage_Rescale.
+ FILTER_BOX = FREE_IMAGE_FILTER(0); // Box, pulse, Fourier window, 1st order (constant) b-spline
+ FILTER_BICUBIC = FREE_IMAGE_FILTER(1); // Mitchell & Netravali's two-param cubic filter
+ FILTER_BILINEAR = FREE_IMAGE_FILTER(2); // Bilinear filter
+ FILTER_BSPLINE = FREE_IMAGE_FILTER(3); // 4th order (cubic) b-spline
+ FILTER_CATMULLROM = FREE_IMAGE_FILTER(4); // Catmull-Rom spline, Overhauser spline
+ FILTER_LANCZOS3 = FREE_IMAGE_FILTER(5); // Lanczos3 filter
+
+ // Color channels. Constants used in color manipulation routines.
+ FICC_RGB = FREE_IMAGE_COLOR_CHANNEL(0); // Use red, green and blue channels
+ FICC_RED = FREE_IMAGE_COLOR_CHANNEL(1); // Use red channel
+ FICC_GREEN = FREE_IMAGE_COLOR_CHANNEL(2); // Use green channel
+ FICC_BLUE = FREE_IMAGE_COLOR_CHANNEL(3); // Use blue channel
+ FICC_ALPHA = FREE_IMAGE_COLOR_CHANNEL(4); // Use alpha channel
+ FICC_BLACK = FREE_IMAGE_COLOR_CHANNEL(5); // Use black channel
+ FICC_REAL = FREE_IMAGE_COLOR_CHANNEL(6); // Complex images: use real part
+ FICC_IMAG = FREE_IMAGE_COLOR_CHANNEL(7); // Complex images: use imaginary part
+ FICC_MAG = FREE_IMAGE_COLOR_CHANNEL(8); // Complex images: use magnitude
+ FICC_PHASE = FREE_IMAGE_COLOR_CHANNEL(9); // Complex images: use phase
+
+ // Tag data type information (based on TIFF specifications)
+ FIDT_NOTYPE = FREE_IMAGE_MDTYPE(0); // placeholder
+ FIDT_BYTE = FREE_IMAGE_MDTYPE(1); // 8-bit unsigned integer
+ FIDT_ASCII = FREE_IMAGE_MDTYPE(2); // 8-bit bytes w/ last byte null
+ FIDT_SHORT = FREE_IMAGE_MDTYPE(3); // 16-bit unsigned integer
+ FIDT_LONG = FREE_IMAGE_MDTYPE(4); // 32-bit unsigned integer
+ FIDT_RATIONAL = FREE_IMAGE_MDTYPE(5); // 64-bit unsigned fraction
+ FIDT_SBYTE = FREE_IMAGE_MDTYPE(6); // 8-bit signed integer
+ FIDT_UNDEFINED = FREE_IMAGE_MDTYPE(7); // 8-bit untyped data
+ FIDT_SSHORT = FREE_IMAGE_MDTYPE(8); // 16-bit signed integer
+ FIDT_SLONG = FREE_IMAGE_MDTYPE(9); // 32-bit signed integer
+ FIDT_SRATIONAL = FREE_IMAGE_MDTYPE(10); // 64-bit signed fraction
+ FIDT_FLOAT = FREE_IMAGE_MDTYPE(11); // 32-bit IEEE floating point
+ FIDT_DOUBLE = FREE_IMAGE_MDTYPE(12); // 64-bit IEEE floating point
+ FIDT_IFD = FREE_IMAGE_MDTYPE(13); // 32-bit unsigned integer (offset)
+ FIDT_PALETTE = FREE_IMAGE_MDTYPE(14); // 32-bit RGBQUAD
+
+ // Metadata models supported by FreeImage
+ FIMD_NODATA = FREE_IMAGE_MDMODEL(-1);
+ FIMD_COMMENTS = FREE_IMAGE_MDMODEL(0); // single comment or keywords
+ FIMD_EXIF_MAIN = FREE_IMAGE_MDMODEL(1); // Exif-TIFF metadata
+ FIMD_EXIF_EXIF = FREE_IMAGE_MDMODEL(2); // Exif-specific metadata
+ FIMD_EXIF_GPS = FREE_IMAGE_MDMODEL(3); // Exif GPS metadata
+ FIMD_EXIF_MAKERNOTE = FREE_IMAGE_MDMODEL(4); // Exif maker note metadata
+ FIMD_EXIF_INTEROP = FREE_IMAGE_MDMODEL(5); // Exif interoperability metadata
+ FIMD_IPTC = FREE_IMAGE_MDMODEL(6); // IPTC/NAA metadata
+ FIMD_XMP = FREE_IMAGE_MDMODEL(7); // Abobe XMP metadata
+ FIMD_GEOTIFF = FREE_IMAGE_MDMODEL(8); // GeoTIFF metadata (to be implemented)
+ FIMD_ANIMATION = FREE_IMAGE_MDMODEL(9); // Animation metadata
+ FIMD_CUSTOM = FREE_IMAGE_MDMODEL(10); // Used to attach other metadata types to a dib
+
+//{$endif}
+
+type
+ // Handle to a metadata model
+ FIMETADATA = record
+ data: Pointer;
+ end;
+ PFIMETADATA = ^FIMETADATA;
+
+ // Handle to a metadata tag
+ FITAG = record
+ data: Pointer;
+ end;
+ PFITAG = ^FITAG;
+
+// --------------------------------------------------------------------------
+// File IO routines ---------------------------------------------------------
+// --------------------------------------------------------------------------
+
+type
+ FI_Handle = Pointer;
+
+ FI_ReadProc = function(buffer : pointer; size : cuint; count : cuint; handle : fi_handle) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_WriteProc = function(buffer : pointer; size, count : cuint; handle : FI_Handle) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_SeekProc = function(handle : fi_handle; offset : clong; origin : cint) : cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_TellProc = function(handle : fi_handle) : clong; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+
+ FreeImageIO = packed record
+ read_proc : FI_ReadProc; // pointer to the function used to read data
+ write_proc: FI_WriteProc; // pointer to the function used to write data
+ seek_proc : FI_SeekProc; // pointer to the function used to seek
+ tell_proc : FI_TellProc; // pointer to the function used to aquire the current position
+ end;
+ PFreeImageIO = ^FreeImageIO;
+
+ // Handle to a memory I/O stream
+ FIMEMORY = record
+ data: Pointer;
+ end;
+ PFIMEMORY = ^FIMEMORY;
+
+const
+ // constants used in FreeImage_Seek for Origin parameter
+ SEEK_SET = 0;
+ SEEK_CUR = 1;
+ SEEK_END = 2;
+
+// --------------------------------------------------------------------------
+// Plugin routines ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+type
+ PPluginStruct = ^PluginStruct;
+
+ FI_InitProc = procedure(Plugin: PPluginStruct; Format_ID: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_FormatProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_DescriptionProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_ExtensionListProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_RegExprProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_OpenProc = function(IO: PFreeImageIO; Handle: FI_Handle; Read: BOOL): Pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_CloseProc = procedure(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_PageCountProc = function(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_PageCapabilityProc = function(IO: PFreeImageIO; Handle: FI_Handle; Data: Pointer): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_LoadProc = function(IO: PFreeImageIO; Handle: FI_Handle; Page, Flags: cint; data: pointer): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_SaveProc = function(IO: PFreeImageIO; Dib: PFIBITMAP; Handle: FI_Handle; Page, Flags: cint; Data: Pointer): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_ValidateProc = function(IO: PFreeImageIO; Handle: FI_Handle): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_MimeProc = function: PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_SupportsExportBPPProc = function(Bpp: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_SupportsExportTypeProc = function(AType: FREE_IMAGE_TYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+ FI_SupportsICCProfilesProc = function: BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+
+ PluginStruct = record
+ format_proc: FI_FormatProc;
+ description_proc: FI_DescriptionProc;
+ extension_proc: FI_ExtensionListProc;
+ regexpr_proc: FI_RegExprProc;
+ open_proc: FI_OpenProc;
+ close_proc: FI_CloseProc;
+ pagecount_proc: FI_PageCountProc;
+ pagecapability_proc: FI_PageCapabilityProc;
+ load_proc: FI_LoadProc;
+ save_proc: FI_SaveProc;
+ validate_proc: FI_ValidateProc;
+ mime_proc: FI_MimeProc;
+ supports_export_bpp_proc: FI_SupportsExportBPPProc;
+ supports_export_type_proc: FI_SupportsExportTypeProc;
+ supports_icc_profiles_proc: FI_SupportsICCProfilesProc;
+ end;
+
+// --------------------------------------------------------------------------
+// Load/Save flag constants -------------------------------------------------
+// --------------------------------------------------------------------------
+
+const
+ BMP_DEFAULT = 0;
+ BMP_SAVE_RLE = 1;
+ CUT_DEFAULT = 0;
+ DDS_DEFAULT = 0;
+ FAXG3_DEFAULT = 0;
+ GIF_DEFAULT = 0;
+ ICO_DEFAULT = 0;
+ ICO_MAKEALPHA = 0; // convert to 32bpp and create an alpha channel from the AND-mask when loading
+ IFF_DEFAULT = 0;
+ JPEG_DEFAULT = 0;
+ JPEG_FAST = 1;
+ JPEG_ACCURATE = 2;
+ JPEG_QUALITYSUPERB = $0080;
+ JPEG_QUALITYGOOD = $0100;
+ JPEG_QUALITYNORMAL = $0200;
+ JPEG_QUALITYAVERAGE = $0400;
+ JPEG_QUALITYBAD = $0800;
+ JPEG_CMYK = $1000; // load separated CMYK "as is" (use | to combine with other flags)
+ KOALA_DEFAULT = 0;
+ LBM_DEFAULT = 0;
+ MNG_DEFAULT = 0;
+ PCD_DEFAULT = 0;
+ PCD_BASE = 1; // load the bitmap sized 768 x 512
+ PCD_BASEDIV4 = 2; // load the bitmap sized 384 x 256
+ PCD_BASEDIV16 = 3; // load the bitmap sized 192 x 128
+ PCX_DEFAULT = 0;
+ PNG_DEFAULT = 0;
+ PNG_IGNOREGAMMA = 1; // avoid gamma correction
+ PNM_DEFAULT = 0;
+ PNM_SAVE_RAW = 0; // If set the writer saves in RAW format (i.e. P4, P5 or P6)
+ PNM_SAVE_ASCII = 1; // If set the writer saves in ASCII format (i.e. P1, P2 or P3)
+ PSD_DEFAULT = 0;
+ RAS_DEFAULT = 0;
+ SGI_DEFAULT = 0;
+ TARGA_DEFAULT = 0;
+ TARGA_LOAD_RGB888 = 1; // If set the loader converts RGB555 and ARGB8888 -> RGB888.
+ TIFF_DEFAULT = 0;
+ TIFF_CMYK = $0001; // reads/stores tags for separated CMYK (use | to combine with compression flags)
+ TIFF_PACKBITS = $0100; // save using PACKBITS compression
+ TIFF_DEFLATE = $0200; // save using DEFLATE compression
+ TIFF_ADOBE_DEFLATE = $0400; // save using ADOBE DEFLATE compression
+ TIFF_NONE = $0800; // save without any compression
+ TIFF_CCITTFAX = $1000; // save using CCITT Group 3 fax encoding
+ TIFF_CCITTFAX4 = $2000; // save using CCITT Group 4 fax encoding
+ TIFF_LZW = $4000; // save using LZW compression
+ TIFF_JPEG = $8000; // save using JPEG compression
+ WBMP_DEFAULT = 0;
+ XBM_DEFAULT = 0;
+ XPM_DEFAULT = 0;
+
+// --------------------------------------------------------------------------
+// Init/Error routines ------------------------------------------------------
+// --------------------------------------------------------------------------
+
+procedure FreeImage_Initialise(load_local_plugins_only : BOOL = False); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_DeInitialise; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Version routines ---------------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetVersion : PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetCopyrightMessage : PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Message output functions -------------------------------------------------
+// --------------------------------------------------------------------------
+
+procedure FreeImage_OutPutMessageProc(fif: cint; fmt: PChar); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+type FreeImage_OutputMessageFunction = function(fif: FREE_IMAGE_FORMAT; msg: PChar): pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF}
+procedure FreeImage_SetOutputMessage(omf: FreeImage_OutputMessageFunction); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Allocate/Unload routines -------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_Allocate(width, height, bpp: cint; red_mask: cuint = 0; green_mask: cuint = 0; blue_mask: cuint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_AllocateT(Atype: FREE_IMAGE_TYPE; Width, Height: cint; bpp: cint = 8; red_mask: cuint = 0; green_mask: cuint = 0; blue_mask: cuint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Clone(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_Unload(dib: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Load / Save routines -----------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_Load(fif: FREE_IMAGE_FORMAT; const filename: PChar; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LoadU(fif: FREE_IMAGE_FORMAT; const filename: PWideChar; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LoadFromHandle(fif: FREE_IMAGE_FORMAT; io: PFreeImageIO; handle: fi_handle; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Save(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; filename: PChar; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SaveU(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; const filename: PWideChar; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SaveToHandle(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; io : PFreeImageIO; handle : fi_handle; flags : cint = 0) : BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Memory I/O stream routines -----------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_OpenMemory(data: PByte = nil; size_in_bytes: DWORD = 0): PFIMEMORY; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_CloseMemory(stream: PFIMEMORY); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LoadFromMemory(fif: FREE_IMAGE_FORMAT; stream: PFIMEMORY; flags: cint = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SaveToMemory(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; stream: PFIMEMORY; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_TellMemory(stream: PFIMEMORY): clong; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SeekMemory(stream: PFIMEMORY; offset: clong; origin: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_AcquireMemory(stream: PFIMEMORY; var data: PByte; var size_in_bytes: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Plugin Interface ---------------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_RegisterLocalPlugin(proc_address: FI_InitProc; format, description, extension, regexpr: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_RegisterExternalPlugin(path, format, description, extension, regexpr: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFCount: cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_SetPluginEnabled(fif: FREE_IMAGE_FORMAT; enable: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_IsPluginEnabled(fif: FREE_IMAGE_FORMAT): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFFromFormat(const format: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFFromMime(const format: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFormatFromFIF(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFExtensionList(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFDescription(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFRegExpr(fif: FREE_IMAGE_FORMAT): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFFromFilename(const fname: PChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFIFFromFilenameU(const fname:PWideChar): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FIFSupportsReading(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FIFSupportsWriting(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FIFSupportsExportBPP(fif: FREE_IMAGE_FORMAT; bpp: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FIFSupportsICCProfiles(fif: FREE_IMAGE_FORMAT): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FIFSupportsExportType(fif: FREE_IMAGE_FORMAT; image_type: FREE_IMAGE_TYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Multipaging interface ----------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_OpenMultiBitmap(fif: FREE_IMAGE_FORMAT; filename: PChar; create_new, read_only, keep_cache_in_memory: BOOL; flags: cint = 0): PFIMULTIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_CloseMultiBitmap(bitmap: PFIMULTIBITMAP; flags: cint = 0): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetPageCount(bitmap: PFIMULTIBITMAP): cint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_AppendPage(bitmap: PFIMULTIBITMAP; data: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_InsertPage(bitmap: PFIMULTIBITMAP; page: cint; data: PFIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_DeletePage(bitmap: PFIMULTIBITMAP; page: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LockPage(bitmap: PFIMULTIBITMAP; page: cint): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_UnlockPage(bitmap: PFIMULTIBITMAP; page: PFIBITMAP; changed: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_MovePage(bitmap: PFIMULTIBITMAP; target, source: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetLockedPageNumbers(bitmap: PFIMULTIBITMAP; var pages: cint; var count : cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Filetype request routines ------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetFileType(const filename: PChar; size: cint): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFileTypeU(const filename: PWideChar; size: cint): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFileTypeFromHandle(io: PFreeImageIO; handle: FI_Handle; size: cint = 0): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetFileTypeFromMemory(stream: PFIMEMORY; size: cint = 0): FREE_IMAGE_FORMAT; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// ImageType request routine ------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetImageType(dib: PFIBITMAP): FREE_IMAGE_TYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// FreeImage helper routines ------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_IsLittleEndian: BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LookupX11Color(const szColor: PChar; var nRed, nGreen, nBlue: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_LookupSVGColor(const szColor: PChar; var nRed, nGreen, nBlue: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Pixels access routines ---------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetBits(dib: PFIBITMAP): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetScanLine(dib: PFIBITMAP; scanline: cint): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_GetPixelIndex(dib: PFIBITMAP; X, Y: cuint; Value: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetPixelColor(dib: PFIBITMAP; X, Y: cuint; Value: PRGBQuad): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetPixelIndex(dib: PFIBITMAP; X, Y: cuint; Value: PByte): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetPixelColor(dib: PFIBITMAP; X, Y: cuint; Value: PRGBQuad): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// DIB info routines --------------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetColorsUsed(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetBPP(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetWidth(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetHeight(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetLine(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetPitch(dib : PFIBITMAP) : cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetDIBSize(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetPalette(dib: PFIBITMAP): PRGBQUAD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_GetDotsPerMeterX(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetDotsPerMeterY(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_SetDotsPerMeterX(dib: PFIBITMAP; res: cuint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_SetDotsPerMeterY(dib: PFIBITMAP; res: cuint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_GetInfoHeader(dib: PFIBITMAP): PBITMAPINFOHEADER; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetInfo(var dib: FIBITMAP): PBITMAPINFO; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetColorType(dib: PFIBITMAP): FREE_IMAGE_COLOR_TYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_GetRedMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetGreenMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetBlueMask(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_GetTransparencyCount(dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTransparencyTable(dib: PFIBITMAP): PByte; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_SetTransparent(dib: PFIBITMAP; enabled: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_SetTransparencyTable(dib: PFIBITMAP; table: PByte; count: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_IsTransparent(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_HasBackgroundColor(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetBackgroundColor(dib: PFIBITMAP; var bkcolor: PRGBQUAD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetBackgroundColor(dib: PFIBITMAP; bkcolor: PRGBQUAD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// ICC profile routines -----------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_GetICCProfile(var dib: FIBITMAP): PFIICCPROFILE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_CreateICCProfile(var dib: FIBITMAP; data: Pointer; size: clong): PFIICCPROFILE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_DestroyICCProfile(var dib : FIBITMAP); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Line conversion routines -------------------------------------------------
+// --------------------------------------------------------------------------
+
+procedure FreeImage_ConvertLine1To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine8To4(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQuad); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To4_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To4_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine24To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine32To4(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+procedure FreeImage_ConvertLine1To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine4To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To8_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To8_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine24To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine32To8(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+procedure FreeImage_ConvertLine1To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine4To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine8To16_555(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16_565_To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine24To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine32To16_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+procedure FreeImage_ConvertLine1To16_565(target, source : PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine4To16_565(target, source : PBYTE; width_in_pixels : cint; palette : PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine8To16_565(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16_555_To16_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine24To16_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine32To16_565(target, source : PBYTE; width_in_pixels : cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+procedure FreeImage_ConvertLine1To24(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine4To24(target, source : PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine8To24(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To24_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To24_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine32To24(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+procedure FreeImage_ConvertLine1To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine4To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine8To32(target, source: PBYTE; width_in_pixels: cint; palette: PRGBQUAD); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To32_555(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine16To32_565(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertLine24To32(target, source: PBYTE; width_in_pixels: cint); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Smart conversion routines ------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_ConvertTo4Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertTo8Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertToGreyscale(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertTo16Bits555(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertTo16Bits565(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertTo24Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertTo32Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ColorQuantize(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ColorQuantizeEx(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE = FIQ_WUQUANT; PaletteSize: cint = 256; ReserveSize: cint = 0; ReservePalette: PRGBQuad = nil): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Threshold(dib: PFIBITMAP; T: Byte): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Dither(dib: PFIBITMAP; algorithm: FREE_IMAGE_DITHER): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_ConvertFromRawBits(bits: PBYTE; width, height, pitch: cint; bpp, red_mask, green_mask, blue_mask: cuint; topdown: BOOL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_ConvertToRawBits(bits: PBYTE; dib: PFIBITMAP; pitch: cint; bpp, red_mask, green_mask, blue_mask: cuint; topdown: BOOL); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_ConvertToRGBF(dib: PFIBITMAP): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_ConvertToStandardType(src: PFIBITMAP; scale_linear: BOOL = True): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ConvertToType(src: PFIBITMAP; dst_type: FREE_IMAGE_TYPE; scale_linear: BOOL = True): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// tone mapping operators
+function FreeImage_ToneMapping(dib: PFIBITMAP; tmo: FREE_IMAGE_TMO; first_param: cdouble = 0; second_param: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_TmoDrago03(src: PFIBITMAP; gamma: cdouble = 2.2; exposure: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_TmoReinhard05(src: PFIBITMAP; intensity: cdouble = 0; contrast: cdouble = 0): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// ZLib interface -----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+function FreeImage_ZLibCompress(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ZLibUncompress(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_ZLibGZip(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ZLibGUnzip(target: PBYTE; target_size: DWORD; source: PBYTE; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_ZLibCRC32(crc: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Metadata routines --------------------------------------------------------
+// --------------------------------------------------------------------------
+
+// tag creation / destruction
+function FreeImage_CreateTag: PFITAG; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_DeleteTag(tag: PFITAG); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_CloneTag(tag: PFITAG): PFITAG; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// tag getters and setters
+function FreeImage_GetTagKey(tag: PFITAG): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagDescription(tag: PFITAG): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagID(tag: PFITAG): Word; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagType(tag: PFITAG): FREE_IMAGE_MDTYPE; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagCount(tag: PFITAG): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagLength(tag: PFITAG): DWORD; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetTagValue(tag: PFITAG): Pointer; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+function FreeImage_SetTagKey(tag: PFITAG; const key: PChar): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagDescription(tag: PFITAG; const description: PChar): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagID(tag: PFITAG; id: Word): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagType(tag: PFITAG; atype: FREE_IMAGE_MDTYPE): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagCount(tag: PFITAG; count: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagLength(tag: PFITAG; length: DWORD): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetTagValue(tag: PFITAG; const value: Pointer): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// iterator
+function FreeImage_FindFirstMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; var tag: PFITAG): PFIMETADATA; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FindNextMetadata(mdhandle: PFIMETADATA; var tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+procedure FreeImage_FindCloseMetadata(mdhandle: PFIMETADATA); {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// metadata setter and getter
+function FreeImage_SetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; const key: PChar; tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP; const key: PChar; var tag: PFITAG): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// helpers
+function FreeImage_GetMetadataCount(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP): cuint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// tag to C string conversion
+function FreeImage_TagToString(model: FREE_IMAGE_MDMODEL; tag: PFITAG; Make: PChar = nil): PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// --------------------------------------------------------------------------
+// Image manipulation toolkit -----------------------------------------------
+// --------------------------------------------------------------------------
+
+// rotation and flipping
+function FreeImage_RotateClassic(dib: PFIBITMAP; angle: cdouble): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_RotateEx(dib: PFIBITMAP; angle, x_shift, y_shift, x_origin, y_origin: cdouble; use_mask: BOOL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FlipHorizontal(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_FlipVertical(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_JPEGTransform(const src_file: PChar; const dst_file: PChar; operation: FREE_IMAGE_JPEG_OPERATION; perfect: BOOL = False): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// upsampling / downsampling
+function FreeImage_Rescale(dib: PFIBITMAP; dst_width, dst_height: cint; filter: FREE_IMAGE_FILTER): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_MakeThumbnail(dib: PFIBITMAP; max_pixel_size: cint; convert:BOOL = TRUE): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// color manipulation routines (point operations)
+function FreeImage_AdjustCurve(dib: PFIBITMAP; LUT: PBYTE; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_AdjustGamma(dib: PFIBITMAP; gamma: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_AdjustBrightness(dib: PFIBITMAP; percentage: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_AdjustContrast(dib: PFIBITMAP; percentage: cdouble): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Invert(dib: PFIBITMAP): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetHistogram(dib: PFIBITMAP; histo: PDWORD; channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// channel processing routines
+function FreeImage_GetChannel(dib: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetChannel(dib, dib8: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_GetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_SetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+// copy / paste / composite routines
+
+function FreeImage_Copy(dib: PFIBITMAP; left, top, right, bottom: cint): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Paste(dst, src: PFIBITMAP; left, top, alpha: cint): BOOL; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+function FreeImage_Composite(fg: PFIBITMAP; useFileBkg: BOOL = False; appBkColor: PRGBQUAD = nil; bg: PFIBITMAP = nil): PFIBITMAP; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external FIDLL;
+
+{$MINENUMSIZE 1}
+implementation
+
+end.
diff --git a/src/lib/JEDI-SDL/JEDI-SDL-README.txt b/src/lib/JEDI-SDL/JEDI-SDL-README.txt
new file mode 100644
index 00000000..8e0d25f9
--- /dev/null
+++ b/src/lib/JEDI-SDL/JEDI-SDL-README.txt
@@ -0,0 +1,244 @@
+This is the based on the SDL ( http://www.libsdl.org ) headers, and has been converted, comments and all, to the Pascal unit called sdl.pas.
+Other conversions that have also been done are SDL_Mixer.h, SDL_Net.h, SDL_Image.h, SDL_ttf, SMPEG.h, SDL_sound and the SFont library,
+which are all included in this distribution.
+
+It allows you to access all the functions within the SDL libraries under Windows, Linux and FreeBSD, so you can write cross-platform games or multimedia applications.
+
+Installation Instructions
+-------------------------
+Windows - We now have a semi-automated setup under Windows ( thanks to David House and the Jedi JCL team ).
+ Once you have extracted the zip file, simply double click on the "JEDISDLWin32Installer.exe" to have the correct paths added to your respective
+ IDEs. All IDEs from Delphi 4 - 7 are supported and it also adds a link to the .CHM help file under the Tools menu.
+
+Linux - Alternatively if you use Linux or want to to manually install the paths, then make sure you read the "Getting Started.html" file ( ideal for those who are new to JEDI-SDL ) and is now included as a guide to help getting everything setup for smooth compilation.
+
+Also included is a guide of how to use Sourceforge using TortoiseCVS under Windows ( Linux guide is under development ).
+Both documents can be found in the "documentation" directory.
+
+
+Release History
+---------------
+1.0 : Yeah!! The Official v1.0 Release of JEDI-SDL!!
+ JEDI-SDL now updated to SDL v1.2.11, SDL_Image v1.2.5, SDL_Mixer v1.2.7, SDL_Net v1.2.6 & SDL_ttf v2.0.8
+ Added Improved FreePascal, TMT Pascal and GnuPascal support as well as maintaining Delphi/Kylix support.
+ Fixed Various bugs as pointed out on the JEDI-SDL mailing list.
+ Added SDL_GL_STEREO, SDL_GL_MULTISAMPLEBUFFERS, SDL_GL_MULTISAMPLESAMPLES
+
+Now works on MacOS X and a MacOS X disk image is available for download.
+
+// DLL/Shared object functions
+function SDL_LoadObject( const sofile : PChar ) : Pointer;
+
+function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer;
+
+procedure SDL_UnloadObject( handle : Pointer );
+
+//Added function to create RWops from const memory: SDL_RWFromConstMem()
+function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops;
+
+//Added support for environment variables SDL_VIDEO_WINDOW_POS and SDL_VIDEO_CENTERED on Windows
+
+ New Units :
+ -----------
+ sdl_cpuinfo.pas - ported SDL_cpuinfo.h so Now you can test for Specific CPU types.
+ sdlinput.pas - Input wrapper class
+ sdlwindow.pas - Window wrapper class
+ sdltruetypefont.pas - True Type Font wrapper class
+ tcputils.pas - SDL_Net utility functions
+ sdlweb.pas - SDL_Net Web class
+ sdlwebhttp.pas - SDL_Net http protocol wrapper class
+ sdlwebftp.pas - SDL_Net ftp protocol wrapper class
+
+ New 2D Demos :
+ --------------
+
+
+ New 3D Demos :
+ --------------
+
+
+ Other New Stuff :
+ -----------------
+
+
+
+0.5 : The JEDI-SDL project is now also set up on Sourceforge ( http://sf.net/projects/jedi-sdl/ ) so the latest code is available from there.
+ Improved FreePascal support has been added.
+ Various bug fixes as pointed out on the JEDI-SDL mailing list.
+ SDL_Mixer has been updated to version 1.2.1 and includes an Effects API.
+ Demo directories are now split into 2D and 3D related sub-directories.
+ There are now both Kylix ( K prefix ) and Delphi ( D prefix ) project groups for all the demos.
+ They can be found in Demos and the 2D and 3D directories.
+
+ New Units
+ ---------
+ SDLStreams.pas - Chris Bruner has created a wrapper that uses Streams to load BMPs
+ SDLUtils.pas - Pascal only version of some Utility functions
+ SDLi386Utils.pas - Intel Assembler versions of the SDLUtils.pas functions.
+ SDL_ttf.pas - Port of the SDL True Type font support unit.
+ SDL_Sound.pas - Port of the SDL Sound library ( untested ).
+
+ New 2D Demos :
+ --------------
+ Pan and Zoom Demo - How to Pan and Zoom an SDL surface.
+ Isometric Demo - I ported my old DelphiX isometric demo over to SDL.
+ TestTimer demo - Shows hows how to use AddTimer and RemoveTimer.
+ MpegPlayer - I have updated and improved Anders Ohlsson's CLX MPegPlayer and component and it now works
+ and installs into D4, D5, D6, D7, K1, K2 & K3.
+ Showfont - Demo to show how to us SDL_ttf.dll
+ SmpegPlayer - is a console MPEG player that use smpeg and SDL_Mixer
+
+ New 3D Demos :
+ --------------
+ DeathTruckTion 1.1 - A slightly updated version of this fully functional 3D network game.
+ TerrainDemo - Terrain demo ported from the book "OpenGL Game programming" by Hawkins and Astle.
+ TestGL - the standard SDL/OpenGL Test demo. Shows how to mix 2D and 3D rendering using OpenGL.
+ glfont - Demo to show how to us SDL_ttf with OpenGL.
+ Particle Engine - Ariel's OpenGL Particle Engine.
+ Picking - Phil Freeman's Picking Demo
+ Motion Blur - Phil Freeman's Motion Blur Demo
+ Dynamic Light - Phil Freeman's Dynamic Light Demo
+ Environment Map - Phil Freeman's Environment Map Demo
+ GLMovie - is an MPEG Player that uses OpenGL to render the movie.
+ NeHe - Quite a few more NeHe demos are now included.
+
+ New Network Demos :
+ -------------------
+ There are now 3 SDL_Net Server demos and 4 SDL_Client demos as submitted by Dean Ellis.
+
+
+Beta 4 : The JEDI-SDL home page is now located @ http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME
+ All Demos ( including OpenGL Demos ) now compile under both Kylix and Delphi.
+ I have added quite a few more OpenGL examples, we are now up to Nehe tutorial 12.
+ All OpenGL demos also show how to handle Window resizing.
+ Included an OpenGL demo called Puntos by Gustavo Maximo.
+ Ported Jan Horn's OpenGL MetaBalls and also SkyBox demo to SDL.
+ Ported Ilkka Tuomioja's OpenGL Quake 2 Model Viewer/Animator to SDL.
+ NOTE : All OpenGL demos require OpenGL12.pas which can be found at...
+ http://www.lischke-online.de/Graphics.html#OpenGL12
+ I also fixed a conversion bug to do with SDL_MustLock and also a conversion omission to do with various events.
+ Fixed a conversion bug with SDL_CDOpen ( as suggested on the mailing list ).
+ Added the GetPixel and PuxPixel functions to the SDLUtils.pas file.
+ Jason Farmer has donated SFont, a simple, yet effective Font library he converted for JEDI-SDL.
+ It contains 4 Demos show how to best use it.
+ Added TUInt8Array and PUIntArray to SDL.pas after suggestions from Matthias Thoma and Eric Grange.
+ In the file area of the JEDI-SDL mailing list ( http://groups.yahoo.com/group/JEDI-SDL/files/DTTSrc/ there
+ is a fully functional 3D network game called DeathTruckTion v1.0 written by the TNTeam that makes use of
+ JEDI-SDL and is just too big to include with this distribution but is well worth looking at as it works under Windows and Linux!
+ Gustavo Maxima is working on translating the JEDI-SDL Documentation to Spanish and Portugese.
+ The Mouse Demo has now been speeded up considerably and it is very responsive now.
+ Dean Ellis will provide steps on how to compile the demos using the Free Pascal compiler.
+ Jason Farmer and I are working on a series of Tutorials that should hopefully be out soon.
+ David Aclan has donated a SMpeg component that should work under Kylix.
+ Róbert Kisnémeth, has been hard at work, and has donated some new demos he has created with a SpriteEngine ( which he also donated ).
+ He has also donated a couple of games called BlitzBomber and Oxygene ( which uses the SpriteEngine ) and added a couple of useful
+ functions to SDLUtils.pas.
+ The Functions added are SDL_FlipV, SDL_FlipH, SDL_NewPutPixel ( assembler version ), SDL_AddPixel, SDL_SubPixel, SDL_DrawLine, SDL_AddLine,
+ SDL_SubLine, SDL_AddSurface, SDL_SubSurface, SDL_MonoSurface & SDL_TexturedSurface.
+ He has also donated a Font Blitting class and demo called SDL_MonoFonts which supports alignment like Left, Right and Center.
+ He and Thomas are also working on a GUI library.
+ Jason Farmer has donated a set of Image Filtering functions which add quite a few interesting effects. Check the SDL_Filter sub-directory for more
+ info.
+ Christian Hackbart also donated an OpenGL BlockOut clone.
+
+
+Beta 3 : I have added conversions for SDL_env.h, SDL_Mixer.h and SDL_Net.h while Matthias Thoma has added conversions for SDL_Image.h and SMPEG.h.
+ This version is also SDL version 1.2.0 compliant.
+ This release also adds demos for the SDL_Image, SDL_Mixer and SDL_Net libraries.
+ There are now also some OpenGL demos that make some use of SDL as well as a demo on how to use the Mouse with Clickable regions.
+ A conversion bug, that was pointed out by Clem Vasseur, has also been fixed.
+ There is now a mailing list that has been set up at http://groups.yahoo.com/group/JEDI-SDL/join/ so we can all learn from each other how to use
+ these libraries.
+ Demos have not been unified into single .dpr files for each demo, thus showing how you would write a crossplatform game using only 1 .dpr file.
+ There is also a documentation directory that is currently in HTML format. All code examples in the documentation have been converted to Object
+ Pascal but are untested.
+ I Also fixed a few conversion bugs which I came across while converting the documentation.
+
+Beta 2 : I have added conversions for SDL_active.h, SDL_thread.h, SDL_mutex.h and
+ SDL_error.h, Matthias Thoma has added Linux Support and JEDI compliancy so these
+ units and examples are now x-platform and x-compiler compilable.
+ I also added Tom Jones' SDLUtils.pas file;
+ Matthias also cleaned up the 2 new demos and made them work on both Linux and
+ Windows.
+
+Beta 1 : Initial Release;
+
+
+There are now 5 examples included with this JEDI-SDL distribution.
+1. Is the TestWin application, which is based on the testwin application that comes with the SDL SDK, only my version has a gui front end to the options available and has been compiled under Delphi 4.03. It should be compatible with Delphi 3.0 onwards ( though Delphi 2 compatibility has not been tested ).
+
+2. A Plasma example which was converted from one found on the Demos page of the SDL site.
+
+3. A Voxel terrain following demo, which was converted from one found on the Demos page of the SDL site. This one should be of interest to others as it shows how to handle keyboard events when using SDL.
+
+4. A Mouse handling demo that shows how to use transparency and clickable regions.
+
+5. A Space Invaders style game called Aliens which shows the use of SDL, SDL_Image and SDL_Mixer. This game shows how to handle sound, keyboards and some basic collision detection. It is a conversion of one found on the SDL Demos page.
+
+There are also 14 OpenGL demos that are based on the NeHe tutorials . The other 3 OpenGL demos are Jan Horns' OpenGL demo, A Quake 2 Model viewer that I ported and a Demo by Gustavo Maxima called Puntos.
+
+If writing your own, just make sure that the SDL.pas file is in your projects path for compiling and that the SDL.dll file is in your path when running the compiled app.
+
+Please test these units and report problems to the JEDI-SDL mailing list @ http://groups.yahoo.com/group/JEDI-SDL/ outlining steps under which the error occurred. If you convert any more demos please send them to me so that I can
+include them in the ditribution for others to learn from.
+
+Also if you are using these Units to write any games
+please let me know about it so that I can post the information to the http://www.DelphiGamer.com site.
+
+The plan is to have this unit JEDI certified at some point so that it can be included on the Delphi and Kylix CDs, so all feedback is greatly welcomed.
+
+Compilers supported Tested
+------------------- ------
+Delphi Yes
+Kylix Yes
+FreePascal Yes
+TMT Pascal compiler Not Yet.
+Virtual Pascal No
+Gnu Pascal No
+
+
+
+Credits
+-------
+Matthias Thoma for is endless help with my conversion bugs.
+Jason Farmer for donating the SFont Font Library.
+Gustavo Maximo for the Puntos OpenGL Demo and work he is doing on the documentation
+Róbert Kisnémeth for his numerous contributions
+Chris Bruner for testing under Kylix
+August Logan Bear Jr. for testing under Kylix
+Dean Ellis for FreePascal Compiler compatability testing and SDL_Net demos and testing
+David House for Windows Insaller and testing.
+Romi Kuntsman for helping out on some OpenGL issues.
+Everyone on the JEDI-SDL mailing list for their feedback and support.
+Everyone on the Delphi-JEDI mailing for answering my conversion questions.
+Tom Jones for inspiring this conversion.
+
+The JEDI-SDL Home page can be found @ http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME
+
+The JEDI-SDL source code archive can be found @ http://www.sf.net/projects/jedi-sdl/
+
+The JEDI-SDL mailing list can be found @ http://groups.yahoo.com/group/JEDI-SDL/join/
+
+The Latest Stable Release version of the JEDI-SDL.zip file can always be found on the Delphi-JEDI site
+
+The Latest Alpha/Unstable version can always be grabbed from the SourceForge CVS http://sourceforge.net/cvs/?group_id=43805
+
+
+Sincerely,
+
+
+
+Dominique Louis
+Delphi Game Developer.
+*********************************************************
+** To Do Nothing is to Collaborate with the oppressor **
+** -------------------------------------------------- **
+*********************************************************
+=========================================================
+From . . . . . . . : Dominique Louis
+Email. . . . . . . : Dominique@SavageSoftware.com.au
+Company. . . . . . : Savage Software Solutions
+Delphi Games Site. : http://www.DelphiGamer.com
+Delphi JEDI Site . : http://www.delphi-jedi.org
+=========================================================
+
diff --git a/src/lib/JEDI-SDL/OpenGL-Set8087CW.patch b/src/lib/JEDI-SDL/OpenGL-Set8087CW.patch
new file mode 100644
index 00000000..e08ca63e
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL-Set8087CW.patch
@@ -0,0 +1,16 @@
+Index: OpenGL/Pas/gl.pas
+===================================================================
+--- OpenGL/Pas/gl.pas (revision 961)
++++ OpenGL/Pas/gl.pas (working copy)
+@@ -2287,9 +2287,9 @@
+ end;
+
+ initialization
+- {$ifdef x86}
++ {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
+ Set8087CW($133F);
+- {$endif x86}
++ {$IFEND}
+
+ LoadOpenGL( GLLibName );
+
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/geometry.pas b/src/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
new file mode 100644
index 00000000..166ec811
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/geometry.pas
@@ -0,0 +1,1994 @@
+unit geometry;
+{
+ $Id: geometry.pas,v 1.1 2004/03/30 21:53:54 savage Exp $
+
+}
+
+// This unit contains many needed types, functions and procedures for
+// quaternion, vector and matrix arithmetics. It is specifically designed
+// for geometric calculations within R3 (affine vector space)
+// and R4 (homogeneous vector space).
+//
+// Note: The terms 'affine' or 'affine coordinates' are not really correct here
+// because an 'affine transformation' describes generally a transformation which leads
+// to a uniquely solvable system of equations and has nothing to do with the dimensionality
+// of a vector. One could use 'projective coordinates' but this is also not really correct
+// and since I haven't found a better name (or even any correct one), 'affine' is as good
+// as any other one.
+//
+// Identifiers containing no dimensionality (like affine or homogeneous)
+// and no datatype (integer..extended) are supposed as R4 representation
+// with 'single' floating point type (examples are TVector, TMatrix,
+// and TQuaternion). The default data type is 'single' ('GLFloat' for OpenGL)
+// and used in all routines (except conversions and trigonometric functions).
+//
+// Routines with an open array as argument can either take Func([1,2,3,4,..]) or Func(Vect).
+// The latter is prefered, since no extra stack operations is required.
+// Note: Be careful while passing open array elements! If you pass more elements
+// than there's room in the result the behaviour will be unpredictable.
+//
+// If not otherwise stated, all angles are given in radians
+// (instead of degrees). Use RadToDeg or DegToRad to convert between them.
+//
+// Geometry.pas was assembled from different sources (like GraphicGems)
+// and relevant books or based on self written code, respectivly.
+//
+// Note: Some aspects need to be considered when using Delphi and pure
+// assembler code. Delphi ensures that the direction flag is always
+// cleared while entering a function and expects it cleared on return.
+// This is in particular important in routines with (CPU) string commands (MOVSD etc.)
+// The registers EDI, ESI and EBX (as well as the stack management
+// registers EBP and ESP) must not be changed! EAX, ECX and EDX are
+// freely available and mostly used for parameter.
+//
+// Version 2.5
+// last change : 04. January 2000
+//
+// (c) Copyright 1999, Dipl. Ing. Mike Lischke (public@lischke-online.de)
+{
+ $Log: geometry.pas,v $
+ Revision 1.1 2004/03/30 21:53:54 savage
+ Moved to it's own folder.
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+type
+ // data types needed for 3D graphics calculation,
+ // included are 'C like' aliases for each type (to be
+ // conformal with OpenGL types)
+
+ PByte = ^Byte;
+ PWord = ^Word;
+ PInteger = ^Integer;
+ PFloat = ^Single;
+ PDouble = ^Double;
+ PExtended = ^Extended;
+ PPointer = ^Pointer;
+
+ // types to specify continous streams of a specific type
+ // switch off range checking to access values beyond the limits
+ PByteVector = ^TByteVector;
+ PByteArray = PByteVector;
+ TByteVector = array[0..0] of Byte;
+
+ PWordVector = ^TWordVector;
+ PWordArray = PWordVector; // note: there's a same named type in SysUtils
+ TWordVector = array[0..0] of Word;
+
+ PIntegerVector = ^TIntegerVector;
+ PIntegerArray = PIntegerVector;
+ TIntegerVector = array[0..0] of Integer;
+
+ PFloatVector = ^TFloatVector;
+ PFloatArray = PFloatVector;
+ TFloatVector = array[0..0] of Single;
+
+ PDoubleVector = ^TDoubleVector;
+ PDoubleArray = PDoubleVector;
+ TDoubleVector = array[0..0] of Double;
+
+ PExtendedVector = ^TExtendedVector;
+ PExtendedArray = PExtendedVector;
+ TExtendedVector = array[0..0] of Extended;
+
+ PPointerVector = ^TPointerVector;
+ PPointerArray = PPointerVector;
+ TPointerVector = array[0..0] of Pointer;
+
+ PCardinalVector = ^TCardinalVector;
+ PCardinalArray = PCardinalVector;
+ TCardinalVector = array[0..0] of Cardinal;
+
+ // common vector and matrix types with predefined limits
+ // indices correspond like: x -> 0
+ // y -> 1
+ // z -> 2
+ // w -> 3
+
+ PHomogeneousByteVector = ^THomogeneousByteVector;
+ THomogeneousByteVector = array[0..3] of Byte;
+ TVector4b = THomogeneousByteVector;
+
+ PHomogeneousWordVector = ^THomogeneousWordVector;
+ THomogeneousWordVector = array[0..3] of Word;
+ TVector4w = THomogeneousWordVector;
+
+ PHomogeneousIntVector = ^THomogeneousIntVector;
+ THomogeneousIntVector = array[0..3] of Integer;
+ TVector4i = THomogeneousIntVector;
+
+ PHomogeneousFltVector = ^THomogeneousFltVector;
+ THomogeneousFltVector = array[0..3] of Single;
+ TVector4f = THomogeneousFltVector;
+
+ PHomogeneousDblVector = ^THomogeneousDblVector;
+ THomogeneousDblVector = array[0..3] of Double;
+ TVector4d = THomogeneousDblVector;
+
+ PHomogeneousExtVector = ^THomogeneousExtVector;
+ THomogeneousExtVector = array[0..3] of Extended;
+ TVector4e = THomogeneousExtVector;
+
+ PHomogeneousPtrVector = ^THomogeneousPtrVector;
+ THomogeneousPtrVector = array[0..3] of Pointer;
+ TVector4p = THomogeneousPtrVector;
+
+ PAffineByteVector = ^TAffineByteVector;
+ TAffineByteVector = array[0..2] of Byte;
+ TVector3b = TAffineByteVector;
+
+ PAffineWordVector = ^TAffineWordVector;
+ TAffineWordVector = array[0..2] of Word;
+ TVector3w = TAffineWordVector;
+
+ PAffineIntVector = ^TAffineIntVector;
+ TAffineIntVector = array[0..2] of Integer;
+ TVector3i = TAffineIntVector;
+
+ PAffineFltVector = ^TAffineFltVector;
+ TAffineFltVector = array[0..2] of Single;
+ TVector3f = TAffineFltVector;
+
+ PAffineDblVector = ^TAffineDblVector;
+ TAffineDblVector = array[0..2] of Double;
+ TVector3d = TAffineDblVector;
+
+ PAffineExtVector = ^TAffineExtVector;
+ TAffineExtVector = array[0..2] of Extended;
+ TVector3e = TAffineExtVector;
+
+ PAffinePtrVector = ^TAffinePtrVector;
+ TAffinePtrVector = array[0..2] of Pointer;
+ TVector3p = TAffinePtrVector;
+
+ // some simplified names
+ PVector = ^TVector;
+ TVector = THomogeneousFltVector;
+
+ PHomogeneousVector = ^THomogeneousVector;
+ THomogeneousVector = THomogeneousFltVector;
+
+ PAffineVector = ^TAffineVector;
+ TAffineVector = TAffineFltVector;
+
+ // arrays of vectors
+ PVectorArray = ^TVectorArray;
+ TVectorArray = array[0..0] of TAffineVector;
+
+ // matrices
+ THomogeneousByteMatrix = array[0..3] of THomogeneousByteVector;
+ TMatrix4b = THomogeneousByteMatrix;
+
+ THomogeneousWordMatrix = array[0..3] of THomogeneousWordVector;
+ TMatrix4w = THomogeneousWordMatrix;
+
+ THomogeneousIntMatrix = array[0..3] of THomogeneousIntVector;
+ TMatrix4i = THomogeneousIntMatrix;
+
+ THomogeneousFltMatrix = array[0..3] of THomogeneousFltVector;
+ TMatrix4f = THomogeneousFltMatrix;
+
+ THomogeneousDblMatrix = array[0..3] of THomogeneousDblVector;
+ TMatrix4d = THomogeneousDblMatrix;
+
+ THomogeneousExtMatrix = array[0..3] of THomogeneousExtVector;
+ TMatrix4e = THomogeneousExtMatrix;
+
+ TAffineByteMatrix = array[0..2] of TAffineByteVector;
+ TMatrix3b = TAffineByteMatrix;
+
+ TAffineWordMatrix = array[0..2] of TAffineWordVector;
+ TMatrix3w = TAffineWordMatrix;
+
+ TAffineIntMatrix = array[0..2] of TAffineIntVector;
+ TMatrix3i = TAffineIntMatrix;
+
+ TAffineFltMatrix = array[0..2] of TAffineFltVector;
+ TMatrix3f = TAffineFltMatrix;
+
+ TAffineDblMatrix = array[0..2] of TAffineDblVector;
+ TMatrix3d = TAffineDblMatrix;
+
+ TAffineExtMatrix = array[0..2] of TAffineExtVector;
+ TMatrix3e = TAffineExtMatrix;
+
+ // some simplified names
+ PMatrix = ^TMatrix;
+ TMatrix = THomogeneousFltMatrix;
+
+ PHomogeneousMatrix = ^THomogeneousMatrix;
+ THomogeneousMatrix = THomogeneousFltMatrix;
+
+ PAffineMatrix = ^TAffineMatrix;
+ TAffineMatrix = TAffineFltMatrix;
+
+ // q = ([x, y, z], w)
+ TQuaternion = record
+ case Integer of
+ 0:
+ (ImagPart: TAffineVector;
+ RealPart: Single);
+ 1:
+ (Vector: TVector4f);
+ end;
+
+ TRectangle = record
+ Left,
+ Top,
+ Width,
+ Height: Integer;
+ end;
+
+ TTransType = (ttScaleX, ttScaleY, ttScaleZ,
+ ttShearXY, ttShearXZ, ttShearYZ,
+ ttRotateX, ttRotateY, ttRotateZ,
+ ttTranslateX, ttTranslateY, ttTranslateZ,
+ ttPerspectiveX, ttPerspectiveY, ttPerspectiveZ, ttPerspectiveW);
+
+ // used to describe a sequence of transformations in following order:
+ // [Sx][Sy][Sz][ShearXY][ShearXZ][ShearZY][Rx][Ry][Rz][Tx][Ty][Tz][P(x,y,z,w)]
+ // constants are declared for easier access (see MatrixDecompose below)
+ TTransformations = array[TTransType] of Single;
+
+
+const
+ // useful constants
+
+ // standard vectors
+ XVector: TAffineVector = (1, 0, 0);
+ YVector: TAffineVector = (0, 1, 0);
+ ZVector: TAffineVector = (0, 0, 1);
+ NullVector: TAffineVector = (0, 0, 0);
+
+ IdentityMatrix: TMatrix = ((1, 0, 0, 0),
+ (0, 1, 0, 0),
+ (0, 0, 1, 0),
+ (0, 0, 0, 1));
+ EmptyMatrix: TMatrix = ((0, 0, 0, 0),
+ (0, 0, 0, 0),
+ (0, 0, 0, 0),
+ (0, 0, 0, 0));
+ // some very small numbers
+ EPSILON = 1e-100;
+ EPSILON2 = 1e-50;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+// vector functions
+function VectorAdd(V1, V2: TVector): TVector;
+function VectorAffineAdd(V1, V2: TAffineVector): TAffineVector;
+function VectorAffineCombine(V1, V2: TAffineVector; F1, F2: Single): TAffineVector;
+function VectorAffineDotProduct(V1, V2: TAffineVector): Single;
+function VectorAffineLerp(V1, V2: TAffineVector; t: Single): TAffineVector;
+function VectorAffineSubtract(V1, V2: TAffineVector): TAffineVector;
+function VectorAngle(V1, V2: TAffineVector): Single;
+function VectorCombine(V1, V2: TVector; F1, F2: Single): TVector;
+function VectorCrossProduct(V1, V2: TAffineVector): TAffineVector;
+function VectorDotProduct(V1, V2: TVector): Single;
+function VectorLength(V: array of Single): Single;
+function VectorLerp(V1, V2: TVector; t: Single): TVector;
+procedure VectorNegate(V: array of Single);
+function VectorNorm(V: array of Single): Single;
+function VectorNormalize(V: array of Single): Single;
+function VectorPerpendicular(V, N: TAffineVector): TAffineVector;
+function VectorReflect(V, N: TAffineVector): TAffineVector;
+procedure VectorRotate(var Vector: TVector4f; Axis: TVector3f; Angle: Single);
+procedure VectorScale(V: array of Single; Factor: Single);
+function VectorSubtract(V1, V2: TVector): TVector;
+
+// matrix functions
+function CreateRotationMatrixX(Sine, Cosine: Single): TMatrix;
+function CreateRotationMatrixY(Sine, Cosine: Single): TMatrix;
+function CreateRotationMatrixZ(Sine, Cosine: Single): TMatrix;
+function CreateScaleMatrix(V: TAffineVector): TMatrix;
+function CreateTranslationMatrix(V: TVector): TMatrix;
+procedure MatrixAdjoint(var M: TMatrix);
+function MatrixAffineDeterminant(M: TAffineMatrix): Single;
+procedure MatrixAffineTranspose(var M: TAffineMatrix);
+function MatrixDeterminant(M: TMatrix): Single;
+procedure MatrixInvert(var M: TMatrix);
+function MatrixMultiply(M1, M2: TMatrix): TMatrix;
+procedure MatrixScale(var M: TMatrix; Factor: Single);
+procedure MatrixTranspose(var M: TMatrix);
+
+// quaternion functions
+function QuaternionConjugate(Q: TQuaternion): TQuaternion;
+function QuaternionFromPoints(V1, V2: TAffineVector): TQuaternion;
+function QuaternionMultiply(qL, qR: TQuaternion): TQuaternion;
+function QuaternionSlerp(QStart, QEnd: TQuaternion; Spin: Integer; t: Single): TQuaternion;
+function QuaternionToMatrix(Q: TQuaternion): TMatrix;
+procedure QuaternionToPoints(Q: TQuaternion; var ArcFrom, ArcTo: TAffineVector);
+
+// mixed functions
+function ConvertRotation(Angles: TAffineVector): TVector;
+function CreateRotationMatrix(Axis: TVector3f; Angle: Single): TMatrix;
+function MatrixDecompose(M: TMatrix; var Tran: TTransformations): Boolean;
+function VectorAffineTransform(V: TAffineVector; M: TAffineMatrix): TAffineVector;
+function VectorTransform(V: TVector4f; M: TMatrix): TVector4f; overload;
+function VectorTransform(V: TVector3f; M: TMatrix): TVector3f; overload;
+
+// miscellaneous functions
+function MakeAffineDblVector(V: array of Double): TAffineDblVector;
+function MakeDblVector(V: array of Double): THomogeneousDblVector;
+function MakeAffineVector(V: array of Single): TAffineVector;
+function MakeQuaternion(Imag: array of Single; Real: Single): TQuaternion;
+function MakeVector(V: array of Single): TVector;
+function PointInPolygon(xp, yp : array of Single; x, y: Single): Boolean;
+function VectorAffineDblToFlt(V: TAffineDblVector): TAffineVector;
+function VectorDblToFlt(V: THomogeneousDblVector): THomogeneousVector;
+function VectorAffineFltToDbl(V: TAffineVector): TAffineDblVector;
+function VectorFltToDbl(V: TVector): THomogeneousDblVector;
+
+// trigonometric functions
+function ArcCos(X: Extended): Extended;
+function ArcSin(X: Extended): Extended;
+function ArcTan2(Y, X: Extended): Extended;
+function CoTan(X: Extended): Extended;
+function DegToRad(Degrees: Extended): Extended;
+function RadToDeg(Radians: Extended): Extended;
+procedure SinCos(Theta: Extended; var Sin, Cos: Extended);
+function Tan(X: Extended): Extended;
+
+// coordinate system manipulation functions
+function Turn(Matrix: TMatrix; Angle: Single): TMatrix; overload;
+function Turn(Matrix: TMatrix; MasterUp: TAffineVector; Angle: Single): TMatrix; overload;
+function Pitch(Matrix: TMatrix; Angle: Single): TMatrix; overload;
+function Pitch(Matrix: TMatrix; MasterRight: TAffineVector; Angle: Single): TMatrix; overload;
+function Roll(Matrix: TMatrix; Angle: Single): TMatrix; overload;
+function Roll(Matrix: TMatrix; MasterDirection: TAffineVector; Angle: Single): TMatrix; overload;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+implementation
+
+const
+ // FPU status flags (high order byte)
+ C0 = 1;
+ C1 = 2;
+ C2 = 4;
+ C3 = $40;
+
+ // to be used as descriptive indices
+ X = 0;
+ Y = 1;
+ Z = 2;
+ W = 3;
+
+//----------------- trigonometric helper functions ---------------------------------------------------------------------
+
+function DegToRad(Degrees: Extended): Extended;
+
+begin
+ Result := Degrees * (PI / 180);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function RadToDeg(Radians: Extended): Extended;
+
+begin
+ Result := Radians * (180 / PI);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure SinCos(Theta: Extended; var Sin, Cos: Extended); assembler; register;
+
+// calculates sine and cosine from the given angle Theta
+// EAX contains address of Sin
+// EDX contains address of Cos
+// Theta is passed over the stack
+
+asm
+ FLD Theta
+ FSINCOS
+ FSTP TBYTE PTR [EDX] // cosine
+ FSTP TBYTE PTR [EAX] // sine
+ FWAIT
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function ArcCos(X: Extended): Extended;
+
+begin
+ Result := ArcTan2(Sqrt(1 - X * X), X);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function ArcSin(X: Extended): Extended;
+
+begin
+ Result := ArcTan2(X, Sqrt(1 - X * X))
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function ArcTan2(Y, X: Extended): Extended;
+
+asm
+ FLD Y
+ FLD X
+ FPATAN
+ FWAIT
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Tan(X: Extended): Extended;
+
+asm
+ FLD X
+ FPTAN
+ FSTP ST(0) // FPTAN pushes 1.0 after result
+ FWAIT
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CoTan(X: Extended): Extended;
+
+asm
+ FLD X
+ FPTAN
+ FDIVRP
+ FWAIT
+end;
+
+//----------------- miscellaneous vector functions ---------------------------------------------------------------------
+
+function MakeAffineDblVector(V: array of Double): TAffineDblVector; assembler;
+
+// creates a vector from given values
+// EAX contains address of V
+// ECX contains address to result vector
+// EDX contains highest index of V
+
+asm
+ PUSH EDI
+ PUSH ESI
+ MOV EDI, ECX
+ MOV ESI, EAX
+ MOV ECX, EDX
+ ADD ECX, 2
+ REP MOVSD
+ POP ESI
+ POP EDI
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MakeDblVector(V: array of Double): THomogeneousDblVector; assembler;
+
+// creates a vector from given values
+// EAX contains address of V
+// ECX contains address to result vector
+// EDX contains highest index of V
+
+asm
+ PUSH EDI
+ PUSH ESI
+ MOV EDI, ECX
+ MOV ESI, EAX
+ MOV ECX, EDX
+ ADD ECX, 2
+ REP MOVSD
+ POP ESI
+ POP EDI
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MakeAffineVector(V: array of Single): TAffineVector; assembler;
+
+// creates a vector from given values
+// EAX contains address of V
+// ECX contains address to result vector
+// EDX contains highest index of V
+
+asm
+ PUSH EDI
+ PUSH ESI
+ MOV EDI, ECX
+ MOV ESI, EAX
+ MOV ECX, EDX
+ INC ECX
+ CMP ECX, 3
+ JB @@1
+ MOV ECX, 3
+@@1: REP MOVSD // copy given values
+ MOV ECX, 2
+ SUB ECX, EDX // determine missing entries
+ JS @@Finish
+ XOR EAX, EAX
+ REP STOSD // set remaining fields to 0
+@@Finish: POP ESI
+ POP EDI
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MakeQuaternion(Imag: array of Single; Real: Single): TQuaternion; assembler;
+
+// creates a quaternion from the given values
+// EAX contains address of Imag
+// ECX contains address to result vector
+// EDX contains highest index of Imag
+// Real part is passed on the stack
+
+asm
+ PUSH EDI
+ PUSH ESI
+ MOV EDI, ECX
+ MOV ESI, EAX
+ MOV ECX, EDX
+ INC ECX
+ REP MOVSD
+ MOV EAX, [Real]
+ MOV [EDI], EAX
+ POP ESI
+ POP EDI
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MakeVector(V: array of Single): TVector; assembler;
+
+// creates a vector from given values
+// EAX contains address of V
+// ECX contains address to result vector
+// EDX contains highest index of V
+
+asm
+ PUSH EDI
+ PUSH ESI
+ MOV EDI, ECX
+ MOV ESI, EAX
+ MOV ECX, EDX
+ INC ECX
+ CMP ECX, 4
+ JB @@1
+ MOV ECX, 4
+@@1: REP MOVSD // copy given values
+ MOV ECX, 3
+ SUB ECX, EDX // determine missing entries
+ JS @@Finish
+ XOR EAX, EAX
+ REP STOSD // set remaining fields to 0
+@@Finish: POP ESI
+ POP EDI
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorLength(V: array of Single): Single; assembler;
+
+// calculates the length of a vector following the equation: sqrt(x * x + y * y + ...)
+// Note: The parameter of this function is declared as open array. Thus
+// there's no restriction about the number of the components of the vector.
+//
+// EAX contains address of V
+// EDX contains the highest index of V
+// the result is returned in ST(0)
+
+asm
+ FLDZ // initialize sum
+@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
+ FMUL ST, ST
+ FADDP
+ SUB EDX, 1
+ JNL @@Loop
+ FSQRT
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAngle(V1, V2: TAffineVector): Single; assembler;
+
+// calculates the cosine of the angle between Vector1 and Vector2
+// Result = DotProduct(V1, V2) / (Length(V1) * Length(V2))
+//
+// EAX contains address of Vector1
+// EDX contains address of Vector2
+
+asm
+ FLD DWORD PTR [EAX] // V1[0]
+ FLD ST // double V1[0]
+ FMUL ST, ST // V1[0]^2 (prep. for divisor)
+ FLD DWORD PTR [EDX] // V2[0]
+ FMUL ST(2), ST // ST(2) := V1[0] * V2[0]
+ FMUL ST, ST // V2[0]^2 (prep. for divisor)
+ FLD DWORD PTR [EAX + 4] // V1[1]
+ FLD ST // double V1[1]
+ FMUL ST, ST // ST(0) := V1[1]^2
+ FADDP ST(3), ST // ST(2) := V1[0]^2 + V1[1] * * 2
+ FLD DWORD PTR [EDX + 4] // V2[1]
+ FMUL ST(1), ST // ST(1) := V1[1] * V2[1]
+ FMUL ST, ST // ST(0) := V2[1]^2
+ FADDP ST(2), ST // ST(1) := V2[0]^2 + V2[1]^2
+ FADDP ST(3), ST // ST(2) := V1[0] * V2[0] + V1[1] * V2[1]
+ FLD DWORD PTR [EAX + 8] // load V2[1]
+ FLD ST // same calcs go here
+ FMUL ST, ST // (compare above)
+ FADDP ST(3), ST
+ FLD DWORD PTR [EDX + 8]
+ FMUL ST(1), ST
+ FMUL ST, ST
+ FADDP ST(2), ST
+ FADDP ST(3), ST
+ FMULP // ST(0) := (V1[0]^2 + V1[1]^2 + V1[2]) *
+ // (V2[0]^2 + V2[1]^2 + V2[2])
+ FSQRT // sqrt(ST(0))
+ FDIVP // ST(0) := Result := ST(1) / ST(0)
+ // the result is expected in ST(0), if it's invalid, an error is raised
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorNorm(V: array of Single): Single; assembler; register;
+
+// calculates norm of a vector which is defined as norm = x * x + y * y + ...
+// EAX contains address of V
+// EDX contains highest index in V
+// result is passed in ST(0)
+
+asm
+ FLDZ // initialize sum
+@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
+ FMUL ST, ST // make square
+ FADDP // add previous calculated sum
+ SUB EDX, 1
+ JNL @@Loop
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorNormalize(V: array of Single): Single; assembler; register;
+
+// transforms a vector to unit length and return length
+// EAX contains address of V
+// EDX contains the highest index in V
+// return former length of V in ST
+
+asm
+ PUSH EBX
+ MOV ECX, EDX // save size of V
+ CALL VectorLength // calculate length of vector
+ FTST // test if length = 0
+ MOV EBX, EAX // save parameter address
+ FSTSW AX // get test result
+ TEST AH, C3 // check the test result
+ JNZ @@Finish
+ SUB EBX, 4 // simplyfied address calculation
+ INC ECX
+ FLD1 // calculate reciprocal of length
+ FDIV ST, ST(1)
+@@1: FLD ST // double reciprocal
+ FMUL DWORD PTR [EBX + 4 * ECX] // scale component
+ WAIT
+ FSTP DWORD PTR [EBX + 4 * ECX] // store result
+ LOOP @@1
+ FSTP ST // remove reciprocal from FPU stack
+@@Finish: POP EBX
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineSubtract(V1, V2: TAffineVector): TAffineVector; assembler; register;
+
+// returns v1 minus v2
+// EAX contains address of V1
+// EDX contains address of V2
+// ECX contains address of the result
+
+asm
+ {Result[X] := V1[X]-V2[X];
+ Result[Y] := V1[Y]-V2[Y];
+ Result[Z] := V1[Z]-V2[Z];}
+
+ FLD DWORD PTR [EAX]
+ FSUB DWORD PTR [EDX]
+ FSTP DWORD PTR [ECX]
+ FLD DWORD PTR [EAX + 4]
+ FSUB DWORD PTR [EDX + 4]
+ FSTP DWORD PTR [ECX + 4]
+ FLD DWORD PTR [EAX + 8]
+ FSUB DWORD PTR [EDX + 8]
+ FSTP DWORD PTR [ECX + 8]
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorReflect(V, N: TAffineVector): TAffineVector; assembler; register;
+
+// reflects vector V against N (assumes N is normalized)
+// EAX contains address of V
+// EDX contains address of N
+// ECX contains address of the result
+
+//var Dot : Single;
+
+asm
+ {Dot := VectorAffineDotProduct(V, N);
+ Result[X] := V[X]-2 * Dot * N[X];
+ Result[Y] := V[Y]-2 * Dot * N[Y];
+ Result[Z] := V[Z]-2 * Dot * N[Z];}
+
+ CALL VectorAffineDotProduct // dot is now in ST(0)
+ FCHS // -dot
+ FADD ST, ST // -dot * 2
+ FLD DWORD PTR [EDX] // ST := N[X]
+ FMUL ST, ST(1) // ST := -2 * dot * N[X]
+ FADD DWORD PTR[EAX] // ST := V[X] - 2 * dot * N[X]
+ FSTP DWORD PTR [ECX] // store result
+ FLD DWORD PTR [EDX + 4] // etc.
+ FMUL ST, ST(1)
+ FADD DWORD PTR[EAX + 4]
+ FSTP DWORD PTR [ECX + 4]
+ FLD DWORD PTR [EDX + 8]
+ FMUL ST, ST(1)
+ FADD DWORD PTR[EAX + 8]
+ FSTP DWORD PTR [ECX + 8]
+ FSTP ST // clean FPU stack
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure VectorRotate(var Vector: TVector4f; Axis: TVector3f; Angle: Single);
+
+// rotates Vector about Axis with Angle radiants
+
+var RotMatrix : TMatrix4f;
+
+begin
+ RotMatrix := CreateRotationMatrix(Axis, Angle);
+ Vector := VectorTransform(Vector, RotMatrix);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure VectorScale(V: array of Single; Factor: Single); assembler; register;
+
+// returns a vector scaled by a factor
+// EAX contains address of V
+// EDX contains highest index in V
+// Factor is located on the stack
+
+asm
+ {for I := Low(V) to High(V) do V[I] := V[I] * Factor;}
+
+ FLD DWORD PTR [Factor] // load factor
+@@Loop: FLD DWORD PTR [EAX + 4 * EDX] // load a component
+ FMUL ST, ST(1) // multiply it with the factor
+ WAIT
+ FSTP DWORD PTR [EAX + 4 * EDX] // store the result
+ DEC EDX // do the entire array
+ JNS @@Loop
+ FSTP ST(0) // clean the FPU stack
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure VectorNegate(V: array of Single); assembler; register;
+
+// returns a negated vector
+// EAX contains address of V
+// EDX contains highest index in V
+
+asm
+ {V[X] := -V[X];
+ V[Y] := -V[Y];
+ V[Z] := -V[Z];}
+
+@@Loop: FLD DWORD PTR [EAX + 4 * EDX]
+ FCHS
+ WAIT
+ FSTP DWORD PTR [EAX + 4 * EDX]
+ DEC EDX
+ JNS @@Loop
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAdd(V1, V2: TVector): TVector; register;
+
+// returns the sum of two vectors
+
+begin
+ Result[X] := V1[X] + V2[X];
+ Result[Y] := V1[Y] + V2[Y];
+ Result[Z] := V1[Z] + V2[Z];
+ Result[W] := V1[W] + V2[W];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineAdd(V1, V2: TAffineVector): TAffineVector; register;
+
+// returns the sum of two vectors
+
+begin
+ Result[X] := V1[X] + V2[X];
+ Result[Y] := V1[Y] + V2[Y];
+ Result[Z] := V1[Z] + V2[Z];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorSubtract(V1, V2: TVector): TVector; register;
+
+// returns the difference of two vectors
+
+begin
+ Result[X] := V1[X] - V2[X];
+ Result[Y] := V1[Y] - V2[Y];
+ Result[Z] := V1[Z] - V2[Z];
+ Result[W] := V1[W] - V2[W];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorDotProduct(V1, V2: TVector): Single; register;
+
+begin
+ Result := V1[X] * V2[X] + V1[Y] * V2[Y] + V1[Z] * V2[Z] + V1[W] * V2[W];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineDotProduct(V1, V2: TAffineVector): Single; assembler; register;
+
+// calculates the dot product between V1 and V2
+// EAX contains address of V1
+// EDX contains address of V2
+// result is stored in ST(0)
+
+asm
+ //Result := V1[X] * V2[X] + V1[Y] * V2[Y] + V1[Z] * V2[Z];
+
+ FLD DWORD PTR [EAX]
+ FMUL DWORD PTR [EDX]
+ FLD DWORD PTR [EAX + 4]
+ FMUL DWORD PTR [EDX + 4]
+ FADDP
+ FLD DWORD PTR [EAX + 8]
+ FMUL DWORD PTR [EDX + 8]
+ FADDP
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorCrossProduct(V1, V2: TAffineVector): TAffineVector;
+
+// calculates the cross product between vector 1 and 2, Temp is necessary because
+// either V1 or V2 could also be the result vector
+//
+// EAX contains address of V1
+// EDX contains address of V2
+// ECX contains address of result
+
+var Temp: TAffineVector;
+
+asm
+ {Temp[X] := V1[Y] * V2[Z]-V1[Z] * V2[Y];
+ Temp[Y] := V1[Z] * V2[X]-V1[X] * V2[Z];
+ Temp[Z] := V1[X] * V2[Y]-V1[Y] * V2[X];
+ Result := Temp;}
+
+ PUSH EBX // save EBX, must be restored to original value
+ LEA EBX, [Temp]
+ FLD DWORD PTR [EDX + 8] // first load both vectors onto FPU register stack
+ FLD DWORD PTR [EDX + 4]
+ FLD DWORD PTR [EDX + 0]
+ FLD DWORD PTR [EAX + 8]
+ FLD DWORD PTR [EAX + 4]
+ FLD DWORD PTR [EAX + 0]
+
+ FLD ST(1) // ST(0) := V1[Y]
+ FMUL ST, ST(6) // ST(0) := V1[Y] * V2[Z]
+ FLD ST(3) // ST(0) := V1[Z]
+ FMUL ST, ST(6) // ST(0) := V1[Z] * V2[Y]
+ FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
+ FSTP DWORD [EBX] // Temp[X] := ST(0)
+ FLD ST(2) // ST(0) := V1[Z]
+ FMUL ST, ST(4) // ST(0) := V1[Z] * V2[X]
+ FLD ST(1) // ST(0) := V1[X]
+ FMUL ST, ST(7) // ST(0) := V1[X] * V2[Z]
+ FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
+ FSTP DWORD [EBX + 4] // Temp[Y] := ST(0)
+ FLD ST // ST(0) := V1[X]
+ FMUL ST, ST(5) // ST(0) := V1[X] * V2[Y]
+ FLD ST(2) // ST(0) := V1[Y]
+ FMUL ST, ST(5) // ST(0) := V1[Y] * V2[X]
+ FSUBP ST(1), ST // ST(0) := ST(1)-ST(0)
+ FSTP DWORD [EBX + 8] // Temp[Z] := ST(0)
+ FSTP ST(0) // clear FPU register stack
+ FSTP ST(0)
+ FSTP ST(0)
+ FSTP ST(0)
+ FSTP ST(0)
+ FSTP ST(0)
+ MOV EAX, [EBX] // copy Temp to Result
+ MOV [ECX], EAX
+ MOV EAX, [EBX + 4]
+ MOV [ECX + 4], EAX
+ MOV EAX, [EBX + 8]
+ MOV [ECX + 8], EAX
+ POP EBX
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorPerpendicular(V, N: TAffineVector): TAffineVector;
+
+// calculates a vector perpendicular to N (N is assumed to be of unit length)
+// subtract out any component parallel to N
+
+var Dot: Single;
+
+begin
+ Dot := VectorAffineDotProduct(V, N);
+ Result[X] := V[X]-Dot * N[X];
+ Result[Y] := V[Y]-Dot * N[Y];
+ Result[Z] := V[Z]-Dot * N[Z];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorTransform(V: TVector4f; M: TMatrix): TVector4f; register;
+
+// transforms a homogeneous vector by multiplying it with a matrix
+
+var TV: TVector4f;
+
+begin
+ TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X] + V[W] * M[W, X];
+ TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y] + V[W] * M[W, Y];
+ TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z] + V[W] * M[W, Z];
+ TV[W] := V[X] * M[X, W] + V[Y] * M[Y, W] + V[Z] * M[Z, W] + V[W] * M[W, W];
+ Result := TV
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorTransform(V: TVector3f; M: TMatrix): TVector3f;
+
+// transforms an affine vector by multiplying it with a (homogeneous) matrix
+
+var TV: TVector3f;
+
+begin
+ TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X] + M[W, X];
+ TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y] + M[W, Y];
+ TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z] + M[W, Z];
+ Result := TV;
+end;
+
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineTransform(V: TAffineVector; M: TAffineMatrix): TAffineVector; register;
+
+// transforms an affine vector by multiplying it with a matrix
+
+var TV: TAffineVector;
+
+begin
+ TV[X] := V[X] * M[X, X] + V[Y] * M[Y, X] + V[Z] * M[Z, X];
+ TV[Y] := V[X] * M[X, Y] + V[Y] * M[Y, Y] + V[Z] * M[Z, Y];
+ TV[Z] := V[X] * M[X, Z] + V[Y] * M[Y, Z] + V[Z] * M[Z, Z];
+ Result := TV;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function PointInPolygon(xp, yp : array of Single; x, y: Single): Boolean;
+
+// The code below is from Wm. Randolph Franklin
+// with some minor modifications for speed. It returns 1 for strictly
+// interior points, 0 for strictly exterior, and 0 or 1 for points on
+// the boundary.
+// This code is not yet tested!
+
+var I, J: Integer;
+
+begin
+ Result := False;
+ if High(XP) <> High(YP) then Exit;
+ J := High(XP);
+ for I := 0 to High(XP) do
+ begin
+ if ((((yp[I] <= y) and (y < yp[J])) or ((yp[J] <= y) and (y < yp[I]))) and
+ (x < (xp[J] - xp[I]) * (y - yp[I]) / (yp[J] - yp[I]) + xp[I]))
+ then Result := not Result;
+ J := I + 1;
+ end;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function QuaternionConjugate(Q: TQuaternion): TQuaternion; assembler;
+
+// returns the conjugate of a quaternion
+// EAX contains address of Q
+// EDX contains address of result
+
+asm
+ FLD DWORD PTR [EAX]
+ FCHS
+ WAIT
+ FSTP DWORD PTR [EDX]
+ FLD DWORD PTR [EAX + 4]
+ FCHS
+ WAIT
+ FSTP DWORD PTR [EDX + 4]
+ FLD DWORD PTR [EAX + 8]
+ FCHS
+ WAIT
+ FSTP DWORD PTR [EDX + 8]
+ MOV EAX, [EAX + 12]
+ MOV [EDX + 12], EAX
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function QuaternionFromPoints(V1, V2: TAffineVector): TQuaternion; assembler;
+
+// constructs a unit quaternion from two points on unit sphere
+// EAX contains address of V1
+// ECX contains address to result
+// EDX contains address of V2
+
+asm
+ {Result.ImagPart := VectorCrossProduct(V1, V2);
+ Result.RealPart := Sqrt((VectorAffineDotProduct(V1, V2) + 1)/2);}
+
+ PUSH EAX
+ CALL VectorCrossProduct // determine axis to rotate about
+ POP EAX
+ FLD1 // prepare next calculation
+ Call VectorAffineDotProduct // calculate cos(angle between V1 and V2)
+ FADD ST, ST(1) // transform angle to angle/2 by: cos(a/2)=sqrt((1 + cos(a))/2)
+ FXCH ST(1)
+ FADD ST, ST
+ FDIVP ST(1), ST
+ FSQRT
+ FSTP DWORD PTR [ECX + 12] // Result.RealPart := ST(0)
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function QuaternionMultiply(qL, qR: TQuaternion): TQuaternion;
+
+// Returns quaternion product qL * qR. Note: order is important!
+// To combine rotations, use the product QuaternionMuliply(qSecond, qFirst),
+// which gives the effect of rotating by qFirst then qSecond.
+
+var Temp : TQuaternion;
+
+begin
+ Temp.RealPart := qL.RealPart * qR.RealPart - qL.ImagPart[X] * qR.ImagPart[X] -
+ qL.ImagPart[Y] * qR.ImagPart[Y] - qL.ImagPart[Z] * qR.ImagPart[Z];
+ Temp.ImagPart[X] := qL.RealPart * qR.ImagPart[X] + qL.ImagPart[X] * qR.RealPart +
+ qL.ImagPart[Y] * qR.ImagPart[Z] - qL.ImagPart[Z] * qR.ImagPart[Y];
+ Temp.ImagPart[Y] := qL.RealPart * qR.ImagPart[Y] + qL.ImagPart[Y] * qR.RealPart +
+ qL.ImagPart[Z] * qR.ImagPart[X] - qL.ImagPart[X] * qR.ImagPart[Z];
+ Temp.ImagPart[Z] := qL.RealPart * qR.ImagPart[Z] + qL.ImagPart[Z] * qR.RealPart +
+ qL.ImagPart[X] * qR.ImagPart[Y] - qL.ImagPart[Y] * qR.ImagPart[X];
+ Result := Temp;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function QuaternionToMatrix(Q: TQuaternion): TMatrix;
+
+// Constructs rotation matrix from (possibly non-unit) quaternion.
+// Assumes matrix is used to multiply column vector on the left:
+// vnew = mat vold. Works correctly for right-handed coordinate system
+// and right-handed rotations.
+
+// Essentially, this function is the same as CreateRotationMatrix and you can consider it as
+// being for reference here.
+
+{var Norm, S,
+ XS, YS, ZS,
+ WX, WY, WZ,
+ XX, XY, XZ,
+ YY, YZ, ZZ : Single;
+
+begin
+ Norm := Q.Vector[X] * Q.Vector[X] + Q.Vector[Y] * Q.Vector[Y] + Q.Vector[Z] * Q.Vector[Z] + Q.RealPart * Q.RealPart;
+ if Norm > 0 then S := 2 / Norm
+ else S := 0;
+
+ XS := Q.Vector[X] * S; YS := Q.Vector[Y] * S; ZS := Q.Vector[Z] * S;
+ WX := Q.RealPart * XS; WY := Q.RealPart * YS; WZ := Q.RealPart * ZS;
+ XX := Q.Vector[X] * XS; XY := Q.Vector[X] * YS; XZ := Q.Vector[X] * ZS;
+ YY := Q.Vector[Y] * YS; YZ := Q.Vector[Y] * ZS; ZZ := Q.Vector[Z] * ZS;
+
+ Result[X, X] := 1 - (YY + ZZ); Result[Y, X] := XY + WZ; Result[Z, X] := XZ - WY; Result[W, X] := 0;
+ Result[X, Y] := XY - WZ; Result[Y, Y] := 1 - (XX + ZZ); Result[Z, Y] := YZ + WX; Result[W, Y] := 0;
+ Result[X, Z] := XZ + WY; Result[Y, Z] := YZ - WX; Result[Z, Z] := 1 - (XX + YY); Result[W, Z] := 0;
+ Result[X, W] := 0; Result[Y, W] := 0; Result[Z, W] := 0; Result[W, W] := 1;}
+
+var
+ V: TAffineVector;
+ SinA, CosA,
+ A, B, C: Extended;
+
+begin
+ V := Q.ImagPart;
+ VectorNormalize(V);
+ SinCos(Q.RealPart / 2, SinA, CosA);
+ A := V[X] * SinA;
+ B := V[Y] * SinA;
+ C := V[Z] * SinA;
+
+ Result := IdentityMatrix;
+ Result[X, X] := 1 - 2 * B * B - 2 * C * C;
+ Result[X, Y] := 2 * A * B - 2 * CosA * C;
+ Result[X, Z] := 2 * A * C + 2 * CosA * B;
+
+ Result[Y, X] := 2 * A * B + 2 * CosA * C;
+ Result[Y, Y] := 1 - 2 * A * A - 2 * C * C;
+ Result[Y, Z] := 2 * B * C - 2 * CosA * A;
+
+ Result[Z, X] := 2 * A * C - 2 * CosA * B;
+ Result[Z, Y] := 2 * B * C + 2 * CosA * A;
+ Result[Z, Z] := 1 - 2 * A * A - 2 * B * B;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure QuaternionToPoints(Q: TQuaternion; var ArcFrom, ArcTo: TAffineVector); register;
+
+// converts a unit quaternion into two points on a unit sphere
+
+var S: Single;
+
+begin
+ S := Sqrt(Q.ImagPart[X] * Q.ImagPart[X] + Q.ImagPart[Y] * Q.ImagPart[Y]);
+ if S = 0 then ArcFrom := MakeAffineVector([0, 1, 0])
+ else ArcFrom := MakeAffineVector([-Q.ImagPart[Y] / S, Q.ImagPart[X] / S, 0]);
+ ArcTo[X] := Q.RealPart * ArcFrom[X] - Q.ImagPart[Z] * ArcFrom[Y];
+ ArcTo[Y] := Q.RealPart * ArcFrom[Y] + Q.ImagPart[Z] * ArcFrom[X];
+ ArcTo[Z] := Q.ImagPart[X] * ArcFrom[Y] - Q.ImagPart[Y] * ArcFrom[X];
+ if Q.RealPart < 0 then ArcFrom := MakeAffineVector([-ArcFrom[X], -ArcFrom[Y], 0]);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MatrixAffineDeterminant(M: TAffineMatrix): Single; register;
+
+// determinant of a 3x3 matrix
+
+begin
+ Result := M[X, X] * (M[Y, Y] * M[Z, Z] - M[Z, Y] * M[Y, Z]) -
+ M[X, Y] * (M[Y, X] * M[Z, Z] - M[Z, X] * M[Y, Z]) +
+ M[X, Z] * (M[Y, X] * M[Z, Y] - M[Z, X] * M[Y, Y]);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3: Single): Single;
+
+// internal version for the determinant of a 3x3 matrix
+
+begin
+ Result := a1 * (b2 * c3 - b3 * c2) -
+ b1 * (a2 * c3 - a3 * c2) +
+ c1 * (a2 * b3 - a3 * b2);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure MatrixAdjoint(var M: TMatrix); register;
+
+// Adjoint of a 4x4 matrix - used in the computation of the inverse
+// of a 4x4 matrix
+
+var a1, a2, a3, a4,
+ b1, b2, b3, b4,
+ c1, c2, c3, c4,
+ d1, d2, d3, d4: Single;
+
+
+begin
+ a1 := M[X, X]; b1 := M[X, Y];
+ c1 := M[X, Z]; d1 := M[X, W];
+ a2 := M[Y, X]; b2 := M[Y, Y];
+ c2 := M[Y, Z]; d2 := M[Y, W];
+ a3 := M[Z, X]; b3 := M[Z, Y];
+ c3 := M[Z, Z]; d3 := M[Z, W];
+ a4 := M[W, X]; b4 := M[W, Y];
+ c4 := M[W, Z]; d4 := M[W, W];
+
+ // row column labeling reversed since we transpose rows & columns
+ M[X, X] := MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4);
+ M[Y, X] := -MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4);
+ M[Z, X] := MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4);
+ M[W, X] := -MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
+
+ M[X, Y] := -MatrixDetInternal(b1, b3, b4, c1, c3, c4, d1, d3, d4);
+ M[Y, Y] := MatrixDetInternal(a1, a3, a4, c1, c3, c4, d1, d3, d4);
+ M[Z, Y] := -MatrixDetInternal(a1, a3, a4, b1, b3, b4, d1, d3, d4);
+ M[W, Y] := MatrixDetInternal(a1, a3, a4, b1, b3, b4, c1, c3, c4);
+
+ M[X, Z] := MatrixDetInternal(b1, b2, b4, c1, c2, c4, d1, d2, d4);
+ M[Y, Z] := -MatrixDetInternal(a1, a2, a4, c1, c2, c4, d1, d2, d4);
+ M[Z, Z] := MatrixDetInternal(a1, a2, a4, b1, b2, b4, d1, d2, d4);
+ M[W, Z] := -MatrixDetInternal(a1, a2, a4, b1, b2, b4, c1, c2, c4);
+
+ M[X, W] := -MatrixDetInternal(b1, b2, b3, c1, c2, c3, d1, d2, d3);
+ M[Y, W] := MatrixDetInternal(a1, a2, a3, c1, c2, c3, d1, d2, d3);
+ M[Z, W] := -MatrixDetInternal(a1, a2, a3, b1, b2, b3, d1, d2, d3);
+ M[W, W] := MatrixDetInternal(a1, a2, a3, b1, b2, b3, c1, c2, c3);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MatrixDeterminant(M: TMatrix): Single; register;
+
+// Determinant of a 4x4 matrix
+
+var a1, a2, a3, a4,
+ b1, b2, b3, b4,
+ c1, c2, c3, c4,
+ d1, d2, d3, d4 : Single;
+
+begin
+ a1 := M[X, X]; b1 := M[X, Y]; c1 := M[X, Z]; d1 := M[X, W];
+ a2 := M[Y, X]; b2 := M[Y, Y]; c2 := M[Y, Z]; d2 := M[Y, W];
+ a3 := M[Z, X]; b3 := M[Z, Y]; c3 := M[Z, Z]; d3 := M[Z, W];
+ a4 := M[W, X]; b4 := M[W, Y]; c4 := M[W, Z]; d4 := M[W, W];
+
+ Result := a1 * MatrixDetInternal(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
+ b1 * MatrixDetInternal(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
+ c1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
+ d1 * MatrixDetInternal(a2, a3, a4, b2, b3, b4, c2, c3, c4);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure MatrixScale(var M: TMatrix; Factor: Single); register;
+
+// multiplies all elements of a 4x4 matrix with a factor
+
+var I, J: Integer;
+
+begin
+ for I := 0 to 3 do
+ for J := 0 to 3 do M[I, J] := M[I, J] * Factor;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure MatrixInvert(var M: TMatrix); register;
+
+// finds the inverse of a 4x4 matrix
+
+var Det: Single;
+
+begin
+ Det := MatrixDeterminant(M);
+ if Abs(Det) < EPSILON then M := IdentityMatrix
+ else
+ begin
+ MatrixAdjoint(M);
+ MatrixScale(M, 1 / Det);
+ end;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure MatrixTranspose(var M: TMatrix); register;
+
+// computes transpose of 4x4 matrix
+
+var I, J: Integer;
+ TM: TMatrix;
+
+begin
+ for I := 0 to 3 do
+ for J := 0 to 3 do TM[J, I] := M[I, J];
+ M := TM;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+procedure MatrixAffineTranspose(var M: TAffineMatrix); register;
+
+// computes transpose of 3x3 matrix
+
+var I, J: Integer;
+ TM: TAffineMatrix;
+
+begin
+ for I := 0 to 2 do
+ for J := 0 to 2 do TM[J, I] := M[I, J];
+ M := TM;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MatrixMultiply(M1, M2: TMatrix): TMatrix; register;
+
+// multiplies two 4x4 matrices
+
+var I, J: Integer;
+ TM: TMatrix;
+
+begin
+ for I := 0 to 3 do
+ for J := 0 to 3 do
+ TM[I, J] := M1[I, X] * M2[X, J] +
+ M1[I, Y] * M2[Y, J] +
+ M1[I, Z] * M2[Z, J] +
+ M1[I, W] * M2[W, J];
+ Result := TM;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateRotationMatrix(Axis: TVector3f; Angle: Single): TMatrix; register;
+
+// Creates a rotation matrix along the given Axis by the given Angle in radians.
+
+var cosine,
+ sine,
+ Len,
+ one_minus_cosine: Extended;
+
+begin
+ SinCos(Angle, Sine, Cosine);
+ one_minus_cosine := 1 - cosine;
+ Len := VectorNormalize(Axis);
+
+ if Len = 0 then Result := IdentityMatrix
+ else
+ begin
+ Result[X, X] := (one_minus_cosine * Sqr(Axis[0])) + Cosine;
+ Result[X, Y] := (one_minus_cosine * Axis[0] * Axis[1]) - (Axis[2] * Sine);
+ Result[X, Z] := (one_minus_cosine * Axis[2] * Axis[0]) + (Axis[1] * Sine);
+ Result[X, W] := 0;
+
+ Result[Y, X] := (one_minus_cosine * Axis[0] * Axis[1]) + (Axis[2] * Sine);
+ Result[Y, Y] := (one_minus_cosine * Sqr(Axis[1])) + Cosine;
+ Result[Y, Z] := (one_minus_cosine * Axis[1] * Axis[2]) - (Axis[0] * Sine);
+ Result[Y, W] := 0;
+
+ Result[Z, X] := (one_minus_cosine * Axis[2] * Axis[0]) - (Axis[1] * Sine);
+ Result[Z, Y] := (one_minus_cosine * Axis[1] * Axis[2]) + (Axis[0] * Sine);
+ Result[Z, Z] := (one_minus_cosine * Sqr(Axis[2])) + Cosine;
+ Result[Z, W] := 0;
+
+ Result[W, X] := 0;
+ Result[W, Y] := 0;
+ Result[W, Z] := 0;
+ Result[W, W] := 1;
+ end;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function ConvertRotation(Angles: TAffineVector): TVector; register;
+
+{ Turn a triplet of rotations about x, y, and z (in that order) into an
+ equivalent rotation around a single axis (all in radians).
+
+ Rotation of the Angle t about the axis (X, Y, Z) is given by:
+
+ | X^2 + (1-X^2) Cos(t), XY(1-Cos(t)) + Z Sin(t), XZ(1-Cos(t))-Y Sin(t) |
+ M = | XY(1-Cos(t))-Z Sin(t), Y^2 + (1-Y^2) Cos(t), YZ(1-Cos(t)) + X Sin(t) |
+ | XZ(1-Cos(t)) + Y Sin(t), YZ(1-Cos(t))-X Sin(t), Z^2 + (1-Z^2) Cos(t) |
+
+ Rotation about the three axes (Angles a1, a2, a3) can be represented as
+ the product of the individual rotation matrices:
+
+ | 1 0 0 | | Cos(a2) 0 -Sin(a2) | | Cos(a3) Sin(a3) 0 |
+ | 0 Cos(a1) Sin(a1) | * | 0 1 0 | * | -Sin(a3) Cos(a3) 0 |
+ | 0 -Sin(a1) Cos(a1) | | Sin(a2) 0 Cos(a2) | | 0 0 1 |
+ Mx My Mz
+
+ We now want to solve for X, Y, Z, and t given 9 equations in 4 unknowns.
+ Using the diagonal elements of the two matrices, we get:
+
+ X^2 + (1-X^2) Cos(t) = M[0][0]
+ Y^2 + (1-Y^2) Cos(t) = M[1][1]
+ Z^2 + (1-Z^2) Cos(t) = M[2][2]
+
+ Adding the three equations, we get:
+
+ X^2 + Y^2 + Z^2 - (M[0][0] + M[1][1] + M[2][2]) =
+ - (3 - X^2 - Y^2 - Z^2) Cos(t)
+
+ Since (X^2 + Y^2 + Z^2) = 1, we can rewrite as:
+
+ Cos(t) = (1 - (M[0][0] + M[1][1] + M[2][2])) / 2
+
+ Solving for t, we get:
+
+ t = Acos(((M[0][0] + M[1][1] + M[2][2]) - 1) / 2)
+
+ We can substitute t into the equations for X^2, Y^2, and Z^2 above
+ to get the values for X, Y, and Z. To find the proper signs we note
+ that:
+
+ 2 X Sin(t) = M[1][2] - M[2][1]
+ 2 Y Sin(t) = M[2][0] - M[0][2]
+ 2 Z Sin(t) = M[0][1] - M[1][0]
+}
+
+var Axis1, Axis2: TVector3f;
+ M, M1, M2: TMatrix;
+ cost, cost1,
+ sint,
+ s1, s2, s3: Single;
+ I: Integer;
+
+
+begin
+ // see if we are only rotating about a single Axis
+ if Abs(Angles[X]) < EPSILON then
+ begin
+ if Abs(Angles[Y]) < EPSILON then
+ begin
+ Result := MakeVector([0, 0, 1, Angles[Z]]);
+ Exit;
+ end
+ else
+ if Abs(Angles[Z]) < EPSILON then
+ begin
+ Result := MakeVector([0, 1, 0, Angles[Y]]);
+ Exit;
+ end
+ end
+ else
+ if (Abs(Angles[Y]) < EPSILON) and
+ (Abs(Angles[Z]) < EPSILON) then
+ begin
+ Result := MakeVector([1, 0, 0, Angles[X]]);
+ Exit;
+ end;
+
+ // make the rotation matrix
+ Axis1 := MakeAffineVector([1, 0, 0]);
+ M := CreateRotationMatrix(Axis1, Angles[X]);
+
+ Axis2 := MakeAffineVector([0, 1, 0]);
+ M2 := CreateRotationMatrix(Axis2, Angles[Y]);
+ M1 := MatrixMultiply(M, M2);
+
+ Axis2 := MakeAffineVector([0, 0, 1]);
+ M2 := CreateRotationMatrix(Axis2, Angles[Z]);
+ M := MatrixMultiply(M1, M2);
+
+ cost := ((M[X, X] + M[Y, Y] + M[Z, Z])-1) / 2;
+ if cost < -1 then cost := -1
+ else
+ if cost > 1 - EPSILON then
+ begin
+ // Bad Angle - this would cause a crash
+ Result := MakeVector([1, 0, 0, 0]);
+ Exit;
+ end;
+
+ cost1 := 1 - cost;
+ Result := Makevector([Sqrt((M[X, X]-cost) / cost1),
+ Sqrt((M[Y, Y]-cost) / cost1),
+ sqrt((M[Z, Z]-cost) / cost1),
+ arccos(cost)]);
+
+ sint := 2 * Sqrt(1 - cost * cost); // This is actually 2 Sin(t)
+
+ // Determine the proper signs
+ for I := 0 to 7 do
+ begin
+ if (I and 1) > 1 then s1 := -1 else s1 := 1;
+ if (I and 2) > 1 then s2 := -1 else s2 := 1;
+ if (I and 4) > 1 then s3 := -1 else s3 := 1;
+ if (Abs(s1 * Result[X] * sint-M[Y, Z] + M[Z, Y]) < EPSILON2) and
+ (Abs(s2 * Result[Y] * sint-M[Z, X] + M[X, Z]) < EPSILON2) and
+ (Abs(s3 * Result[Z] * sint-M[X, Y] + M[Y, X]) < EPSILON2) then
+ begin
+ // We found the right combination of signs
+ Result[X] := Result[X] * s1;
+ Result[Y] := Result[Y] * s2;
+ Result[Z] := Result[Z] * s3;
+ Exit;
+ end;
+ end;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateRotationMatrixX(Sine, Cosine: Single): TMatrix; register;
+
+// creates matrix for rotation about x-axis
+
+begin
+ Result := EmptyMatrix;
+ Result[X, X] := 1;
+ Result[Y, Y] := Cosine;
+ Result[Y, Z] := Sine;
+ Result[Z, Y] := -Sine;
+ Result[Z, Z] := Cosine;
+ Result[W, W] := 1;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateRotationMatrixY(Sine, Cosine: Single): TMatrix; register;
+
+// creates matrix for rotation about y-axis
+
+begin
+ Result := EmptyMatrix;
+ Result[X, X] := Cosine;
+ Result[X, Z] := -Sine;
+ Result[Y, Y] := 1;
+ Result[Z, X] := Sine;
+ Result[Z, Z] := Cosine;
+ Result[W, W] := 1;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateRotationMatrixZ(Sine, Cosine: Single): TMatrix; register;
+
+// creates matrix for rotation about z-axis
+
+begin
+ Result := EmptyMatrix;
+ Result[X, X] := Cosine;
+ Result[X, Y] := Sine;
+ Result[Y, X] := -Sine;
+ Result[Y, Y] := Cosine;
+ Result[Z, Z] := 1;
+ Result[W, W] := 1;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateScaleMatrix(V: TAffineVector): TMatrix; register;
+
+// creates scaling matrix
+
+begin
+ Result := IdentityMatrix;
+ Result[X, X] := V[X];
+ Result[Y, Y] := V[Y];
+ Result[Z, Z] := V[Z];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function CreateTranslationMatrix(V: TVector): TMatrix; register;
+
+// creates translation matrix
+
+begin
+ Result := IdentityMatrix;
+ Result[W, X] := V[X];
+ Result[W, Y] := V[Y];
+ Result[W, Z] := V[Z];
+ Result[W, W] := V[W];
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Lerp(Start, Stop, t: Single): Single;
+
+// calculates linear interpolation between start and stop at point t
+
+begin
+ Result := Start + (Stop - Start) * t;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineLerp(V1, V2: TAffineVector; t: Single): TAffineVector;
+
+// calculates linear interpolation between vector1 and vector2 at point t
+
+begin
+ Result[X] := Lerp(V1[X], V2[X], t);
+ Result[Y] := Lerp(V1[Y], V2[Y], t);
+ Result[Z] := Lerp(V1[Z], V2[Z], t);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorLerp(V1, V2: TVector; t: Single): TVector;
+
+// calculates linear interpolation between vector1 and vector2 at point t
+
+begin
+ Result[X] := Lerp(V1[X], V2[X], t);
+ Result[Y] := Lerp(V1[Y], V2[Y], t);
+ Result[Z] := Lerp(V1[Z], V2[Z], t);
+ Result[W] := Lerp(V1[W], V2[W], t);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function QuaternionSlerp(QStart, QEnd: TQuaternion; Spin: Integer; t: Single): TQuaternion;
+
+// spherical linear interpolation of unit quaternions with spins
+// QStart, QEnd - start and end unit quaternions
+// t - interpolation parameter (0 to 1)
+// Spin - number of extra spin rotations to involve
+
+var beta, // complementary interp parameter
+ theta, // Angle between A and B
+ sint, cost, // sine, cosine of theta
+ phi: Single; // theta plus spins
+ bflip: Boolean; // use negativ t?
+
+
+begin
+ // cosine theta
+ cost := VectorAngle(QStart.ImagPart, QEnd.ImagPart);
+
+ // if QEnd is on opposite hemisphere from QStart, use -QEnd instead
+ if cost < 0 then
+ begin
+ cost := -cost;
+ bflip := True;
+ end
+ else bflip := False;
+
+ // if QEnd is (within precision limits) the same as QStart,
+ // just linear interpolate between QStart and QEnd.
+ // Can't do spins, since we don't know what direction to spin.
+
+ if (1 - cost) < EPSILON then beta := 1 - t
+ else
+ begin
+ // normal case
+ theta := arccos(cost);
+ phi := theta + Spin * Pi;
+ sint := sin(theta);
+ beta := sin(theta - t * phi) / sint;
+ t := sin(t * phi) / sint;
+ end;
+
+ if bflip then t := -t;
+
+ // interpolate
+ Result.ImagPart[X] := beta * QStart.ImagPart[X] + t * QEnd.ImagPart[X];
+ Result.ImagPart[Y] := beta * QStart.ImagPart[Y] + t * QEnd.ImagPart[Y];
+ Result.ImagPart[Z] := beta * QStart.ImagPart[Z] + t * QEnd.ImagPart[Z];
+ Result.RealPart := beta * QStart.RealPart + t * QEnd.RealPart;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineCombine(V1, V2: TAffineVector; F1, F2: Single): TAffineVector;
+
+// makes a linear combination of two vectors and return the result
+
+begin
+ Result[X] := (F1 * V1[X]) + (F2 * V2[X]);
+ Result[Y] := (F1 * V1[Y]) + (F2 * V2[Y]);
+ Result[Z] := (F1 * V1[Z]) + (F2 * V2[Z]);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorCombine(V1, V2: TVector; F1, F2: Single): TVector;
+
+// makes a linear combination of two vectors and return the result
+
+begin
+ Result[X] := (F1 * V1[X]) + (F2 * V2[X]);
+ Result[Y] := (F1 * V1[Y]) + (F2 * V2[Y]);
+ Result[Z] := (F1 * V1[Z]) + (F2 * V2[Z]);
+ Result[W] := (F1 * V1[W]) + (F2 * V2[W]);
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function MatrixDecompose(M: TMatrix; var Tran: TTransformations): Boolean; register;
+
+// Author: Spencer W. Thomas, University of Michigan
+//
+// MatrixDecompose - Decompose a non-degenerated 4x4 transformation matrix into
+// the sequence of transformations that produced it.
+//
+// The coefficient of each transformation is returned in the corresponding
+// element of the vector Tran.
+//
+// Returns true upon success, false if the matrix is singular.
+
+var I, J: Integer;
+ LocMat,
+ pmat,
+ invpmat,
+ tinvpmat: TMatrix;
+ prhs,
+ psol: TVector;
+ Row: array[0..2] of TAffineVector;
+
+begin
+ Result := False;
+ locmat := M;
+ // normalize the matrix
+ if locmat[W, W] = 0 then Exit;
+ for I := 0 to 3 do
+ for J := 0 to 3 do
+ locmat[I, J] := locmat[I, J] / locmat[W, W];
+
+ // pmat is used to solve for perspective, but it also provides
+ // an easy way to test for singularity of the upper 3x3 component.
+
+ pmat := locmat;
+ for I := 0 to 2 do pmat[I, W] := 0;
+ pmat[W, W] := 1;
+
+ if MatrixDeterminant(pmat) = 0 then Exit;
+
+ // First, isolate perspective. This is the messiest.
+ if (locmat[X, W] <> 0) or
+ (locmat[Y, W] <> 0) or
+ (locmat[Z, W] <> 0) then
+ begin
+ // prhs is the right hand side of the equation.
+ prhs[X] := locmat[X, W];
+ prhs[Y] := locmat[Y, W];
+ prhs[Z] := locmat[Z, W];
+ prhs[W] := locmat[W, W];
+
+ // Solve the equation by inverting pmat and multiplying
+ // prhs by the inverse. (This is the easiest way, not
+ // necessarily the best.)
+
+ invpmat := pmat;
+ MatrixInvert(invpmat);
+ MatrixTranspose(invpmat);
+ psol := VectorTransform(prhs, tinvpmat);
+
+ // stuff the answer away
+ Tran[ttPerspectiveX] := psol[X];
+ Tran[ttPerspectiveY] := psol[Y];
+ Tran[ttPerspectiveZ] := psol[Z];
+ Tran[ttPerspectiveW] := psol[W];
+
+ // clear the perspective partition
+ locmat[X, W] := 0;
+ locmat[Y, W] := 0;
+ locmat[Z, W] := 0;
+ locmat[W, W] := 1;
+ end
+ else
+ begin
+ // no perspective
+ Tran[ttPerspectiveX] := 0;
+ Tran[ttPerspectiveY] := 0;
+ Tran[ttPerspectiveZ] := 0;
+ Tran[ttPerspectiveW] := 0;
+ end;
+
+ // next take care of translation (easy)
+ for I := 0 to 2 do
+ begin
+ Tran[TTransType(Ord(ttTranslateX) + I)] := locmat[W, I];
+ locmat[W, I] := 0;
+ end;
+
+ // now get scale and shear
+ for I := 0 to 2 do
+ begin
+ row[I, X] := locmat[I, X];
+ row[I, Y] := locmat[I, Y];
+ row[I, Z] := locmat[I, Z];
+ end;
+
+ // compute X scale factor and normalize first row
+ Tran[ttScaleX] := Sqr(VectorNormalize(row[0])); // ml: calculation optimized
+
+ // compute XY shear factor and make 2nd row orthogonal to 1st
+ Tran[ttShearXY] := VectorAffineDotProduct(row[0], row[1]);
+ row[1] := VectorAffineCombine(row[1], row[0], 1, -Tran[ttShearXY]);
+
+ // now, compute Y scale and normalize 2nd row
+ Tran[ttScaleY] := Sqr(VectorNormalize(row[1])); // ml: calculation optimized
+ Tran[ttShearXY] := Tran[ttShearXY]/Tran[ttScaleY];
+
+ // compute XZ and YZ shears, orthogonalize 3rd row
+ Tran[ttShearXZ] := VectorAffineDotProduct(row[0], row[2]);
+ row[2] := VectorAffineCombine(row[2], row[0], 1, -Tran[ttShearXZ]);
+ Tran[ttShearYZ] := VectorAffineDotProduct(row[1], row[2]);
+ row[2] := VectorAffineCombine(row[2], row[1], 1, -Tran[ttShearYZ]);
+
+ // next, get Z scale and normalize 3rd row
+ Tran[ttScaleZ] := Sqr(VectorNormalize(row[1])); // (ML) calc. optimized
+ Tran[ttShearXZ] := Tran[ttShearXZ] / tran[ttScaleZ];
+ Tran[ttShearYZ] := Tran[ttShearYZ] / Tran[ttScaleZ];
+
+ // At this point, the matrix (in rows[]) is orthonormal.
+ // Check for a coordinate system flip. If the determinant
+ // is -1, then negate the matrix and the scaling factors.
+ if VectorAffineDotProduct(row[0], VectorCrossProduct(row[1], row[2])) < 0 then
+ for I := 0 to 2 do
+ begin
+ Tran[TTransType(Ord(ttScaleX) + I)] := -Tran[TTransType(Ord(ttScaleX) + I)];
+ row[I, X] := -row[I, X];
+ row[I, Y] := -row[I, Y];
+ row[I, Z] := -row[I, Z];
+ end;
+
+ // now, get the rotations out, as described in the gem
+ Tran[ttRotateY] := arcsin(-row[0, Z]);
+ if cos(Tran[ttRotateY]) <> 0 then
+ begin
+ Tran[ttRotateX] := arctan2(row[1, Z], row[2, Z]);
+ Tran[ttRotateZ] := arctan2(row[0, Y], row[0, X]);
+ end
+ else
+ begin
+ tran[ttRotateX] := arctan2(row[1, X], row[1, Y]);
+ tran[ttRotateZ] := 0;
+ end;
+ // All done!
+ Result := True;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorDblToFlt(V: THomogeneousDblVector): THomogeneousVector; assembler;
+
+// converts a vector containing double sized values into a vector with single sized values
+
+asm
+ FLD QWORD PTR [EAX]
+ FSTP DWORD PTR [EDX]
+ FLD QWORD PTR [EAX + 8]
+ FSTP DWORD PTR [EDX + 4]
+ FLD QWORD PTR [EAX + 16]
+ FSTP DWORD PTR [EDX + 8]
+ FLD QWORD PTR [EAX + 24]
+ FSTP DWORD PTR [EDX + 12]
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineDblToFlt(V: TAffineDblVector): TAffineVector; assembler;
+
+// converts a vector containing double sized values into a vector with single sized values
+
+asm
+ FLD QWORD PTR [EAX]
+ FSTP DWORD PTR [EDX]
+ FLD QWORD PTR [EAX + 8]
+ FSTP DWORD PTR [EDX + 4]
+ FLD QWORD PTR [EAX + 16]
+ FSTP DWORD PTR [EDX + 8]
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorAffineFltToDbl(V: TAffineVector): TAffineDblVector; assembler;
+
+// converts a vector containing single sized values into a vector with double sized values
+
+asm
+ FLD DWORD PTR [EAX]
+ FSTP QWORD PTR [EDX]
+ FLD DWORD PTR [EAX + 8]
+ FSTP QWORD PTR [EDX + 4]
+ FLD DWORD PTR [EAX + 16]
+ FSTP QWORD PTR [EDX + 8]
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function VectorFltToDbl(V: TVector): THomogeneousDblVector; assembler;
+
+// converts a vector containing single sized values into a vector with double sized values
+
+asm
+ FLD DWORD PTR [EAX]
+ FSTP QWORD PTR [EDX]
+ FLD DWORD PTR [EAX + 8]
+ FSTP QWORD PTR [EDX + 4]
+ FLD DWORD PTR [EAX + 16]
+ FSTP QWORD PTR [EDX + 8]
+ FLD DWORD PTR [EAX + 24]
+ FSTP QWORD PTR [EDX + 12]
+end;
+
+//----------------- coordinate system manipulation functions -----------------------------------------------------------
+
+function Turn(Matrix: TMatrix; Angle: Single): TMatrix;
+
+// rotates the given coordinate system (represented by the matrix) around its Y-axis
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[1]), Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Turn(Matrix: TMatrix; MasterUp: TAffineVector; Angle: Single): TMatrix;
+
+// rotates the given coordinate system (represented by the matrix) around MasterUp
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterUp, Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Pitch(Matrix: TMatrix; Angle: Single): TMatrix;
+
+// rotates the given coordinate system (represented by the matrix) around its X-axis
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[0]), Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Pitch(Matrix: TMatrix; MasterRight: TAffineVector; Angle: Single): TMatrix; overload;
+
+// rotates the given coordinate system (represented by the matrix) around MasterRight
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterRight, Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Roll(Matrix: TMatrix; Angle: Single): TMatrix;
+
+// rotates the given coordinate system (represented by the matrix) around its Z-axis
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MakeAffineVector(Matrix[2]), Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function Roll(Matrix: TMatrix; MasterDirection: TAffineVector; Angle: Single): TMatrix; overload;
+
+// rotates the given coordinate system (represented by the matrix) around MasterDirection
+
+begin
+ Result := MatrixMultiply(Matrix, CreateRotationMatrix(MasterDirection, Angle));
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+end.
+
+
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/gl.pas b/src/lib/JEDI-SDL/OpenGL/Pas/gl.pas
new file mode 100644
index 00000000..2dc99df5
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/gl.pas
@@ -0,0 +1,2301 @@
+unit gl;
+{
+ $Id: gl.pas,v 1.5 2007/05/20 20:28:31 savage Exp $
+
+ Adaption of the delphi3d.net OpenGL units to FreePascal
+ Sebastian Guenther (sg@freepascal.org) in 2002
+ These units are free to use
+}
+
+(*++ BUILD Version: 0004 // Increment this if a change has global effects
+
+Copyright (c) 1985-96, Microsoft Corporation
+
+Module Name:
+
+ gl.h
+
+Abstract:
+
+ Procedure declarations, constant definitions and macros for the OpenGL
+ component.
+
+--*)
+
+(*
+** Copyright 1996 Silicon Graphics, Inc.
+** All Rights Reserved.
+**
+** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
+** the contents of this file may not be disclosed to third parties, copied or
+** duplicated in any form, in whole or in part, without the prior written
+** permission of Silicon Graphics, Inc.
+**
+** RESTRICTED RIGHTS LEGEND:
+** Use, duplication or disclosure by the Government is subject to restrictions
+** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
+** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
+** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
+** rights reserved under the Copyright Laws of the United States.
+*)
+
+{******************************************************************************}
+{ }
+{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
+{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
+{ }
+{ Modified for Delphi/Kylix and FreePascal }
+{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
+{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
+{ }
+{******************************************************************************}
+
+{
+ $Log: gl.pas,v $
+ Revision 1.5 2007/05/20 20:28:31 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.4 2006/11/20 21:20:59 savage
+ Updated to work in MacOS X
+
+ Revision 1.3 2005/05/22 18:52:09 savage
+ Changes as suggested by Michalis Kamburelis. Thanks again.
+
+ Revision 1.2 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.1 2004/03/30 21:53:54 savage
+ Moved to it's own folder.
+
+ Revision 1.4 2004/02/20 17:09:55 savage
+ Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
+
+ Revision 1.3 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+ Revision 1.2 2004/02/14 00:09:18 savage
+ Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+ Revision 1.6 2003/06/02 12:32:12 savage
+ Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+uses
+{$IFDEF __GPC__}
+ system,
+ gpc,
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+ Windows,
+{$ENDIF}
+ moduleloader;
+
+
+var
+ LibGL: TModuleHandle;
+
+type
+ GLenum = Cardinal; PGLenum = ^GLenum;
+ GLboolean = Byte; PGLboolean = ^GLboolean;
+ GLbitfield = Cardinal; PGLbitfield = ^GLbitfield;
+ GLbyte = ShortInt; PGLbyte = ^GLbyte;
+ GLshort = SmallInt; PGLshort = ^GLshort;
+ GLint = Integer; PGLint = ^GLint;
+ GLsizei = Integer; PGLsizei = ^GLsizei;
+ GLubyte = Byte; PGLubyte = ^GLubyte;
+ GLushort = Word; PGLushort = ^GLushort;
+ GLuint = Cardinal; PGLuint = ^GLuint;
+ GLfloat = Single; PGLfloat = ^GLfloat;
+ GLclampf = Single; PGLclampf = ^GLclampf;
+ GLdouble = Double; PGLdouble = ^GLdouble;
+ GLclampd = Double; PGLclampd = ^GLclampd;
+{ GLvoid = void; } PGLvoid = Pointer;
+
+{******************************************************************************}
+
+const
+{$IFDEF WINDOWS}
+ GLLibName = 'OpenGL32.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ GLLibName = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib';
+{$ELSE}
+ GLLibName = 'libGL.so';
+{$ENDIF}
+{$ENDIF}
+
+ // Version
+ GL_VERSION_1_1 = 1;
+
+ // AccumOp
+ GL_ACCUM = $0100;
+ GL_LOAD = $0101;
+ GL_RETURN = $0102;
+ GL_MULT = $0103;
+ GL_ADD = $0104;
+
+ // AlphaFunction
+ GL_NEVER = $0200;
+ GL_LESS = $0201;
+ GL_EQUAL = $0202;
+ GL_LEQUAL = $0203;
+ GL_GREATER = $0204;
+ GL_NOTEQUAL = $0205;
+ GL_GEQUAL = $0206;
+ GL_ALWAYS = $0207;
+
+ // AttribMask
+ GL_CURRENT_BIT = $00000001;
+ GL_POINT_BIT = $00000002;
+ GL_LINE_BIT = $00000004;
+ GL_POLYGON_BIT = $00000008;
+ GL_POLYGON_STIPPLE_BIT = $00000010;
+ GL_PIXEL_MODE_BIT = $00000020;
+ GL_LIGHTING_BIT = $00000040;
+ GL_FOG_BIT = $00000080;
+ GL_DEPTH_BUFFER_BIT = $00000100;
+ GL_ACCUM_BUFFER_BIT = $00000200;
+ GL_STENCIL_BUFFER_BIT = $00000400;
+ GL_VIEWPORT_BIT = $00000800;
+ GL_TRANSFORM_BIT = $00001000;
+ GL_ENABLE_BIT = $00002000;
+ GL_COLOR_BUFFER_BIT = $00004000;
+ GL_HINT_BIT = $00008000;
+ GL_EVAL_BIT = $00010000;
+ GL_LIST_BIT = $00020000;
+ GL_TEXTURE_BIT = $00040000;
+ GL_SCISSOR_BIT = $00080000;
+ GL_ALL_ATTRIB_BITS = $000FFFFF;
+
+ // BeginMode
+ GL_POINTS = $0000;
+ GL_LINES = $0001;
+ GL_LINE_LOOP = $0002;
+ GL_LINE_STRIP = $0003;
+ GL_TRIANGLES = $0004;
+ GL_TRIANGLE_STRIP = $0005;
+ GL_TRIANGLE_FAN = $0006;
+ GL_QUADS = $0007;
+ GL_QUAD_STRIP = $0008;
+ GL_POLYGON = $0009;
+
+ // BlendingFactorDest
+ GL_ZERO = 0;
+ GL_ONE = 1;
+ GL_SRC_COLOR = $0300;
+ GL_ONE_MINUS_SRC_COLOR = $0301;
+ GL_SRC_ALPHA = $0302;
+ GL_ONE_MINUS_SRC_ALPHA = $0303;
+ GL_DST_ALPHA = $0304;
+ GL_ONE_MINUS_DST_ALPHA = $0305;
+
+ // BlendingFactorSrc
+ // GL_ZERO
+ // GL_ONE
+ GL_DST_COLOR = $0306;
+ GL_ONE_MINUS_DST_COLOR = $0307;
+ GL_SRC_ALPHA_SATURATE = $0308;
+ // GL_SRC_ALPHA
+ // GL_ONE_MINUS_SRC_ALPHA
+ // GL_DST_ALPHA
+ // GL_ONE_MINUS_DST_ALPHA
+
+ // Boolean
+ GL_TRUE = 1;
+ GL_FALSE = 0;
+
+ // ClearBufferMask
+ // GL_COLOR_BUFFER_BIT
+ // GL_ACCUM_BUFFER_BIT
+ // GL_STENCIL_BUFFER_BIT
+ // GL_DEPTH_BUFFER_BIT
+
+ // ClientArrayType
+ // GL_VERTEX_ARRAY
+ // GL_NORMAL_ARRAY
+ // GL_COLOR_ARRAY
+ // GL_INDEX_ARRAY
+ // GL_TEXTURE_COORD_ARRAY
+ // GL_EDGE_FLAG_ARRAY
+
+ // ClipPlaneName
+ GL_CLIP_PLANE0 = $3000;
+ GL_CLIP_PLANE1 = $3001;
+ GL_CLIP_PLANE2 = $3002;
+ GL_CLIP_PLANE3 = $3003;
+ GL_CLIP_PLANE4 = $3004;
+ GL_CLIP_PLANE5 = $3005;
+
+ // ColorMaterialFace
+ // GL_FRONT
+ // GL_BACK
+ // GL_FRONT_AND_BACK
+
+ // ColorMaterialParameter
+ // GL_AMBIENT
+ // GL_DIFFUSE
+ // GL_SPECULAR
+ // GL_EMISSION
+ // GL_AMBIENT_AND_DIFFUSE
+
+ // ColorPointerType
+ // GL_BYTE
+ // GL_UNSIGNED_BYTE
+ // GL_SHORT
+ // GL_UNSIGNED_SHORT
+ // GL_INT
+ // GL_UNSIGNED_INT
+ // GL_FLOAT
+ // GL_DOUBLE
+
+ // CullFaceMode
+ // GL_FRONT
+ // GL_BACK
+ // GL_FRONT_AND_BACK
+
+ // DataType
+ GL_BYTE = $1400;
+ GL_UNSIGNED_BYTE = $1401;
+ GL_SHORT = $1402;
+ GL_UNSIGNED_SHORT = $1403;
+ GL_INT = $1404;
+ GL_UNSIGNED_INT = $1405;
+ GL_FLOAT = $1406;
+ GL_2_BYTES = $1407;
+ GL_3_BYTES = $1408;
+ GL_4_BYTES = $1409;
+ GL_DOUBLE = $140A;
+
+ // DepthFunction
+ // GL_NEVER
+ // GL_LESS
+ // GL_EQUAL
+ // GL_LEQUAL
+ // GL_GREATER
+ // GL_NOTEQUAL
+ // GL_GEQUAL
+ // GL_ALWAYS
+
+ // DrawBufferMode
+ GL_NONE = 0;
+ GL_FRONT_LEFT = $0400;
+ GL_FRONT_RIGHT = $0401;
+ GL_BACK_LEFT = $0402;
+ GL_BACK_RIGHT = $0403;
+ GL_FRONT = $0404;
+ GL_BACK = $0405;
+ GL_LEFT = $0406;
+ GL_RIGHT = $0407;
+ GL_FRONT_AND_BACK = $0408;
+ GL_AUX0 = $0409;
+ GL_AUX1 = $040A;
+ GL_AUX2 = $040B;
+ GL_AUX3 = $040C;
+
+ // Enable
+ // GL_FOG
+ // GL_LIGHTING
+ // GL_TEXTURE_1D
+ // GL_TEXTURE_2D
+ // GL_LINE_STIPPLE
+ // GL_POLYGON_STIPPLE
+ // GL_CULL_FACE
+ // GL_ALPHA_TEST
+ // GL_BLEND
+ // GL_INDEX_LOGIC_OP
+ // GL_COLOR_LOGIC_OP
+ // GL_DITHER
+ // GL_STENCIL_TEST
+ // GL_DEPTH_TEST
+ // GL_CLIP_PLANE0
+ // GL_CLIP_PLANE1
+ // GL_CLIP_PLANE2
+ // GL_CLIP_PLANE3
+ // GL_CLIP_PLANE4
+ // GL_CLIP_PLANE5
+ // GL_LIGHT0
+ // GL_LIGHT1
+ // GL_LIGHT2
+ // GL_LIGHT3
+ // GL_LIGHT4
+ // GL_LIGHT5
+ // GL_LIGHT6
+ // GL_LIGHT7
+ // GL_TEXTURE_GEN_S
+ // GL_TEXTURE_GEN_T
+ // GL_TEXTURE_GEN_R
+ // GL_TEXTURE_GEN_Q
+ // GL_MAP1_VERTEX_3
+ // GL_MAP1_VERTEX_4
+ // GL_MAP1_COLOR_4
+ // GL_MAP1_INDEX
+ // GL_MAP1_NORMAL
+ // GL_MAP1_TEXTURE_COORD_1
+ // GL_MAP1_TEXTURE_COORD_2
+ // GL_MAP1_TEXTURE_COORD_3
+ // GL_MAP1_TEXTURE_COORD_4
+ // GL_MAP2_VERTEX_3
+ // GL_MAP2_VERTEX_4
+ // GL_MAP2_COLOR_4
+ // GL_MAP2_INDEX
+ // GL_MAP2_NORMAL
+ // GL_MAP2_TEXTURE_COORD_1
+ // GL_MAP2_TEXTURE_COORD_2
+ // GL_MAP2_TEXTURE_COORD_3
+ // GL_MAP2_TEXTURE_COORD_4
+ // GL_POINT_SMOOTH
+ // GL_LINE_SMOOTH
+ // GL_POLYGON_SMOOTH
+ // GL_SCISSOR_TEST
+ // GL_COLOR_MATERIAL
+ // GL_NORMALIZE
+ // GL_AUTO_NORMAL
+ // GL_VERTEX_ARRAY
+ // GL_NORMAL_ARRAY
+ // GL_COLOR_ARRAY
+ // GL_INDEX_ARRAY
+ // GL_TEXTURE_COORD_ARRAY
+ // GL_EDGE_FLAG_ARRAY
+ // GL_POLYGON_OFFSET_POINT
+ // GL_POLYGON_OFFSET_LINE
+ // GL_POLYGON_OFFSET_FILL
+
+ // ErrorCode
+ GL_NO_ERROR = 0;
+ GL_INVALID_ENUM = $0500;
+ GL_INVALID_VALUE = $0501;
+ GL_INVALID_OPERATION = $0502;
+ GL_STACK_OVERFLOW = $0503;
+ GL_STACK_UNDERFLOW = $0504;
+ GL_OUT_OF_MEMORY = $0505;
+
+ // FeedBackMode
+ GL_2D = $0600;
+ GL_3D = $0601;
+ GL_3D_COLOR = $0602;
+ GL_3D_COLOR_TEXTURE = $0603;
+ GL_4D_COLOR_TEXTURE = $0604;
+
+ // FeedBackToken
+ GL_PASS_THROUGH_TOKEN = $0700;
+ GL_POINT_TOKEN = $0701;
+ GL_LINE_TOKEN = $0702;
+ GL_POLYGON_TOKEN = $0703;
+ GL_BITMAP_TOKEN = $0704;
+ GL_DRAW_PIXEL_TOKEN = $0705;
+ GL_COPY_PIXEL_TOKEN = $0706;
+ GL_LINE_RESET_TOKEN = $0707;
+
+ // FogMode
+ // GL_LINEAR
+ GL_EXP = $0800;
+ GL_EXP2 = $0801;
+
+ // FogParameter
+ // GL_FOG_COLOR
+ // GL_FOG_DENSITY
+ // GL_FOG_END
+ // GL_FOG_INDEX
+ // GL_FOG_MODE
+ // GL_FOG_START
+
+ // FrontFaceDirection
+ GL_CW = $0900;
+ GL_CCW = $0901;
+
+ // GetMapTarget
+ GL_COEFF = $0A00;
+ GL_ORDER = $0A01;
+ GL_DOMAIN = $0A02;
+
+ // GetPixelMap
+ // GL_PIXEL_MAP_I_TO_I
+ // GL_PIXEL_MAP_S_TO_S
+ // GL_PIXEL_MAP_I_TO_R
+ // GL_PIXEL_MAP_I_TO_G
+ // GL_PIXEL_MAP_I_TO_B
+ // GL_PIXEL_MAP_I_TO_A
+ // GL_PIXEL_MAP_R_TO_R
+ // GL_PIXEL_MAP_G_TO_G
+ // GL_PIXEL_MAP_B_TO_B
+ // GL_PIXEL_MAP_A_TO_A
+
+ // GetPointerTarget
+ // GL_VERTEX_ARRAY_POINTER
+ // GL_NORMAL_ARRAY_POINTER
+ // GL_COLOR_ARRAY_POINTER
+ // GL_INDEX_ARRAY_POINTER
+ // GL_TEXTURE_COORD_ARRAY_POINTER
+ // GL_EDGE_FLAG_ARRAY_POINTER
+
+ // GetTarget
+ GL_CURRENT_COLOR = $0B00;
+ GL_CURRENT_INDEX = $0B01;
+ GL_CURRENT_NORMAL = $0B02;
+ GL_CURRENT_TEXTURE_COORDS = $0B03;
+ GL_CURRENT_RASTER_COLOR = $0B04;
+ GL_CURRENT_RASTER_INDEX = $0B05;
+ GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06;
+ GL_CURRENT_RASTER_POSITION = $0B07;
+ GL_CURRENT_RASTER_POSITION_VALID = $0B08;
+ GL_CURRENT_RASTER_DISTANCE = $0B09;
+ GL_POINT_SMOOTH = $0B10;
+ GL_POINT_SIZE = $0B11;
+ GL_POINT_SIZE_RANGE = $0B12;
+ GL_POINT_SIZE_GRANULARITY = $0B13;
+ GL_LINE_SMOOTH = $0B20;
+ GL_LINE_WIDTH = $0B21;
+ GL_LINE_WIDTH_RANGE = $0B22;
+ GL_LINE_WIDTH_GRANULARITY = $0B23;
+ GL_LINE_STIPPLE = $0B24;
+ GL_LINE_STIPPLE_PATTERN = $0B25;
+ GL_LINE_STIPPLE_REPEAT = $0B26;
+ GL_LIST_MODE = $0B30;
+ GL_MAX_LIST_NESTING = $0B31;
+ GL_LIST_BASE = $0B32;
+ GL_LIST_INDEX = $0B33;
+ GL_POLYGON_MODE = $0B40;
+ GL_POLYGON_SMOOTH = $0B41;
+ GL_POLYGON_STIPPLE = $0B42;
+ GL_EDGE_FLAG = $0B43;
+ GL_CULL_FACE = $0B44;
+ GL_CULL_FACE_MODE = $0B45;
+ GL_FRONT_FACE = $0B46;
+ GL_LIGHTING = $0B50;
+ GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51;
+ GL_LIGHT_MODEL_TWO_SIDE = $0B52;
+ GL_LIGHT_MODEL_AMBIENT = $0B53;
+ GL_SHADE_MODEL = $0B54;
+ GL_COLOR_MATERIAL_FACE = $0B55;
+ GL_COLOR_MATERIAL_PARAMETER = $0B56;
+ GL_COLOR_MATERIAL = $0B57;
+ GL_FOG = $0B60;
+ GL_FOG_INDEX = $0B61;
+ GL_FOG_DENSITY = $0B62;
+ GL_FOG_START = $0B63;
+ GL_FOG_END = $0B64;
+ GL_FOG_MODE = $0B65;
+ GL_FOG_COLOR = $0B66;
+ GL_DEPTH_RANGE = $0B70;
+ GL_DEPTH_TEST = $0B71;
+ GL_DEPTH_WRITEMASK = $0B72;
+ GL_DEPTH_CLEAR_VALUE = $0B73;
+ GL_DEPTH_FUNC = $0B74;
+ GL_ACCUM_CLEAR_VALUE = $0B80;
+ GL_STENCIL_TEST = $0B90;
+ GL_STENCIL_CLEAR_VALUE = $0B91;
+ GL_STENCIL_FUNC = $0B92;
+ GL_STENCIL_VALUE_MASK = $0B93;
+ GL_STENCIL_FAIL = $0B94;
+ GL_STENCIL_PASS_DEPTH_FAIL = $0B95;
+ GL_STENCIL_PASS_DEPTH_PASS = $0B96;
+ GL_STENCIL_REF = $0B97;
+ GL_STENCIL_WRITEMASK = $0B98;
+ GL_MATRIX_MODE = $0BA0;
+ GL_NORMALIZE = $0BA1;
+ GL_VIEWPORT = $0BA2;
+ GL_MODELVIEW_STACK_DEPTH = $0BA3;
+ GL_PROJECTION_STACK_DEPTH = $0BA4;
+ GL_TEXTURE_STACK_DEPTH = $0BA5;
+ GL_MODELVIEW_MATRIX = $0BA6;
+ GL_PROJECTION_MATRIX = $0BA7;
+ GL_TEXTURE_MATRIX = $0BA8;
+ GL_ATTRIB_STACK_DEPTH = $0BB0;
+ GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1;
+ GL_ALPHA_TEST = $0BC0;
+ GL_ALPHA_TEST_FUNC = $0BC1;
+ GL_ALPHA_TEST_REF = $0BC2;
+ GL_DITHER = $0BD0;
+ GL_BLEND_DST = $0BE0;
+ GL_BLEND_SRC = $0BE1;
+ GL_BLEND = $0BE2;
+ GL_LOGIC_OP_MODE = $0BF0;
+ GL_INDEX_LOGIC_OP = $0BF1;
+ GL_COLOR_LOGIC_OP = $0BF2;
+ GL_AUX_BUFFERS = $0C00;
+ GL_DRAW_BUFFER = $0C01;
+ GL_READ_BUFFER = $0C02;
+ GL_SCISSOR_BOX = $0C10;
+ GL_SCISSOR_TEST = $0C11;
+ GL_INDEX_CLEAR_VALUE = $0C20;
+ GL_INDEX_WRITEMASK = $0C21;
+ GL_COLOR_CLEAR_VALUE = $0C22;
+ GL_COLOR_WRITEMASK = $0C23;
+ GL_INDEX_MODE = $0C30;
+ GL_RGBA_MODE = $0C31;
+ GL_DOUBLEBUFFER = $0C32;
+ GL_STEREO = $0C33;
+ GL_RENDER_MODE = $0C40;
+ GL_PERSPECTIVE_CORRECTION_HINT = $0C50;
+ GL_POINT_SMOOTH_HINT = $0C51;
+ GL_LINE_SMOOTH_HINT = $0C52;
+ GL_POLYGON_SMOOTH_HINT = $0C53;
+ GL_FOG_HINT = $0C54;
+ GL_TEXTURE_GEN_S = $0C60;
+ GL_TEXTURE_GEN_T = $0C61;
+ GL_TEXTURE_GEN_R = $0C62;
+ GL_TEXTURE_GEN_Q = $0C63;
+ GL_PIXEL_MAP_I_TO_I = $0C70;
+ GL_PIXEL_MAP_S_TO_S = $0C71;
+ GL_PIXEL_MAP_I_TO_R = $0C72;
+ GL_PIXEL_MAP_I_TO_G = $0C73;
+ GL_PIXEL_MAP_I_TO_B = $0C74;
+ GL_PIXEL_MAP_I_TO_A = $0C75;
+ GL_PIXEL_MAP_R_TO_R = $0C76;
+ GL_PIXEL_MAP_G_TO_G = $0C77;
+ GL_PIXEL_MAP_B_TO_B = $0C78;
+ GL_PIXEL_MAP_A_TO_A = $0C79;
+ GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0;
+ GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1;
+ GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2;
+ GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3;
+ GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4;
+ GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5;
+ GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6;
+ GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7;
+ GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8;
+ GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9;
+ GL_UNPACK_SWAP_BYTES = $0CF0;
+ GL_UNPACK_LSB_FIRST = $0CF1;
+ GL_UNPACK_ROW_LENGTH = $0CF2;
+ GL_UNPACK_SKIP_ROWS = $0CF3;
+ GL_UNPACK_SKIP_PIXELS = $0CF4;
+ GL_UNPACK_ALIGNMENT = $0CF5;
+ GL_PACK_SWAP_BYTES = $0D00;
+ GL_PACK_LSB_FIRST = $0D01;
+ GL_PACK_ROW_LENGTH = $0D02;
+ GL_PACK_SKIP_ROWS = $0D03;
+ GL_PACK_SKIP_PIXELS = $0D04;
+ GL_PACK_ALIGNMENT = $0D05;
+ GL_MAP_COLOR = $0D10;
+ GL_MAP_STENCIL = $0D11;
+ GL_INDEX_SHIFT = $0D12;
+ GL_INDEX_OFFSET = $0D13;
+ GL_RED_SCALE = $0D14;
+ GL_RED_BIAS = $0D15;
+ GL_ZOOM_X = $0D16;
+ GL_ZOOM_Y = $0D17;
+ GL_GREEN_SCALE = $0D18;
+ GL_GREEN_BIAS = $0D19;
+ GL_BLUE_SCALE = $0D1A;
+ GL_BLUE_BIAS = $0D1B;
+ GL_ALPHA_SCALE = $0D1C;
+ GL_ALPHA_BIAS = $0D1D;
+ GL_DEPTH_SCALE = $0D1E;
+ GL_DEPTH_BIAS = $0D1F;
+ GL_MAX_EVAL_ORDER = $0D30;
+ GL_MAX_LIGHTS = $0D31;
+ GL_MAX_CLIP_PLANES = $0D32;
+ GL_MAX_TEXTURE_SIZE = $0D33;
+ GL_MAX_PIXEL_MAP_TABLE = $0D34;
+ GL_MAX_ATTRIB_STACK_DEPTH = $0D35;
+ GL_MAX_MODELVIEW_STACK_DEPTH = $0D36;
+ GL_MAX_NAME_STACK_DEPTH = $0D37;
+ GL_MAX_PROJECTION_STACK_DEPTH = $0D38;
+ GL_MAX_TEXTURE_STACK_DEPTH = $0D39;
+ GL_MAX_VIEWPORT_DIMS = $0D3A;
+ GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B;
+ GL_SUBPIXEL_BITS = $0D50;
+ GL_INDEX_BITS = $0D51;
+ GL_RED_BITS = $0D52;
+ GL_GREEN_BITS = $0D53;
+ GL_BLUE_BITS = $0D54;
+ GL_ALPHA_BITS = $0D55;
+ GL_DEPTH_BITS = $0D56;
+ GL_STENCIL_BITS = $0D57;
+ GL_ACCUM_RED_BITS = $0D58;
+ GL_ACCUM_GREEN_BITS = $0D59;
+ GL_ACCUM_BLUE_BITS = $0D5A;
+ GL_ACCUM_ALPHA_BITS = $0D5B;
+ GL_NAME_STACK_DEPTH = $0D70;
+ GL_AUTO_NORMAL = $0D80;
+ GL_MAP1_COLOR_4 = $0D90;
+ GL_MAP1_INDEX = $0D91;
+ GL_MAP1_NORMAL = $0D92;
+ GL_MAP1_TEXTURE_COORD_1 = $0D93;
+ GL_MAP1_TEXTURE_COORD_2 = $0D94;
+ GL_MAP1_TEXTURE_COORD_3 = $0D95;
+ GL_MAP1_TEXTURE_COORD_4 = $0D96;
+ GL_MAP1_VERTEX_3 = $0D97;
+ GL_MAP1_VERTEX_4 = $0D98;
+ GL_MAP2_COLOR_4 = $0DB0;
+ GL_MAP2_INDEX = $0DB1;
+ GL_MAP2_NORMAL = $0DB2;
+ GL_MAP2_TEXTURE_COORD_1 = $0DB3;
+ GL_MAP2_TEXTURE_COORD_2 = $0DB4;
+ GL_MAP2_TEXTURE_COORD_3 = $0DB5;
+ GL_MAP2_TEXTURE_COORD_4 = $0DB6;
+ GL_MAP2_VERTEX_3 = $0DB7;
+ GL_MAP2_VERTEX_4 = $0DB8;
+ GL_MAP1_GRID_DOMAIN = $0DD0;
+ GL_MAP1_GRID_SEGMENTS = $0DD1;
+ GL_MAP2_GRID_DOMAIN = $0DD2;
+ GL_MAP2_GRID_SEGMENTS = $0DD3;
+ GL_TEXTURE_1D = $0DE0;
+ GL_TEXTURE_2D = $0DE1;
+ GL_FEEDBACK_BUFFER_POINTER = $0DF0;
+ GL_FEEDBACK_BUFFER_SIZE = $0DF1;
+ GL_FEEDBACK_BUFFER_TYPE = $0DF2;
+ GL_SELECTION_BUFFER_POINTER = $0DF3;
+ GL_SELECTION_BUFFER_SIZE = $0DF4;
+ // GL_TEXTURE_BINDING_1D
+ // GL_TEXTURE_BINDING_2D
+ // GL_VERTEX_ARRAY
+ // GL_NORMAL_ARRAY
+ // GL_COLOR_ARRAY
+ // GL_INDEX_ARRAY
+ // GL_TEXTURE_COORD_ARRAY
+ // GL_EDGE_FLAG_ARRAY
+ // GL_VERTEX_ARRAY_SIZE
+ // GL_VERTEX_ARRAY_TYPE
+ // GL_VERTEX_ARRAY_STRIDE
+ // GL_NORMAL_ARRAY_TYPE
+ // GL_NORMAL_ARRAY_STRIDE
+ // GL_COLOR_ARRAY_SIZE
+ // GL_COLOR_ARRAY_TYPE
+ // GL_COLOR_ARRAY_STRIDE
+ // GL_INDEX_ARRAY_TYPE
+ // GL_INDEX_ARRAY_STRIDE
+ // GL_TEXTURE_COORD_ARRAY_SIZE
+ // GL_TEXTURE_COORD_ARRAY_TYPE
+ // GL_TEXTURE_COORD_ARRAY_STRIDE
+ // GL_EDGE_FLAG_ARRAY_STRIDE
+ // GL_POLYGON_OFFSET_FACTOR
+ // GL_POLYGON_OFFSET_UNITS
+
+ // GetTextureParameter
+ // GL_TEXTURE_MAG_FILTER
+ // GL_TEXTURE_MIN_FILTER
+ // GL_TEXTURE_WRAP_S
+ // GL_TEXTURE_WRAP_T
+ GL_TEXTURE_WIDTH = $1000;
+ GL_TEXTURE_HEIGHT = $1001;
+ GL_TEXTURE_INTERNAL_FORMAT = $1003;
+ GL_TEXTURE_BORDER_COLOR = $1004;
+ GL_TEXTURE_BORDER = $1005;
+ // GL_TEXTURE_RED_SIZE
+ // GL_TEXTURE_GREEN_SIZE
+ // GL_TEXTURE_BLUE_SIZE
+ // GL_TEXTURE_ALPHA_SIZE
+ // GL_TEXTURE_LUMINANCE_SIZE
+ // GL_TEXTURE_INTENSITY_SIZE
+ // GL_TEXTURE_PRIORITY
+ // GL_TEXTURE_RESIDENT
+
+ // HintMode
+ GL_DONT_CARE = $1100;
+ GL_FASTEST = $1101;
+ GL_NICEST = $1102;
+
+ // HintTarget
+ // GL_PERSPECTIVE_CORRECTION_HINT
+ // GL_POINT_SMOOTH_HINT
+ // GL_LINE_SMOOTH_HINT
+ // GL_POLYGON_SMOOTH_HINT
+ // GL_FOG_HINT
+
+ // IndexPointerType
+ // GL_SHORT
+ // GL_INT
+ // GL_FLOAT
+ // GL_DOUBLE
+
+ // LightModelParameter
+ // GL_LIGHT_MODEL_AMBIENT
+ // GL_LIGHT_MODEL_LOCAL_VIEWER
+ // GL_LIGHT_MODEL_TWO_SIDE
+
+ // LightName
+ GL_LIGHT0 = $4000;
+ GL_LIGHT1 = $4001;
+ GL_LIGHT2 = $4002;
+ GL_LIGHT3 = $4003;
+ GL_LIGHT4 = $4004;
+ GL_LIGHT5 = $4005;
+ GL_LIGHT6 = $4006;
+ GL_LIGHT7 = $4007;
+
+ // LightParameter
+ GL_AMBIENT = $1200;
+ GL_DIFFUSE = $1201;
+ GL_SPECULAR = $1202;
+ GL_POSITION = $1203;
+ GL_SPOT_DIRECTION = $1204;
+ GL_SPOT_EXPONENT = $1205;
+ GL_SPOT_CUTOFF = $1206;
+ GL_CONSTANT_ATTENUATION = $1207;
+ GL_LINEAR_ATTENUATION = $1208;
+ GL_QUADRATIC_ATTENUATION = $1209;
+
+ // InterleavedArrays
+ // GL_V2F
+ // GL_V3F
+ // GL_C4UB_V2F
+ // GL_C4UB_V3F
+ // GL_C3F_V3F
+ // GL_N3F_V3F
+ // GL_C4F_N3F_V3F
+ // GL_T2F_V3F
+ // GL_T4F_V4F
+ // GL_T2F_C4UB_V3F
+ // GL_T2F_C3F_V3F
+ // GL_T2F_N3F_V3F
+ // GL_T2F_C4F_N3F_V3F
+ // GL_T4F_C4F_N3F_V4F
+
+ // ListMode
+ GL_COMPILE = $1300;
+ GL_COMPILE_AND_EXECUTE = $1301;
+
+ // ListNameType
+ // GL_BYTE
+ // GL_UNSIGNED_BYTE
+ // GL_SHORT
+ // GL_UNSIGNED_SHORT
+ // GL_INT
+ // GL_UNSIGNED_INT
+ // GL_FLOAT
+ // GL_2_BYTES
+ // GL_3_BYTES
+ // GL_4_BYTES
+
+ // LogicOp
+ GL_CLEAR = $1500;
+ GL_AND = $1501;
+ GL_AND_REVERSE = $1502;
+ GL_COPY = $1503;
+ GL_AND_INVERTED = $1504;
+ GL_NOOP = $1505;
+ GL_XOR = $1506;
+ GL_OR = $1507;
+ GL_NOR = $1508;
+ GL_EQUIV = $1509;
+ GL_INVERT = $150A;
+ GL_OR_REVERSE = $150B;
+ GL_COPY_INVERTED = $150C;
+ GL_OR_INVERTED = $150D;
+ GL_NAND = $150E;
+ GL_SET = $150F;
+
+ // MapTarget
+ // GL_MAP1_COLOR_4
+ // GL_MAP1_INDEX
+ // GL_MAP1_NORMAL
+ // GL_MAP1_TEXTURE_COORD_1
+ // GL_MAP1_TEXTURE_COORD_2
+ // GL_MAP1_TEXTURE_COORD_3
+ // GL_MAP1_TEXTURE_COORD_4
+ // GL_MAP1_VERTEX_3
+ // GL_MAP1_VERTEX_4
+ // GL_MAP2_COLOR_4
+ // GL_MAP2_INDEX
+ // GL_MAP2_NORMAL
+ // GL_MAP2_TEXTURE_COORD_1
+ // GL_MAP2_TEXTURE_COORD_2
+ // GL_MAP2_TEXTURE_COORD_3
+ // GL_MAP2_TEXTURE_COORD_4
+ // GL_MAP2_VERTEX_3
+ // GL_MAP2_VERTEX_4
+
+ // MaterialFace
+ // GL_FRONT
+ // GL_BACK
+ // GL_FRONT_AND_BACK
+
+ // MaterialParameter
+ GL_EMISSION = $1600;
+ GL_SHININESS = $1601;
+ GL_AMBIENT_AND_DIFFUSE = $1602;
+ GL_COLOR_INDEXES = $1603;
+ // GL_AMBIENT
+ // GL_DIFFUSE
+ // GL_SPECULAR
+
+ // MatrixMode
+ GL_MODELVIEW = $1700;
+ GL_PROJECTION = $1701;
+ GL_TEXTURE = $1702;
+
+ // MeshMode1
+ // GL_POINT
+ // GL_LINE
+
+ // MeshMode2
+ // GL_POINT
+ // GL_LINE
+ // GL_FILL
+
+ // NormalPointerType
+ // GL_BYTE
+ // GL_SHORT
+ // GL_INT
+ // GL_FLOAT
+ // GL_DOUBLE
+
+ // PixelCopyType
+ GL_COLOR = $1800;
+ GL_DEPTH = $1801;
+ GL_STENCIL = $1802;
+
+ // PixelFormat
+ GL_COLOR_INDEX = $1900;
+ GL_STENCIL_INDEX = $1901;
+ GL_DEPTH_COMPONENT = $1902;
+ GL_RED = $1903;
+ GL_GREEN = $1904;
+ GL_BLUE = $1905;
+ GL_ALPHA = $1906;
+ GL_RGB = $1907;
+ GL_RGBA = $1908;
+ GL_LUMINANCE = $1909;
+ GL_LUMINANCE_ALPHA = $190A;
+
+ // PixelMap
+ // GL_PIXEL_MAP_I_TO_I
+ // GL_PIXEL_MAP_S_TO_S
+ // GL_PIXEL_MAP_I_TO_R
+ // GL_PIXEL_MAP_I_TO_G
+ // GL_PIXEL_MAP_I_TO_B
+ // GL_PIXEL_MAP_I_TO_A
+ // GL_PIXEL_MAP_R_TO_R
+ // GL_PIXEL_MAP_G_TO_G
+ // GL_PIXEL_MAP_B_TO_B
+ // GL_PIXEL_MAP_A_TO_A
+
+ // PixelStore
+ // GL_UNPACK_SWAP_BYTES
+ // GL_UNPACK_LSB_FIRST
+ // GL_UNPACK_ROW_LENGTH
+ // GL_UNPACK_SKIP_ROWS
+ // GL_UNPACK_SKIP_PIXELS
+ // GL_UNPACK_ALIGNMENT
+ // GL_PACK_SWAP_BYTES
+ // GL_PACK_LSB_FIRST
+ // GL_PACK_ROW_LENGTH
+ // GL_PACK_SKIP_ROWS
+ // GL_PACK_SKIP_PIXELS
+ // GL_PACK_ALIGNMENT
+
+ // PixelTransfer
+ // GL_MAP_COLOR
+ // GL_MAP_STENCIL
+ // GL_INDEX_SHIFT
+ // GL_INDEX_OFFSET
+ // GL_RED_SCALE
+ // GL_RED_BIAS
+ // GL_GREEN_SCALE
+ // GL_GREEN_BIAS
+ // GL_BLUE_SCALE
+ // GL_BLUE_BIAS
+ // GL_ALPHA_SCALE
+ // GL_ALPHA_BIAS
+ // GL_DEPTH_SCALE
+ // GL_DEPTH_BIAS
+
+ // PixelType
+ GL_BITMAP = $1A00;
+ // GL_BYTE
+ // GL_UNSIGNED_BYTE
+ // GL_SHORT
+ // GL_UNSIGNED_SHORT
+ // GL_INT
+ // GL_UNSIGNED_INT
+ // GL_FLOAT
+
+ // PolygonMode
+ GL_POINT = $1B00;
+ GL_LINE = $1B01;
+ GL_FILL = $1B02;
+
+ // ReadBufferMode
+ // GL_FRONT_LEFT
+ // GL_FRONT_RIGHT
+ // GL_BACK_LEFT
+ // GL_BACK_RIGHT
+ // GL_FRONT
+ // GL_BACK
+ // GL_LEFT
+ // GL_RIGHT
+ // GL_AUX0
+ // GL_AUX1
+ // GL_AUX2
+ // GL_AUX3
+
+ // RenderingMode
+ GL_RENDER = $1C00;
+ GL_FEEDBACK = $1C01;
+ GL_SELECT = $1C02;
+
+ // ShadingModel
+ GL_FLAT = $1D00;
+ GL_SMOOTH = $1D01;
+
+ // StencilFunction
+ // GL_NEVER
+ // GL_LESS
+ // GL_EQUAL
+ // GL_LEQUAL
+ // GL_GREATER
+ // GL_NOTEQUAL
+ // GL_GEQUAL
+ // GL_ALWAYS
+
+ // StencilOp
+ // GL_ZERO
+ GL_KEEP = $1E00;
+ GL_REPLACE = $1E01;
+ GL_INCR = $1E02;
+ GL_DECR = $1E03;
+ // GL_INVERT
+
+ // StringName
+ GL_VENDOR = $1F00;
+ GL_RENDERER = $1F01;
+ GL_VERSION = $1F02;
+ GL_EXTENSIONS = $1F03;
+
+ // TextureCoordName
+ GL_S = $2000;
+ GL_T = $2001;
+ GL_R = $2002;
+ GL_Q = $2003;
+
+ // TexCoordPointerType
+ // GL_SHORT
+ // GL_INT
+ // GL_FLOAT
+ // GL_DOUBLE
+
+ // TextureEnvMode
+ GL_MODULATE = $2100;
+ GL_DECAL = $2101;
+ // GL_BLEND
+ // GL_REPLACE
+
+ // TextureEnvParameter
+ GL_TEXTURE_ENV_MODE = $2200;
+ GL_TEXTURE_ENV_COLOR = $2201;
+
+ // TextureEnvTarget
+ GL_TEXTURE_ENV = $2300;
+
+ // TextureGenMode
+ GL_EYE_LINEAR = $2400;
+ GL_OBJECT_LINEAR = $2401;
+ GL_SPHERE_MAP = $2402;
+
+ // TextureGenParameter
+ GL_TEXTURE_GEN_MODE = $2500;
+ GL_OBJECT_PLANE = $2501;
+ GL_EYE_PLANE = $2502;
+
+ // TextureMagFilter
+ GL_NEAREST = $2600;
+ GL_LINEAR = $2601;
+
+ // TextureMinFilter
+ // GL_NEAREST
+ // GL_LINEAR
+ GL_NEAREST_MIPMAP_NEAREST = $2700;
+ GL_LINEAR_MIPMAP_NEAREST = $2701;
+ GL_NEAREST_MIPMAP_LINEAR = $2702;
+ GL_LINEAR_MIPMAP_LINEAR = $2703;
+
+ // TextureParameterName
+ GL_TEXTURE_MAG_FILTER = $2800;
+ GL_TEXTURE_MIN_FILTER = $2801;
+ GL_TEXTURE_WRAP_S = $2802;
+ GL_TEXTURE_WRAP_T = $2803;
+ // GL_TEXTURE_BORDER_COLOR
+ // GL_TEXTURE_PRIORITY
+
+ // TextureTarget
+ // GL_TEXTURE_1D
+ // GL_TEXTURE_2D
+ // GL_PROXY_TEXTURE_1D
+ // GL_PROXY_TEXTURE_2D
+
+ // TextureWrapMode
+ GL_CLAMP = $2900;
+ GL_REPEAT = $2901;
+
+ // VertexPointerType
+ // GL_SHORT
+ // GL_INT
+ // GL_FLOAT
+ // GL_DOUBLE
+
+ // ClientAttribMask
+ GL_CLIENT_PIXEL_STORE_BIT = $00000001;
+ GL_CLIENT_VERTEX_ARRAY_BIT = $00000002;
+ GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF;
+
+ // polygon_offset
+ GL_POLYGON_OFFSET_FACTOR = $8038;
+ GL_POLYGON_OFFSET_UNITS = $2A00;
+ GL_POLYGON_OFFSET_POINT = $2A01;
+ GL_POLYGON_OFFSET_LINE = $2A02;
+ GL_POLYGON_OFFSET_FILL = $8037;
+
+ // texture
+ GL_ALPHA4 = $803B;
+ GL_ALPHA8 = $803C;
+ GL_ALPHA12 = $803D;
+ GL_ALPHA16 = $803E;
+ GL_LUMINANCE4 = $803F;
+ GL_LUMINANCE8 = $8040;
+ GL_LUMINANCE12 = $8041;
+ GL_LUMINANCE16 = $8042;
+ GL_LUMINANCE4_ALPHA4 = $8043;
+ GL_LUMINANCE6_ALPHA2 = $8044;
+ GL_LUMINANCE8_ALPHA8 = $8045;
+ GL_LUMINANCE12_ALPHA4 = $8046;
+ GL_LUMINANCE12_ALPHA12 = $8047;
+ GL_LUMINANCE16_ALPHA16 = $8048;
+ GL_INTENSITY = $8049;
+ GL_INTENSITY4 = $804A;
+ GL_INTENSITY8 = $804B;
+ GL_INTENSITY12 = $804C;
+ GL_INTENSITY16 = $804D;
+ GL_R3_G3_B2 = $2A10;
+ GL_RGB4 = $804F;
+ GL_RGB5 = $8050;
+ GL_RGB8 = $8051;
+ GL_RGB10 = $8052;
+ GL_RGB12 = $8053;
+ GL_RGB16 = $8054;
+ GL_RGBA2 = $8055;
+ GL_RGBA4 = $8056;
+ GL_RGB5_A1 = $8057;
+ GL_RGBA8 = $8058;
+ GL_RGB10_A2 = $8059;
+ GL_RGBA12 = $805A;
+ GL_RGBA16 = $805B;
+ GL_TEXTURE_RED_SIZE = $805C;
+ GL_TEXTURE_GREEN_SIZE = $805D;
+ GL_TEXTURE_BLUE_SIZE = $805E;
+ GL_TEXTURE_ALPHA_SIZE = $805F;
+ GL_TEXTURE_LUMINANCE_SIZE = $8060;
+ GL_TEXTURE_INTENSITY_SIZE = $8061;
+ GL_PROXY_TEXTURE_1D = $8063;
+ GL_PROXY_TEXTURE_2D = $8064;
+
+ // texture_object
+ GL_TEXTURE_PRIORITY = $8066;
+ GL_TEXTURE_RESIDENT = $8067;
+ GL_TEXTURE_BINDING_1D = $8068;
+ GL_TEXTURE_BINDING_2D = $8069;
+
+ // vertex_array
+ GL_VERTEX_ARRAY = $8074;
+ GL_NORMAL_ARRAY = $8075;
+ GL_COLOR_ARRAY = $8076;
+ GL_INDEX_ARRAY = $8077;
+ GL_TEXTURE_COORD_ARRAY = $8078;
+ GL_EDGE_FLAG_ARRAY = $8079;
+ GL_VERTEX_ARRAY_SIZE = $807A;
+ GL_VERTEX_ARRAY_TYPE = $807B;
+ GL_VERTEX_ARRAY_STRIDE = $807C;
+ GL_NORMAL_ARRAY_TYPE = $807E;
+ GL_NORMAL_ARRAY_STRIDE = $807F;
+ GL_COLOR_ARRAY_SIZE = $8081;
+ GL_COLOR_ARRAY_TYPE = $8082;
+ GL_COLOR_ARRAY_STRIDE = $8083;
+ GL_INDEX_ARRAY_TYPE = $8085;
+ GL_INDEX_ARRAY_STRIDE = $8086;
+ GL_TEXTURE_COORD_ARRAY_SIZE = $8088;
+ GL_TEXTURE_COORD_ARRAY_TYPE = $8089;
+ GL_TEXTURE_COORD_ARRAY_STRIDE = $808A;
+ GL_EDGE_FLAG_ARRAY_STRIDE = $808C;
+ GL_VERTEX_ARRAY_POINTER = $808E;
+ GL_NORMAL_ARRAY_POINTER = $808F;
+ GL_COLOR_ARRAY_POINTER = $8090;
+ GL_INDEX_ARRAY_POINTER = $8091;
+ GL_TEXTURE_COORD_ARRAY_POINTER = $8092;
+ GL_EDGE_FLAG_ARRAY_POINTER = $8093;
+ GL_V2F = $2A20;
+ GL_V3F = $2A21;
+ GL_C4UB_V2F = $2A22;
+ GL_C4UB_V3F = $2A23;
+ GL_C3F_V3F = $2A24;
+ GL_N3F_V3F = $2A25;
+ GL_C4F_N3F_V3F = $2A26;
+ GL_T2F_V3F = $2A27;
+ GL_T4F_V4F = $2A28;
+ GL_T2F_C4UB_V3F = $2A29;
+ GL_T2F_C3F_V3F = $2A2A;
+ GL_T2F_N3F_V3F = $2A2B;
+ GL_T2F_C4F_N3F_V3F = $2A2C;
+ GL_T4F_C4F_N3F_V4F = $2A2D;
+
+ // Extensions
+ GL_EXT_vertex_array = 1;
+ GL_WIN_swap_hint = 1;
+ GL_EXT_bgra = 1;
+ GL_EXT_paletted_texture = 1;
+
+ // EXT_vertex_array
+ GL_VERTEX_ARRAY_EXT = $8074;
+ GL_NORMAL_ARRAY_EXT = $8075;
+ GL_COLOR_ARRAY_EXT = $8076;
+ GL_INDEX_ARRAY_EXT = $8077;
+ GL_TEXTURE_COORD_ARRAY_EXT = $8078;
+ GL_EDGE_FLAG_ARRAY_EXT = $8079;
+ GL_VERTEX_ARRAY_SIZE_EXT = $807A;
+ GL_VERTEX_ARRAY_TYPE_EXT = $807B;
+ GL_VERTEX_ARRAY_STRIDE_EXT = $807C;
+ GL_VERTEX_ARRAY_COUNT_EXT = $807D;
+ GL_NORMAL_ARRAY_TYPE_EXT = $807E;
+ GL_NORMAL_ARRAY_STRIDE_EXT = $807F;
+ GL_NORMAL_ARRAY_COUNT_EXT = $8080;
+ GL_COLOR_ARRAY_SIZE_EXT = $8081;
+ GL_COLOR_ARRAY_TYPE_EXT = $8082;
+ GL_COLOR_ARRAY_STRIDE_EXT = $8083;
+ GL_COLOR_ARRAY_COUNT_EXT = $8084;
+ GL_INDEX_ARRAY_TYPE_EXT = $8085;
+ GL_INDEX_ARRAY_STRIDE_EXT = $8086;
+ GL_INDEX_ARRAY_COUNT_EXT = $8087;
+ GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088;
+ GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089;
+ GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A;
+ GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B;
+ GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C;
+ GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D;
+ GL_VERTEX_ARRAY_POINTER_EXT = $808E;
+ GL_NORMAL_ARRAY_POINTER_EXT = $808F;
+ GL_COLOR_ARRAY_POINTER_EXT = $8090;
+ GL_INDEX_ARRAY_POINTER_EXT = $8091;
+ GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092;
+ GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093;
+ GL_DOUBLE_EXT = GL_DOUBLE;
+
+ // EXT_bgra
+ GL_BGR_EXT = $80E0;
+ GL_BGRA_EXT = $80E1;
+
+ // EXT_paletted_texture
+
+ // These must match the GL_COLOR_TABLE_*_SGI enumerants
+ GL_COLOR_TABLE_FORMAT_EXT = $80D8;
+ GL_COLOR_TABLE_WIDTH_EXT = $80D9;
+ GL_COLOR_TABLE_RED_SIZE_EXT = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF;
+
+ GL_COLOR_INDEX1_EXT = $80E2;
+ GL_COLOR_INDEX2_EXT = $80E3;
+ GL_COLOR_INDEX4_EXT = $80E4;
+ GL_COLOR_INDEX8_EXT = $80E5;
+ GL_COLOR_INDEX12_EXT = $80E6;
+ GL_COLOR_INDEX16_EXT = $80E7;
+
+ // For compatibility with OpenGL v1.0
+ GL_LOGIC_OP = GL_INDEX_LOGIC_OP;
+ GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT;
+
+{******************************************************************************}
+
+var
+ glAccum: procedure(op: GLenum; value: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAlphaFunc: procedure(func: GLenum; ref: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAreTexturesResident: function (n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glArrayElement: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBegin: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindTexture: procedure(target: GLenum; texture: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBitmap: procedure (width, height: GLsizei; xorig, yorig: GLfloat; xmove, ymove: GLfloat; const bitmap: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBlendFunc: procedure(sfactor, dfactor: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCallList: procedure(list: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCallLists: procedure(n: GLsizei; atype: GLenum; const lists: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClear: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearAccum: procedure(red, green, blue, alpha: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearColor: procedure(red, green, blue, alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearDepth: procedure(depth: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearIndex: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearStencil: procedure(s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClipPlane: procedure(plane: GLenum; const equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3b: procedure(red, green, blue: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3d: procedure(red, green, blue: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3f: procedure(red, green, blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3i: procedure(red, green, blue: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3s: procedure(red, green, blue: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3ub: procedure(red, green, blue: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3ui: procedure(red, green, blue: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3us: procedure(red, green, blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4b: procedure(red, green, blue, alpha: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4d: procedure(red, green, blue, alpha: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4f: procedure(red, green, blue, alpha: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4i: procedure(red, green, blue, alpha: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4s: procedure(red, green, blue, alpha: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ub: procedure(red, green, blue, alpha: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ui: procedure(red, green, blue, alpha: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4us: procedure(red, green, blue, alpha: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorMask: procedure(red, green, blue, alpha: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorMaterial: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyPixels: procedure(x, y: GLint; width, height: GLsizei; atype: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexImage1D: procedure (target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexImage2D: procedure(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexSubImage1D: procedure(target: GLenum; level, xoffset, x, y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset, x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCullFace: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteLists: procedure(list: GLuint; range: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDepthFunc: procedure(func: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDepthMask: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDepthRange: procedure(zNear, zFar: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDisable: procedure(cap: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDisableClientState: procedure(aarray: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawArrays: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawBuffer: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawElements: procedure(mode: GLenum; count: GLsizei; atype: GLenum; const indices: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawPixels: procedure(width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlag: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagPointer: procedure(stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagv: procedure(const flag: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnable: procedure(cap: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnableClientState: procedure(aarray: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnd: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndList: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1d: procedure(u: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1f: procedure(u: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2d: procedure(u, v: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2f: procedure(u, v: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalMesh1: procedure(mode: GLenum; i1, i2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalMesh2: procedure(mode: GLenum; i1, i2, j1, j2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalPoint1: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalPoint2: procedure(i, j: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFeedbackBuffer: procedure(size: GLsizei; atype: GLenum; buffer: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFinish: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFlush: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogiv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFrontFace: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFrustum: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenLists: function(range: GLsizei): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenTextures: procedure(n: GLsizei; textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBooleanv: procedure(pname: GLenum; params: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetClipPlane: procedure(plane: GLenum; equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetDoublev: procedure(pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetError: function: GLenum; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFloatv: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetIntegerv: procedure(pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLightfv: procedure(light, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLightiv: procedure(light, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapdv: procedure(target, query: GLenum; v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapfv: procedure(target, query: GLenum; v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapiv: procedure(target, query: GLenum; v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMaterialfv: procedure(face, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMaterialiv: procedure(face, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapfv: procedure(map: GLenum; values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapuiv: procedure(map: GLenum; values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapusv: procedure(map: GLenum; values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPointerv: procedure(pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPolygonStipple: procedure(mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetString: function(name: GLenum): PChar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexEnvfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexEnviv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGendv: procedure(coord, pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGenfv: procedure(coord, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGeniv: procedure(coord, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexImage: procedure(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexLevelParameterfv: procedure(target: GLenum; level: GLint; pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexLevelParameteriv: procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexParameterfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexParameteriv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glHint: procedure(target, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexd: procedure(c: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexdv: procedure(const c: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexf: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexfv: procedure(const c: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexi: procedure(c: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexiv: procedure(const c: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexs: procedure(c: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexsv: procedure(const c: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexub: procedure(c: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexubv: procedure(const c: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glInitNames: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glInterleavedArrays: procedure(format: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsEnabled: function(cap: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsList: function(list: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsTexture: function(texture: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModelf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModelfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModeli: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModeliv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightf: procedure(light, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightfv: procedure(light, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLighti: procedure(light, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightiv: procedure(light, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLineStipple: procedure(factor: GLint; pattern: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLineWidth: procedure(width: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glListBase: procedure(base: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadIdentity: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLogicOp: procedure(opcode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap1d: procedure(target: GLenum; u1, u2: GLdouble; stride, order: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap1f: procedure(target: GLenum; u1, u2: GLfloat; stride, order: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap2d: procedure(target: GLenum; u1, u2: GLdouble; ustride, uorder: GLint; v1, v2: GLdouble; vstride, vorder: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap2f: procedure(target: GLenum; u1, u2: GLfloat; ustride, uorder: GLint; v1, v2: GLfloat; vstride, vorder: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid1d: procedure(un: GLint; u1, u2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid1f: procedure(un: GLint; u1, u2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid2d: procedure(un: GLint; u1, u2: GLdouble; vn: GLint; v1, v2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid2f: procedure(un: GLint; u1, u2: GLfloat; vn: GLint; v1, v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialf: procedure(face, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialfv: procedure(face, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMateriali: procedure(face, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialiv: procedure(face, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMatrixMode: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNewList: procedure(list: GLuint; mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3b: procedure(nx, ny, nz: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3d: procedure(nx, ny, nz: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3f: procedure(nx, ny, nz: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3i: procedure(nx, ny, nz: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3s: procedure(nx, ny, nz: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glOrtho: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPassThrough: procedure(token: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapfv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapuiv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapusv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelStoref: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelStorei: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelTransferf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelTransferi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelZoom: procedure(xfactor, yfactor: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointSize: procedure(size: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonMode: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonOffset: procedure(factor, units: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonStipple: procedure(const mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPopAttrib: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPopClientAttrib: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPopMatrix: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPopName: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPrioritizeTextures: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushClientAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushMatrix: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2d: procedure(x, y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2f: procedure(x, y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2i: procedure(x, y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2s: procedure(x, y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3d: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3f: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3i: procedure(x, y, z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3s: procedure(x, y, z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4d: procedure(x, y, z, w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4f: procedure(x, y, z, w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4i: procedure(x, y, z, w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4s: procedure(x, y, z, w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRasterPos4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReadBuffer: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReadPixels: procedure(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectd: procedure(x1, y1, x2, y2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectdv: procedure(const v1: PGLdouble; const v2: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectf: procedure(x1, y1, x2, y2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectfv: procedure(const v1: PGLfloat; const v2: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRecti: procedure(x1, y1, x2, y2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectiv: procedure(const v1: PGLint; const v2: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRects: procedure(x1, y1, x2, y2: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRectsv: procedure(const v1: PGLshort; const v2: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRenderMode: function(mode: GLint): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRotated: procedure(angle, x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRotatef: procedure(angle, x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glScaled: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glScalef: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glScissor: procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSelectBuffer: procedure(size: GLsizei; buffer: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShadeModel: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilFunc: procedure(func: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilOp: procedure(fail, zfail, zpass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1d: procedure(s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1f: procedure(s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1i: procedure(s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1s: procedure(s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2d: procedure(s, t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2f: procedure(s, t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2i: procedure(s, t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2s: procedure(s, t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3d: procedure(s, t, r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3f: procedure(s, t, r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3i: procedure(s, t, r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3s: procedure(s, t, r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4d: procedure(s, t, r, q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4f: procedure(s, t, r, q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4i: procedure(s, t, r, q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4s: procedure(s, t, r, q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoordPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvi: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnviv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGend: procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGendv: procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGenf: procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGenfv: procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGeni: procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGeniv: procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexImage1D: procedure(target: GLenum; level, internalformat: GLint; width: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexImage2D: procedure(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameteri: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage1D: procedure(target: GLenum; level, xoffset: GLint; width: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTranslated: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTranslatef: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2d: procedure(x, y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2f: procedure(x, y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2i: procedure(x, y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2s: procedure(x, y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3d: procedure(x, y, z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3f: procedure(x, y, z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3i: procedure(x, y, z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3s: procedure(x, y, z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4d: procedure(x, y, z, w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4f: procedure(x, y, z, w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4i: procedure(x, y, z, w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4s: procedure(x, y, z, w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glViewport: procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ {$IFDEF WINDOWS}
+ ChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ {$ENDIF}
+
+type
+ // EXT_vertex_array
+ PFNGLARRAYELEMENTEXTPROC = procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLDRAWARRAYSEXTPROC = procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLVERTEXPOINTEREXTPROC = procedure(size: GLint; atype: GLenum;
+ stride, count: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLNORMALPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei;
+ const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLCOLORPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; stride, count: GLsizei;
+ const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLINDEXPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei;
+ const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLTEXCOORDPOINTEREXTPROC = procedure(size: GLint; atype: GLenum;
+ stride, count: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLEDGEFLAGPOINTEREXTPROC = procedure(stride, count: GLsizei;
+ const pointer: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLGETPOINTERVEXTPROC = procedure(pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLARRAYELEMENTARRAYEXTPROC = procedure(mode: GLenum; count: GLsizei;
+ const pi: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ // WIN_swap_hint
+ PFNGLADDSWAPHINTRECTWINPROC = procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ // EXT_paletted_texture
+ PFNGLCOLORTABLEEXTPROC = procedure(target, internalFormat: GLenum; width: GLsizei;
+ format, atype: GLenum; const data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLCOLORSUBTABLEEXTPROC = procedure(target: GLenum; start, count: GLsizei;
+ format, atype: GLenum; const data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLGETCOLORTABLEEXTPROC = procedure(target, format, atype: GLenum; data: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLGETCOLORTABLEPARAMETERIVEXTPROC = procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ PFNGLGETCOLORTABLEPARAMETERFVEXTPROC = procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+procedure LoadOpenGL( const dll: PChar );
+procedure FreeOpenGL;
+
+implementation
+
+procedure FreeOpenGL;
+begin
+
+ @glAccum := nil;
+ @glAlphaFunc := nil;
+ @glAreTexturesResident := nil;
+ @glArrayElement := nil;
+ @glBegin := nil;
+ @glBindTexture := nil;
+ @glBitmap := nil;
+ @glBlendFunc := nil;
+ @glCallList := nil;
+ @glCallLists := nil;
+ @glClear := nil;
+ @glClearAccum := nil;
+ @glClearColor := nil;
+ @glClearDepth := nil;
+ @glClearIndex := nil;
+ @glClearStencil := nil;
+ @glClipPlane := nil;
+ @glColor3b := nil;
+ @glColor3bv := nil;
+ @glColor3d := nil;
+ @glColor3dv := nil;
+ @glColor3f := nil;
+ @glColor3fv := nil;
+ @glColor3i := nil;
+ @glColor3iv := nil;
+ @glColor3s := nil;
+ @glColor3sv := nil;
+ @glColor3ub := nil;
+ @glColor3ubv := nil;
+ @glColor3ui := nil;
+ @glColor3uiv := nil;
+ @glColor3us := nil;
+ @glColor3usv := nil;
+ @glColor4b := nil;
+ @glColor4bv := nil;
+ @glColor4d := nil;
+ @glColor4dv := nil;
+ @glColor4f := nil;
+ @glColor4fv := nil;
+ @glColor4i := nil;
+ @glColor4iv := nil;
+ @glColor4s := nil;
+ @glColor4sv := nil;
+ @glColor4ub := nil;
+ @glColor4ubv := nil;
+ @glColor4ui := nil;
+ @glColor4uiv := nil;
+ @glColor4us := nil;
+ @glColor4usv := nil;
+ @glColorMask := nil;
+ @glColorMaterial := nil;
+ @glColorPointer := nil;
+ @glCopyPixels := nil;
+ @glCopyTexImage1D := nil;
+ @glCopyTexImage2D := nil;
+ @glCopyTexSubImage1D := nil;
+ @glCopyTexSubImage2D := nil;
+ @glCullFace := nil;
+ @glDeleteLists := nil;
+ @glDeleteTextures := nil;
+ @glDepthFunc := nil;
+ @glDepthMask := nil;
+ @glDepthRange := nil;
+ @glDisable := nil;
+ @glDisableClientState := nil;
+ @glDrawArrays := nil;
+ @glDrawBuffer := nil;
+ @glDrawElements := nil;
+ @glDrawPixels := nil;
+ @glEdgeFlag := nil;
+ @glEdgeFlagPointer := nil;
+ @glEdgeFlagv := nil;
+ @glEnable := nil;
+ @glEnableClientState := nil;
+ @glEnd := nil;
+ @glEndList := nil;
+ @glEvalCoord1d := nil;
+ @glEvalCoord1dv := nil;
+ @glEvalCoord1f := nil;
+ @glEvalCoord1fv := nil;
+ @glEvalCoord2d := nil;
+ @glEvalCoord2dv := nil;
+ @glEvalCoord2f := nil;
+ @glEvalCoord2fv := nil;
+ @glEvalMesh1 := nil;
+ @glEvalMesh2 := nil;
+ @glEvalPoint1 := nil;
+ @glEvalPoint2 := nil;
+ @glFeedbackBuffer := nil;
+ @glFinish := nil;
+ @glFlush := nil;
+ @glFogf := nil;
+ @glFogfv := nil;
+ @glFogi := nil;
+ @glFogiv := nil;
+ @glFrontFace := nil;
+ @glFrustum := nil;
+ @glGenLists := nil;
+ @glGenTextures := nil;
+ @glGetBooleanv := nil;
+ @glGetClipPlane := nil;
+ @glGetDoublev := nil;
+ @glGetError := nil;
+ @glGetFloatv := nil;
+ @glGetIntegerv := nil;
+ @glGetLightfv := nil;
+ @glGetLightiv := nil;
+ @glGetMapdv := nil;
+ @glGetMapfv := nil;
+ @glGetMapiv := nil;
+ @glGetMaterialfv := nil;
+ @glGetMaterialiv := nil;
+ @glGetPixelMapfv := nil;
+ @glGetPixelMapuiv := nil;
+ @glGetPixelMapusv := nil;
+ @glGetPointerv := nil;
+ @glGetPolygonStipple := nil;
+ @glGetString := nil;
+ @glGetTexEnvfv := nil;
+ @glGetTexEnviv := nil;
+ @glGetTexGendv := nil;
+ @glGetTexGenfv := nil;
+ @glGetTexGeniv := nil;
+ @glGetTexImage := nil;
+ @glGetTexLevelParameterfv := nil;
+ @glGetTexLevelParameteriv := nil;
+ @glGetTexParameterfv := nil;
+ @glGetTexParameteriv := nil;
+ @glHint := nil;
+ @glIndexMask := nil;
+ @glIndexPointer := nil;
+ @glIndexd := nil;
+ @glIndexdv := nil;
+ @glIndexf := nil;
+ @glIndexfv := nil;
+ @glIndexi := nil;
+ @glIndexiv := nil;
+ @glIndexs := nil;
+ @glIndexsv := nil;
+ @glIndexub := nil;
+ @glIndexubv := nil;
+ @glInitNames := nil;
+ @glInterleavedArrays := nil;
+ @glIsEnabled := nil;
+ @glIsList := nil;
+ @glIsTexture := nil;
+ @glLightModelf := nil;
+ @glLightModelfv := nil;
+ @glLightModeli := nil;
+ @glLightModeliv := nil;
+ @glLightf := nil;
+ @glLightfv := nil;
+ @glLighti := nil;
+ @glLightiv := nil;
+ @glLineStipple := nil;
+ @glLineWidth := nil;
+ @glListBase := nil;
+ @glLoadIdentity := nil;
+ @glLoadMatrixd := nil;
+ @glLoadMatrixf := nil;
+ @glLoadName := nil;
+ @glLogicOp := nil;
+ @glMap1d := nil;
+ @glMap1f := nil;
+ @glMap2d := nil;
+ @glMap2f := nil;
+ @glMapGrid1d := nil;
+ @glMapGrid1f := nil;
+ @glMapGrid2d := nil;
+ @glMapGrid2f := nil;
+ @glMaterialf := nil;
+ @glMaterialfv := nil;
+ @glMateriali := nil;
+ @glMaterialiv := nil;
+ @glMatrixMode := nil;
+ @glMultMatrixd := nil;
+ @glMultMatrixf := nil;
+ @glNewList := nil;
+ @glNormal3b := nil;
+ @glNormal3bv := nil;
+ @glNormal3d := nil;
+ @glNormal3dv := nil;
+ @glNormal3f := nil;
+ @glNormal3fv := nil;
+ @glNormal3i := nil;
+ @glNormal3iv := nil;
+ @glNormal3s := nil;
+ @glNormal3sv := nil;
+ @glNormalPointer := nil;
+ @glOrtho := nil;
+ @glPassThrough := nil;
+ @glPixelMapfv := nil;
+ @glPixelMapuiv := nil;
+ @glPixelMapusv := nil;
+ @glPixelStoref := nil;
+ @glPixelStorei := nil;
+ @glPixelTransferf := nil;
+ @glPixelTransferi := nil;
+ @glPixelZoom := nil;
+ @glPointSize := nil;
+ @glPolygonMode := nil;
+ @glPolygonOffset := nil;
+ @glPolygonStipple := nil;
+ @glPopAttrib := nil;
+ @glPopClientAttrib := nil;
+ @glPopMatrix := nil;
+ @glPopName := nil;
+ @glPrioritizeTextures := nil;
+ @glPushAttrib := nil;
+ @glPushClientAttrib := nil;
+ @glPushMatrix := nil;
+ @glPushName := nil;
+ @glRasterPos2d := nil;
+ @glRasterPos2dv := nil;
+ @glRasterPos2f := nil;
+ @glRasterPos2fv := nil;
+ @glRasterPos2i := nil;
+ @glRasterPos2iv := nil;
+ @glRasterPos2s := nil;
+ @glRasterPos2sv := nil;
+ @glRasterPos3d := nil;
+ @glRasterPos3dv := nil;
+ @glRasterPos3f := nil;
+ @glRasterPos3fv := nil;
+ @glRasterPos3i := nil;
+ @glRasterPos3iv := nil;
+ @glRasterPos3s := nil;
+ @glRasterPos3sv := nil;
+ @glRasterPos4d := nil;
+ @glRasterPos4dv := nil;
+ @glRasterPos4f := nil;
+ @glRasterPos4fv := nil;
+ @glRasterPos4i := nil;
+ @glRasterPos4iv := nil;
+ @glRasterPos4s := nil;
+ @glRasterPos4sv := nil;
+ @glReadBuffer := nil;
+ @glReadPixels := nil;
+ @glRectd := nil;
+ @glRectdv := nil;
+ @glRectf := nil;
+ @glRectfv := nil;
+ @glRecti := nil;
+ @glRectiv := nil;
+ @glRects := nil;
+ @glRectsv := nil;
+ @glRenderMode := nil;
+ @glRotated := nil;
+ @glRotatef := nil;
+ @glScaled := nil;
+ @glScalef := nil;
+ @glScissor := nil;
+ @glSelectBuffer := nil;
+ @glShadeModel := nil;
+ @glStencilFunc := nil;
+ @glStencilMask := nil;
+ @glStencilOp := nil;
+ @glTexCoord1d := nil;
+ @glTexCoord1dv := nil;
+ @glTexCoord1f := nil;
+ @glTexCoord1fv := nil;
+ @glTexCoord1i := nil;
+ @glTexCoord1iv := nil;
+ @glTexCoord1s := nil;
+ @glTexCoord1sv := nil;
+ @glTexCoord2d := nil;
+ @glTexCoord2dv := nil;
+ @glTexCoord2f := nil;
+ @glTexCoord2fv := nil;
+ @glTexCoord2i := nil;
+ @glTexCoord2iv := nil;
+ @glTexCoord2s := nil;
+ @glTexCoord2sv := nil;
+ @glTexCoord3d := nil;
+ @glTexCoord3dv := nil;
+ @glTexCoord3f := nil;
+ @glTexCoord3fv := nil;
+ @glTexCoord3i := nil;
+ @glTexCoord3iv := nil;
+ @glTexCoord3s := nil;
+ @glTexCoord3sv := nil;
+ @glTexCoord4d := nil;
+ @glTexCoord4dv := nil;
+ @glTexCoord4f := nil;
+ @glTexCoord4fv := nil;
+ @glTexCoord4i := nil;
+ @glTexCoord4iv := nil;
+ @glTexCoord4s := nil;
+ @glTexCoord4sv := nil;
+ @glTexCoordPointer := nil;
+ @glTexEnvf := nil;
+ @glTexEnvfv := nil;
+ @glTexEnvi := nil;
+ @glTexEnviv := nil;
+ @glTexGend := nil;
+ @glTexGendv := nil;
+ @glTexGenf := nil;
+ @glTexGenfv := nil;
+ @glTexGeni := nil;
+ @glTexGeniv := nil;
+ @glTexImage1D := nil;
+ @glTexImage2D := nil;
+ @glTexParameterf := nil;
+ @glTexParameterfv := nil;
+ @glTexParameteri := nil;
+ @glTexParameteriv := nil;
+ @glTexSubImage1D := nil;
+ @glTexSubImage2D := nil;
+ @glTranslated := nil;
+ @glTranslatef := nil;
+ @glVertex2d := nil;
+ @glVertex2dv := nil;
+ @glVertex2f := nil;
+ @glVertex2fv := nil;
+ @glVertex2i := nil;
+ @glVertex2iv := nil;
+ @glVertex2s := nil;
+ @glVertex2sv := nil;
+ @glVertex3d := nil;
+ @glVertex3dv := nil;
+ @glVertex3f := nil;
+ @glVertex3fv := nil;
+ @glVertex3i := nil;
+ @glVertex3iv := nil;
+ @glVertex3s := nil;
+ @glVertex3sv := nil;
+ @glVertex4d := nil;
+ @glVertex4dv := nil;
+ @glVertex4f := nil;
+ @glVertex4fv := nil;
+ @glVertex4i := nil;
+ @glVertex4iv := nil;
+ @glVertex4s := nil;
+ @glVertex4sv := nil;
+ @glVertexPointer := nil;
+ @glViewport := nil;
+ {$IFDEF WINDOWS}
+ @ChoosePixelFormat := nil;
+ {$ENDIF}
+
+ UnLoadModule(LibGL);
+
+end;
+
+procedure LoadOpenGL(const dll: PChar);
+begin
+
+ FreeOpenGL;
+
+ if LoadModule( LibGL, dll ) then
+ begin
+ @glAccum := GetModuleSymbol(LibGL, 'glAccum');
+ @glAlphaFunc := GetModuleSymbol(LibGL, 'glAlphaFunc');
+ @glAreTexturesResident := GetModuleSymbol(LibGL, 'glAreTexturesResident');
+ @glArrayElement := GetModuleSymbol(LibGL, 'glArrayElement');
+ @glBegin := GetModuleSymbol(LibGL, 'glBegin');
+ @glBindTexture := GetModuleSymbol(LibGL, 'glBindTexture');
+ @glBitmap := GetModuleSymbol(LibGL, 'glBitmap');
+ @glBlendFunc := GetModuleSymbol(LibGL, 'glBlendFunc');
+ @glCallList := GetModuleSymbol(LibGL, 'glCallList');
+ @glCallLists := GetModuleSymbol(LibGL, 'glCallLists');
+ @glClear := GetModuleSymbol(LibGL, 'glClear');
+ @glClearAccum := GetModuleSymbol(LibGL, 'glClearAccum');
+ @glClearColor := GetModuleSymbol(LibGL, 'glClearColor');
+ @glClearDepth := GetModuleSymbol(LibGL, 'glClearDepth');
+ @glClearIndex := GetModuleSymbol(LibGL, 'glClearIndex');
+ @glClearStencil := GetModuleSymbol(LibGL, 'glClearStencil');
+ @glClipPlane := GetModuleSymbol(LibGL, 'glClipPlane');
+ @glColor3b := GetModuleSymbol(LibGL, 'glColor3b');
+ @glColor3bv := GetModuleSymbol(LibGL, 'glColor3bv');
+ @glColor3d := GetModuleSymbol(LibGL, 'glColor3d');
+ @glColor3dv := GetModuleSymbol(LibGL, 'glColor3dv');
+ @glColor3f := GetModuleSymbol(LibGL, 'glColor3f');
+ @glColor3fv := GetModuleSymbol(LibGL, 'glColor3fv');
+ @glColor3i := GetModuleSymbol(LibGL, 'glColor3i');
+ @glColor3iv := GetModuleSymbol(LibGL, 'glColor3iv');
+ @glColor3s := GetModuleSymbol(LibGL, 'glColor3s');
+ @glColor3sv := GetModuleSymbol(LibGL, 'glColor3sv');
+ @glColor3ub := GetModuleSymbol(LibGL, 'glColor3ub');
+ @glColor3ubv := GetModuleSymbol(LibGL, 'glColor3ubv');
+ @glColor3ui := GetModuleSymbol(LibGL, 'glColor3ui');
+ @glColor3uiv := GetModuleSymbol(LibGL, 'glColor3uiv');
+ @glColor3us := GetModuleSymbol(LibGL, 'glColor3us');
+ @glColor3usv := GetModuleSymbol(LibGL, 'glColor3usv');
+ @glColor4b := GetModuleSymbol(LibGL, 'glColor4b');
+ @glColor4bv := GetModuleSymbol(LibGL, 'glColor4bv');
+ @glColor4d := GetModuleSymbol(LibGL, 'glColor4d');
+ @glColor4dv := GetModuleSymbol(LibGL, 'glColor4dv');
+ @glColor4f := GetModuleSymbol(LibGL, 'glColor4f');
+ @glColor4fv := GetModuleSymbol(LibGL, 'glColor4fv');
+ @glColor4i := GetModuleSymbol(LibGL, 'glColor4i');
+ @glColor4iv := GetModuleSymbol(LibGL, 'glColor4iv');
+ @glColor4s := GetModuleSymbol(LibGL, 'glColor4s');
+ @glColor4sv := GetModuleSymbol(LibGL, 'glColor4sv');
+ @glColor4ub := GetModuleSymbol(LibGL, 'glColor4ub');
+ @glColor4ubv := GetModuleSymbol(LibGL, 'glColor4ubv');
+ @glColor4ui := GetModuleSymbol(LibGL, 'glColor4ui');
+ @glColor4uiv := GetModuleSymbol(LibGL, 'glColor4uiv');
+ @glColor4us := GetModuleSymbol(LibGL, 'glColor4us');
+ @glColor4usv := GetModuleSymbol(LibGL, 'glColor4usv');
+ @glColorMask := GetModuleSymbol(LibGL, 'glColorMask');
+ @glColorMaterial := GetModuleSymbol(LibGL, 'glColorMaterial');
+ @glColorPointer := GetModuleSymbol(LibGL, 'glColorPointer');
+ @glCopyPixels := GetModuleSymbol(LibGL, 'glCopyPixels');
+ @glCopyTexImage1D := GetModuleSymbol(LibGL, 'glCopyTexImage1D');
+ @glCopyTexImage2D := GetModuleSymbol(LibGL, 'glCopyTexImage2D');
+ @glCopyTexSubImage1D := GetModuleSymbol(LibGL, 'glCopyTexSubImage1D');
+ @glCopyTexSubImage2D := GetModuleSymbol(LibGL, 'glCopyTexSubImage2D');
+ @glCullFace := GetModuleSymbol(LibGL, 'glCullFace');
+ @glDeleteLists := GetModuleSymbol(LibGL, 'glDeleteLists');
+ @glDeleteTextures := GetModuleSymbol(LibGL, 'glDeleteTextures');
+ @glDepthFunc := GetModuleSymbol(LibGL, 'glDepthFunc');
+ @glDepthMask := GetModuleSymbol(LibGL, 'glDepthMask');
+ @glDepthRange := GetModuleSymbol(LibGL, 'glDepthRange');
+ @glDisable := GetModuleSymbol(LibGL, 'glDisable');
+ @glDisableClientState := GetModuleSymbol(LibGL, 'glDisableClientState');
+ @glDrawArrays := GetModuleSymbol(LibGL, 'glDrawArrays');
+ @glDrawBuffer := GetModuleSymbol(LibGL, 'glDrawBuffer');
+ @glDrawElements := GetModuleSymbol(LibGL, 'glDrawElements');
+ @glDrawPixels := GetModuleSymbol(LibGL, 'glDrawPixels');
+ @glEdgeFlag := GetModuleSymbol(LibGL, 'glEdgeFlag');
+ @glEdgeFlagPointer := GetModuleSymbol(LibGL, 'glEdgeFlagPointer');
+ @glEdgeFlagv := GetModuleSymbol(LibGL, 'glEdgeFlagv');
+ @glEnable := GetModuleSymbol(LibGL, 'glEnable');
+ @glEnableClientState := GetModuleSymbol(LibGL, 'glEnableClientState');
+ @glEnd := GetModuleSymbol(LibGL, 'glEnd');
+ @glEndList := GetModuleSymbol(LibGL, 'glEndList');
+ @glEvalCoord1d := GetModuleSymbol(LibGL, 'glEvalCoord1d');
+ @glEvalCoord1dv := GetModuleSymbol(LibGL, 'glEvalCoord1dv');
+ @glEvalCoord1f := GetModuleSymbol(LibGL, 'glEvalCoord1f');
+ @glEvalCoord1fv := GetModuleSymbol(LibGL, 'glEvalCoord1fv');
+ @glEvalCoord2d := GetModuleSymbol(LibGL, 'glEvalCoord2d');
+ @glEvalCoord2dv := GetModuleSymbol(LibGL, 'glEvalCoord2dv');
+ @glEvalCoord2f := GetModuleSymbol(LibGL, 'glEvalCoord2f');
+ @glEvalCoord2fv := GetModuleSymbol(LibGL, 'glEvalCoord2fv');
+ @glEvalMesh1 := GetModuleSymbol(LibGL, 'glEvalMesh1');
+ @glEvalMesh2 := GetModuleSymbol(LibGL, 'glEvalMesh2');
+ @glEvalPoint1 := GetModuleSymbol(LibGL, 'glEvalPoint1');
+ @glEvalPoint2 := GetModuleSymbol(LibGL, 'glEvalPoint2');
+ @glFeedbackBuffer := GetModuleSymbol(LibGL, 'glFeedbackBuffer');
+ @glFinish := GetModuleSymbol(LibGL, 'glFinish');
+ @glFlush := GetModuleSymbol(LibGL, 'glFlush');
+ @glFogf := GetModuleSymbol(LibGL, 'glFogf');
+ @glFogfv := GetModuleSymbol(LibGL, 'glFogfv');
+ @glFogi := GetModuleSymbol(LibGL, 'glFogi');
+ @glFogiv := GetModuleSymbol(LibGL, 'glFogiv');
+ @glFrontFace := GetModuleSymbol(LibGL, 'glFrontFace');
+ @glFrustum := GetModuleSymbol(LibGL, 'glFrustum');
+ @glGenLists := GetModuleSymbol(LibGL, 'glGenLists');
+ @glGenTextures := GetModuleSymbol(LibGL, 'glGenTextures');
+ @glGetBooleanv := GetModuleSymbol(LibGL, 'glGetBooleanv');
+ @glGetClipPlane := GetModuleSymbol(LibGL, 'glGetClipPlane');
+ @glGetDoublev := GetModuleSymbol(LibGL, 'glGetDoublev');
+ @glGetError := GetModuleSymbol(LibGL, 'glGetError');
+ @glGetFloatv := GetModuleSymbol(LibGL, 'glGetFloatv');
+ @glGetIntegerv := GetModuleSymbol(LibGL, 'glGetIntegerv');
+ @glGetLightfv := GetModuleSymbol(LibGL, 'glGetLightfv');
+ @glGetLightiv := GetModuleSymbol(LibGL, 'glGetLightiv');
+ @glGetMapdv := GetModuleSymbol(LibGL, 'glGetMapdv');
+ @glGetMapfv := GetModuleSymbol(LibGL, 'glGetMapfv');
+ @glGetMapiv := GetModuleSymbol(LibGL, 'glGetMapiv');
+ @glGetMaterialfv := GetModuleSymbol(LibGL, 'glGetMaterialfv');
+ @glGetMaterialiv := GetModuleSymbol(LibGL, 'glGetMaterialiv');
+ @glGetPixelMapfv := GetModuleSymbol(LibGL, 'glGetPixelMapfv');
+ @glGetPixelMapuiv := GetModuleSymbol(LibGL, 'glGetPixelMapuiv');
+ @glGetPixelMapusv := GetModuleSymbol(LibGL, 'glGetPixelMapusv');
+ @glGetPointerv := GetModuleSymbol(LibGL, 'glGetPointerv');
+ @glGetPolygonStipple := GetModuleSymbol(LibGL, 'glGetPolygonStipple');
+ @glGetString := GetModuleSymbol(LibGL, 'glGetString');
+ @glGetTexEnvfv := GetModuleSymbol(LibGL, 'glGetTexEnvfv');
+ @glGetTexEnviv := GetModuleSymbol(LibGL, 'glGetTexEnviv');
+ @glGetTexGendv := GetModuleSymbol(LibGL, 'glGetTexGendv');
+ @glGetTexGenfv := GetModuleSymbol(LibGL, 'glGetTexGenfv');
+ @glGetTexGeniv := GetModuleSymbol(LibGL, 'glGetTexGeniv');
+ @glGetTexImage := GetModuleSymbol(LibGL, 'glGetTexImage');
+ @glGetTexLevelParameterfv := GetModuleSymbol(LibGL, 'glGetTexLevelParameterfv');
+ @glGetTexLevelParameteriv := GetModuleSymbol(LibGL, 'glGetTexLevelParameteriv');
+ @glGetTexParameterfv := GetModuleSymbol(LibGL, 'glGetTexParameterfv');
+ @glGetTexParameteriv := GetModuleSymbol(LibGL, 'glGetTexParameteriv');
+ @glHint := GetModuleSymbol(LibGL, 'glHint');
+ @glIndexMask := GetModuleSymbol(LibGL, 'glIndexMask');
+ @glIndexPointer := GetModuleSymbol(LibGL, 'glIndexPointer');
+ @glIndexd := GetModuleSymbol(LibGL, 'glIndexd');
+ @glIndexdv := GetModuleSymbol(LibGL, 'glIndexdv');
+ @glIndexf := GetModuleSymbol(LibGL, 'glIndexf');
+ @glIndexfv := GetModuleSymbol(LibGL, 'glIndexfv');
+ @glIndexi := GetModuleSymbol(LibGL, 'glIndexi');
+ @glIndexiv := GetModuleSymbol(LibGL, 'glIndexiv');
+ @glIndexs := GetModuleSymbol(LibGL, 'glIndexs');
+ @glIndexsv := GetModuleSymbol(LibGL, 'glIndexsv');
+ @glIndexub := GetModuleSymbol(LibGL, 'glIndexub');
+ @glIndexubv := GetModuleSymbol(LibGL, 'glIndexubv');
+ @glInitNames := GetModuleSymbol(LibGL, 'glInitNames');
+ @glInterleavedArrays := GetModuleSymbol(LibGL, 'glInterleavedArrays');
+ @glIsEnabled := GetModuleSymbol(LibGL, 'glIsEnabled');
+ @glIsList := GetModuleSymbol(LibGL, 'glIsList');
+ @glIsTexture := GetModuleSymbol(LibGL, 'glIsTexture');
+ @glLightModelf := GetModuleSymbol(LibGL, 'glLightModelf');
+ @glLightModelfv := GetModuleSymbol(LibGL, 'glLightModelfv');
+ @glLightModeli := GetModuleSymbol(LibGL, 'glLightModeli');
+ @glLightModeliv := GetModuleSymbol(LibGL, 'glLightModeliv');
+ @glLightf := GetModuleSymbol(LibGL, 'glLightf');
+ @glLightfv := GetModuleSymbol(LibGL, 'glLightfv');
+ @glLighti := GetModuleSymbol(LibGL, 'glLighti');
+ @glLightiv := GetModuleSymbol(LibGL, 'glLightiv');
+ @glLineStipple := GetModuleSymbol(LibGL, 'glLineStipple');
+ @glLineWidth := GetModuleSymbol(LibGL, 'glLineWidth');
+ @glListBase := GetModuleSymbol(LibGL, 'glListBase');
+ @glLoadIdentity := GetModuleSymbol(LibGL, 'glLoadIdentity');
+ @glLoadMatrixd := GetModuleSymbol(LibGL, 'glLoadMatrixd');
+ @glLoadMatrixf := GetModuleSymbol(LibGL, 'glLoadMatrixf');
+ @glLoadName := GetModuleSymbol(LibGL, 'glLoadName');
+ @glLogicOp := GetModuleSymbol(LibGL, 'glLogicOp');
+ @glMap1d := GetModuleSymbol(LibGL, 'glMap1d');
+ @glMap1f := GetModuleSymbol(LibGL, 'glMap1f');
+ @glMap2d := GetModuleSymbol(LibGL, 'glMap2d');
+ @glMap2f := GetModuleSymbol(LibGL, 'glMap2f');
+ @glMapGrid1d := GetModuleSymbol(LibGL, 'glMapGrid1d');
+ @glMapGrid1f := GetModuleSymbol(LibGL, 'glMapGrid1f');
+ @glMapGrid2d := GetModuleSymbol(LibGL, 'glMapGrid2d');
+ @glMapGrid2f := GetModuleSymbol(LibGL, 'glMapGrid2f');
+ @glMaterialf := GetModuleSymbol(LibGL, 'glMaterialf');
+ @glMaterialfv := GetModuleSymbol(LibGL, 'glMaterialfv');
+ @glMateriali := GetModuleSymbol(LibGL, 'glMateriali');
+ @glMaterialiv := GetModuleSymbol(LibGL, 'glMaterialiv');
+ @glMatrixMode := GetModuleSymbol(LibGL, 'glMatrixMode');
+ @glMultMatrixd := GetModuleSymbol(LibGL, 'glMultMatrixd');
+ @glMultMatrixf := GetModuleSymbol(LibGL, 'glMultMatrixf');
+ @glNewList := GetModuleSymbol(LibGL, 'glNewList');
+ @glNormal3b := GetModuleSymbol(LibGL, 'glNormal3b');
+ @glNormal3bv := GetModuleSymbol(LibGL, 'glNormal3bv');
+ @glNormal3d := GetModuleSymbol(LibGL, 'glNormal3d');
+ @glNormal3dv := GetModuleSymbol(LibGL, 'glNormal3dv');
+ @glNormal3f := GetModuleSymbol(LibGL, 'glNormal3f');
+ @glNormal3fv := GetModuleSymbol(LibGL, 'glNormal3fv');
+ @glNormal3i := GetModuleSymbol(LibGL, 'glNormal3i');
+ @glNormal3iv := GetModuleSymbol(LibGL, 'glNormal3iv');
+ @glNormal3s := GetModuleSymbol(LibGL, 'glNormal3s');
+ @glNormal3sv := GetModuleSymbol(LibGL, 'glNormal3sv');
+ @glNormalPointer := GetModuleSymbol(LibGL, 'glNormalPointer');
+ @glOrtho := GetModuleSymbol(LibGL, 'glOrtho');
+ @glPassThrough := GetModuleSymbol(LibGL, 'glPassThrough');
+ @glPixelMapfv := GetModuleSymbol(LibGL, 'glPixelMapfv');
+ @glPixelMapuiv := GetModuleSymbol(LibGL, 'glPixelMapuiv');
+ @glPixelMapusv := GetModuleSymbol(LibGL, 'glPixelMapusv');
+ @glPixelStoref := GetModuleSymbol(LibGL, 'glPixelStoref');
+ @glPixelStorei := GetModuleSymbol(LibGL, 'glPixelStorei');
+ @glPixelTransferf := GetModuleSymbol(LibGL, 'glPixelTransferf');
+ @glPixelTransferi := GetModuleSymbol(LibGL, 'glPixelTransferi');
+ @glPixelZoom := GetModuleSymbol(LibGL, 'glPixelZoom');
+ @glPointSize := GetModuleSymbol(LibGL, 'glPointSize');
+ @glPolygonMode := GetModuleSymbol(LibGL, 'glPolygonMode');
+ @glPolygonOffset := GetModuleSymbol(LibGL, 'glPolygonOffset');
+ @glPolygonStipple := GetModuleSymbol(LibGL, 'glPolygonStipple');
+ @glPopAttrib := GetModuleSymbol(LibGL, 'glPopAttrib');
+ @glPopClientAttrib := GetModuleSymbol(LibGL, 'glPopClientAttrib');
+ @glPopMatrix := GetModuleSymbol(LibGL, 'glPopMatrix');
+ @glPopName := GetModuleSymbol(LibGL, 'glPopName');
+ @glPrioritizeTextures := GetModuleSymbol(LibGL, 'glPrioritizeTextures');
+ @glPushAttrib := GetModuleSymbol(LibGL, 'glPushAttrib');
+ @glPushClientAttrib := GetModuleSymbol(LibGL, 'glPushClientAttrib');
+ @glPushMatrix := GetModuleSymbol(LibGL, 'glPushMatrix');
+ @glPushName := GetModuleSymbol(LibGL, 'glPushName');
+ @glRasterPos2d := GetModuleSymbol(LibGL, 'glRasterPos2d');
+ @glRasterPos2dv := GetModuleSymbol(LibGL, 'glRasterPos2dv');
+ @glRasterPos2f := GetModuleSymbol(LibGL, 'glRasterPos2f');
+ @glRasterPos2fv := GetModuleSymbol(LibGL, 'glRasterPos2fv');
+ @glRasterPos2i := GetModuleSymbol(LibGL, 'glRasterPos2i');
+ @glRasterPos2iv := GetModuleSymbol(LibGL, 'glRasterPos2iv');
+ @glRasterPos2s := GetModuleSymbol(LibGL, 'glRasterPos2s');
+ @glRasterPos2sv := GetModuleSymbol(LibGL, 'glRasterPos2sv');
+ @glRasterPos3d := GetModuleSymbol(LibGL, 'glRasterPos3d');
+ @glRasterPos3dv := GetModuleSymbol(LibGL, 'glRasterPos3dv');
+ @glRasterPos3f := GetModuleSymbol(LibGL, 'glRasterPos3f');
+ @glRasterPos3fv := GetModuleSymbol(LibGL, 'glRasterPos3fv');
+ @glRasterPos3i := GetModuleSymbol(LibGL, 'glRasterPos3i');
+ @glRasterPos3iv := GetModuleSymbol(LibGL, 'glRasterPos3iv');
+ @glRasterPos3s := GetModuleSymbol(LibGL, 'glRasterPos3s');
+ @glRasterPos3sv := GetModuleSymbol(LibGL, 'glRasterPos3sv');
+ @glRasterPos4d := GetModuleSymbol(LibGL, 'glRasterPos4d');
+ @glRasterPos4dv := GetModuleSymbol(LibGL, 'glRasterPos4dv');
+ @glRasterPos4f := GetModuleSymbol(LibGL, 'glRasterPos4f');
+ @glRasterPos4fv := GetModuleSymbol(LibGL, 'glRasterPos4fv');
+ @glRasterPos4i := GetModuleSymbol(LibGL, 'glRasterPos4i');
+ @glRasterPos4iv := GetModuleSymbol(LibGL, 'glRasterPos4iv');
+ @glRasterPos4s := GetModuleSymbol(LibGL, 'glRasterPos4s');
+ @glRasterPos4sv := GetModuleSymbol(LibGL, 'glRasterPos4sv');
+ @glReadBuffer := GetModuleSymbol(LibGL, 'glReadBuffer');
+ @glReadPixels := GetModuleSymbol(LibGL, 'glReadPixels');
+ @glRectd := GetModuleSymbol(LibGL, 'glRectd');
+ @glRectdv := GetModuleSymbol(LibGL, 'glRectdv');
+ @glRectf := GetModuleSymbol(LibGL, 'glRectf');
+ @glRectfv := GetModuleSymbol(LibGL, 'glRectfv');
+ @glRecti := GetModuleSymbol(LibGL, 'glRecti');
+ @glRectiv := GetModuleSymbol(LibGL, 'glRectiv');
+ @glRects := GetModuleSymbol(LibGL, 'glRects');
+ @glRectsv := GetModuleSymbol(LibGL, 'glRectsv');
+ @glRenderMode := GetModuleSymbol(LibGL, 'glRenderMode');
+ @glRotated := GetModuleSymbol(LibGL, 'glRotated');
+ @glRotatef := GetModuleSymbol(LibGL, 'glRotatef');
+ @glScaled := GetModuleSymbol(LibGL, 'glScaled');
+ @glScalef := GetModuleSymbol(LibGL, 'glScalef');
+ @glScissor := GetModuleSymbol(LibGL, 'glScissor');
+ @glSelectBuffer := GetModuleSymbol(LibGL, 'glSelectBuffer');
+ @glShadeModel := GetModuleSymbol(LibGL, 'glShadeModel');
+ @glStencilFunc := GetModuleSymbol(LibGL, 'glStencilFunc');
+ @glStencilMask := GetModuleSymbol(LibGL, 'glStencilMask');
+ @glStencilOp := GetModuleSymbol(LibGL, 'glStencilOp');
+ @glTexCoord1d := GetModuleSymbol(LibGL, 'glTexCoord1d');
+ @glTexCoord1dv := GetModuleSymbol(LibGL, 'glTexCoord1dv');
+ @glTexCoord1f := GetModuleSymbol(LibGL, 'glTexCoord1f');
+ @glTexCoord1fv := GetModuleSymbol(LibGL, 'glTexCoord1fv');
+ @glTexCoord1i := GetModuleSymbol(LibGL, 'glTexCoord1i');
+ @glTexCoord1iv := GetModuleSymbol(LibGL, 'glTexCoord1iv');
+ @glTexCoord1s := GetModuleSymbol(LibGL, 'glTexCoord1s');
+ @glTexCoord1sv := GetModuleSymbol(LibGL, 'glTexCoord1sv');
+ @glTexCoord2d := GetModuleSymbol(LibGL, 'glTexCoord2d');
+ @glTexCoord2dv := GetModuleSymbol(LibGL, 'glTexCoord2dv');
+ @glTexCoord2f := GetModuleSymbol(LibGL, 'glTexCoord2f');
+ @glTexCoord2fv := GetModuleSymbol(LibGL, 'glTexCoord2fv');
+ @glTexCoord2i := GetModuleSymbol(LibGL, 'glTexCoord2i');
+ @glTexCoord2iv := GetModuleSymbol(LibGL, 'glTexCoord2iv');
+ @glTexCoord2s := GetModuleSymbol(LibGL, 'glTexCoord2s');
+ @glTexCoord2sv := GetModuleSymbol(LibGL, 'glTexCoord2sv');
+ @glTexCoord3d := GetModuleSymbol(LibGL, 'glTexCoord3d');
+ @glTexCoord3dv := GetModuleSymbol(LibGL, 'glTexCoord3dv');
+ @glTexCoord3f := GetModuleSymbol(LibGL, 'glTexCoord3f');
+ @glTexCoord3fv := GetModuleSymbol(LibGL, 'glTexCoord3fv');
+ @glTexCoord3i := GetModuleSymbol(LibGL, 'glTexCoord3i');
+ @glTexCoord3iv := GetModuleSymbol(LibGL, 'glTexCoord3iv');
+ @glTexCoord3s := GetModuleSymbol(LibGL, 'glTexCoord3s');
+ @glTexCoord3sv := GetModuleSymbol(LibGL, 'glTexCoord3sv');
+ @glTexCoord4d := GetModuleSymbol(LibGL, 'glTexCoord4d');
+ @glTexCoord4dv := GetModuleSymbol(LibGL, 'glTexCoord4dv');
+ @glTexCoord4f := GetModuleSymbol(LibGL, 'glTexCoord4f');
+ @glTexCoord4fv := GetModuleSymbol(LibGL, 'glTexCoord4fv');
+ @glTexCoord4i := GetModuleSymbol(LibGL, 'glTexCoord4i');
+ @glTexCoord4iv := GetModuleSymbol(LibGL, 'glTexCoord4iv');
+ @glTexCoord4s := GetModuleSymbol(LibGL, 'glTexCoord4s');
+ @glTexCoord4sv := GetModuleSymbol(LibGL, 'glTexCoord4sv');
+ @glTexCoordPointer := GetModuleSymbol(LibGL, 'glTexCoordPointer');
+ @glTexEnvf := GetModuleSymbol(LibGL, 'glTexEnvf');
+ @glTexEnvfv := GetModuleSymbol(LibGL, 'glTexEnvfv');
+ @glTexEnvi := GetModuleSymbol(LibGL, 'glTexEnvi');
+ @glTexEnviv := GetModuleSymbol(LibGL, 'glTexEnviv');
+ @glTexGend := GetModuleSymbol(LibGL, 'glTexGend');
+ @glTexGendv := GetModuleSymbol(LibGL, 'glTexGendv');
+ @glTexGenf := GetModuleSymbol(LibGL, 'glTexGenf');
+ @glTexGenfv := GetModuleSymbol(LibGL, 'glTexGenfv');
+ @glTexGeni := GetModuleSymbol(LibGL, 'glTexGeni');
+ @glTexGeniv := GetModuleSymbol(LibGL, 'glTexGeniv');
+ @glTexImage1D := GetModuleSymbol(LibGL, 'glTexImage1D');
+ @glTexImage2D := GetModuleSymbol(LibGL, 'glTexImage2D');
+ @glTexParameterf := GetModuleSymbol(LibGL, 'glTexParameterf');
+ @glTexParameterfv := GetModuleSymbol(LibGL, 'glTexParameterfv');
+ @glTexParameteri := GetModuleSymbol(LibGL, 'glTexParameteri');
+ @glTexParameteriv := GetModuleSymbol(LibGL, 'glTexParameteriv');
+ @glTexSubImage1D := GetModuleSymbol(LibGL, 'glTexSubImage1D');
+ @glTexSubImage2D := GetModuleSymbol(LibGL, 'glTexSubImage2D');
+ @glTranslated := GetModuleSymbol(LibGL, 'glTranslated');
+ @glTranslatef := GetModuleSymbol(LibGL, 'glTranslatef');
+ @glVertex2d := GetModuleSymbol(LibGL, 'glVertex2d');
+ @glVertex2dv := GetModuleSymbol(LibGL, 'glVertex2dv');
+ @glVertex2f := GetModuleSymbol(LibGL, 'glVertex2f');
+ @glVertex2fv := GetModuleSymbol(LibGL, 'glVertex2fv');
+ @glVertex2i := GetModuleSymbol(LibGL, 'glVertex2i');
+ @glVertex2iv := GetModuleSymbol(LibGL, 'glVertex2iv');
+ @glVertex2s := GetModuleSymbol(LibGL, 'glVertex2s');
+ @glVertex2sv := GetModuleSymbol(LibGL, 'glVertex2sv');
+ @glVertex3d := GetModuleSymbol(LibGL, 'glVertex3d');
+ @glVertex3dv := GetModuleSymbol(LibGL, 'glVertex3dv');
+ @glVertex3f := GetModuleSymbol(LibGL, 'glVertex3f');
+ @glVertex3fv := GetModuleSymbol(LibGL, 'glVertex3fv');
+ @glVertex3i := GetModuleSymbol(LibGL, 'glVertex3i');
+ @glVertex3iv := GetModuleSymbol(LibGL, 'glVertex3iv');
+ @glVertex3s := GetModuleSymbol(LibGL, 'glVertex3s');
+ @glVertex3sv := GetModuleSymbol(LibGL, 'glVertex3sv');
+ @glVertex4d := GetModuleSymbol(LibGL, 'glVertex4d');
+ @glVertex4dv := GetModuleSymbol(LibGL, 'glVertex4dv');
+ @glVertex4f := GetModuleSymbol(LibGL, 'glVertex4f');
+ @glVertex4fv := GetModuleSymbol(LibGL, 'glVertex4fv');
+ @glVertex4i := GetModuleSymbol(LibGL, 'glVertex4i');
+ @glVertex4iv := GetModuleSymbol(LibGL, 'glVertex4iv');
+ @glVertex4s := GetModuleSymbol(LibGL, 'glVertex4s');
+ @glVertex4sv := GetModuleSymbol(LibGL, 'glVertex4sv');
+ @glVertexPointer := GetModuleSymbol(LibGL, 'glVertexPointer');
+ @glViewport := GetModuleSymbol(LibGL, 'glViewport');
+
+ {$IFDEF WINDOWS}
+ @ChoosePixelFormat := GetModuleSymbol(LibGL, 'ChoosePixelFormat');
+ if not Assigned(ChoosePixelFormat) then
+ {$IFNDEF FPC}@{$ENDIF}ChoosePixelFormat := @Windows.ChoosePixelFormat;
+ {$ENDIF}
+ end;
+end;
+
+initialization
+ {$IF Defined(CPU386) or Defined(CPUI386) or Defined(CPUX86_64)}
+ Set8087CW($133F);
+ {$IFEND}
+
+ LoadOpenGL( GLLibName );
+
+finalization
+
+ FreeOpenGL;
+
+end.
+
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas b/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas
new file mode 100644
index 00000000..1fc70f8a
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas
@@ -0,0 +1,9578 @@
+unit glext;
+{
+ $Id: glext.pas,v 1.6 2007/05/20 20:28:31 savage Exp $
+
+}
+(**************************************************
+ * OpenGL extension loading library *
+ * Generated by MetaGLext, written by Tom Nuydens *
+ * (tom@delphi3d.net -- http://www.delphi3d.net *
+ **************************************************)
+
+{
+ $Log: glext.pas,v $
+ Revision 1.6 2007/05/20 20:28:31 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.5 2006/01/11 22:39:02 drellis
+ Updated to Support Up to OpenGL 2.0
+
+ Revision 1.4 2005/01/05 00:28:40 savage
+ Forgot to wrap a couple of Load_WGL function calls with an IFDEF WIN32. Fixed so now compiles under Linux as well.
+
+ Revision 1.3 2004/08/24 19:33:06 savage
+ Removed declarations of SDL_GL_GetProcAddress as the correct ones are in sdl.pas.
+
+ Revision 1.2 2004/08/09 00:38:01 savage
+ Updated to Tom's latest version. May contains bugs, but I hope not.
+
+ Revision 1.1 2004/03/30 21:53:54 savage
+ Moved to it's own folder.
+
+ Revision 1.6 2004/03/28 00:28:43 savage
+ Fixed some glSecondaryColor definitions...
+
+ Revision 1.5 2004/02/20 17:18:16 savage
+ Forgot to prefix function pointer with @ for FPC and other Pascal compilers.
+
+ Revision 1.4 2004/02/20 17:09:55 savage
+ Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
+
+ Revision 1.3 2004/02/14 22:36:29 savage
+ Fixed inconsistencies of using LoadLibrary and LoadModule.
+ Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
+
+ Revision 1.2 2004/02/14 00:09:19 savage
+ Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+ Revision 1.7 2003/06/02 12:32:13 savage
+ Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+uses
+ SysUtils,
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+ Windows,
+{$ENDIF}
+ moduleloader,
+ gl;
+
+// Test if the given extension name is present in the given extension string.
+function glext_ExtensionSupported(const extension: PChar; const searchIn: PChar): Boolean;
+
+// Load a Specific Extension
+function glext_LoadExtension(ext: String): Boolean;
+// Some types that were introduced by extensions:
+type
+ GLintptrARB = Integer;
+ PGLintptrARB = ^GLintptrARB;
+
+ GLsizeiptrARB = Integer;
+ PGLsizeiptrARB = ^GLsizeiptrARB;
+
+ GLcharARB = Char;
+ PGLcharARB = ^GLcharARB;
+
+ GLhandleARB = Cardinal;
+ PGLhandleARB = ^GLhandleARB;
+
+ GLintptr = Integer;
+ PGLintptr = ^GLintptr;
+
+ GLsizeiptr = Integer;
+ PGLsizeiptr = ^GLsizeiptr;
+
+ GLchar = Char;
+ PGLchar = ^GLchar;
+
+//***** GL_version_1_2 *****//
+const
+ GL_UNSIGNED_BYTE_3_3_2 = $8032;
+ GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
+ GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
+ GL_UNSIGNED_INT_8_8_8_8 = $8035;
+ GL_UNSIGNED_INT_10_10_10_2 = $8036;
+ GL_RESCALE_NORMAL = $803A;
+ GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
+ GL_UNSIGNED_SHORT_5_6_5 = $8363;
+ GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
+ GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
+ GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
+ GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
+ GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
+ GL_BGR = $80E0;
+ GL_BGRA = $80E1;
+ GL_MAX_ELEMENTS_VERTICES = $80E8;
+ GL_MAX_ELEMENTS_INDICES = $80E9;
+ GL_CLAMP_TO_EDGE = $812F;
+ GL_TEXTURE_MIN_LOD = $813A;
+ GL_TEXTURE_MAX_LOD = $813B;
+ GL_TEXTURE_BASE_LEVEL = $813C;
+ GL_TEXTURE_MAX_LEVEL = $813D;
+ GL_LIGHT_MODEL_COLOR_CONTROL = $81F8;
+ GL_SINGLE_COLOR = $81F9;
+ GL_SEPARATE_SPECULAR_COLOR = $81FA;
+ GL_SMOOTH_POINT_SIZE_RANGE = $0B12;
+ GL_SMOOTH_POINT_SIZE_GRANULARITY = $0B13;
+ GL_SMOOTH_LINE_WIDTH_RANGE = $0B22;
+ GL_SMOOTH_LINE_WIDTH_GRANULARITY = $0B23;
+ GL_ALIASED_POINT_SIZE_RANGE = $846D;
+ GL_ALIASED_LINE_WIDTH_RANGE = $846E;
+ GL_PACK_SKIP_IMAGES = $806B;
+ GL_PACK_IMAGE_HEIGHT = $806C;
+ GL_UNPACK_SKIP_IMAGES = $806D;
+ GL_UNPACK_IMAGE_HEIGHT = $806E;
+ GL_TEXTURE_3D = $806F;
+ GL_PROXY_TEXTURE_3D = $8070;
+ GL_TEXTURE_DEPTH = $8071;
+ GL_TEXTURE_WRAP_R = $8072;
+ GL_MAX_3D_TEXTURE_SIZE = $8073;
+var
+ glDrawRangeElements: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_version_1_2: Boolean;
+
+//***** GL_ARB_imaging *****//
+const
+ GL_CONSTANT_COLOR = $8001;
+ GL_ONE_MINUS_CONSTANT_COLOR = $8002;
+ GL_CONSTANT_ALPHA = $8003;
+ GL_ONE_MINUS_CONSTANT_ALPHA = $8004;
+ GL_BLEND_COLOR = $8005;
+ GL_FUNC_ADD = $8006;
+ GL_MIN = $8007;
+ GL_MAX = $8008;
+ GL_BLEND_EQUATION = $8009;
+ GL_FUNC_SUBTRACT = $800A;
+ GL_FUNC_REVERSE_SUBTRACT = $800B;
+ GL_CONVOLUTION_1D = $8010;
+ GL_CONVOLUTION_2D = $8011;
+ GL_SEPARABLE_2D = $8012;
+ GL_CONVOLUTION_BORDER_MODE = $8013;
+ GL_CONVOLUTION_FILTER_SCALE = $8014;
+ GL_CONVOLUTION_FILTER_BIAS = $8015;
+ GL_REDUCE = $8016;
+ GL_CONVOLUTION_FORMAT = $8017;
+ GL_CONVOLUTION_WIDTH = $8018;
+ GL_CONVOLUTION_HEIGHT = $8019;
+ GL_MAX_CONVOLUTION_WIDTH = $801A;
+ GL_MAX_CONVOLUTION_HEIGHT = $801B;
+ GL_POST_CONVOLUTION_RED_SCALE = $801C;
+ GL_POST_CONVOLUTION_GREEN_SCALE = $801D;
+ GL_POST_CONVOLUTION_BLUE_SCALE = $801E;
+ GL_POST_CONVOLUTION_ALPHA_SCALE = $801F;
+ GL_POST_CONVOLUTION_RED_BIAS = $8020;
+ GL_POST_CONVOLUTION_GREEN_BIAS = $8021;
+ GL_POST_CONVOLUTION_BLUE_BIAS = $8022;
+ GL_POST_CONVOLUTION_ALPHA_BIAS = $8023;
+ GL_HISTOGRAM = $8024;
+ GL_PROXY_HISTOGRAM = $8025;
+ GL_HISTOGRAM_WIDTH = $8026;
+ GL_HISTOGRAM_FORMAT = $8027;
+ GL_HISTOGRAM_RED_SIZE = $8028;
+ GL_HISTOGRAM_GREEN_SIZE = $8029;
+ GL_HISTOGRAM_BLUE_SIZE = $802A;
+ GL_HISTOGRAM_ALPHA_SIZE = $802B;
+ GL_HISTOGRAM_LUMINANCE_SIZE = $802C;
+ GL_HISTOGRAM_SINK = $802D;
+ GL_MINMAX = $802E;
+ GL_MINMAX_FORMAT = $802F;
+ GL_MINMAX_SINK = $8030;
+ GL_TABLE_TOO_LARGE = $8031;
+ GL_COLOR_MATRIX = $80B1;
+ GL_COLOR_MATRIX_STACK_DEPTH = $80B2;
+ GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3;
+ GL_POST_COLOR_MATRIX_RED_SCALE = $80B4;
+ GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5;
+ GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6;
+ GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7;
+ GL_POST_COLOR_MATRIX_RED_BIAS = $80B8;
+ GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9;
+ GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA;
+ GL_POST_COLOR_MATIX_ALPHA_BIAS = $80BB;
+ GL_COLOR_TABLE = $80D0;
+ GL_POST_CONVOLUTION_COLOR_TABLE = $80D1;
+ GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2;
+ GL_PROXY_COLOR_TABLE = $80D3;
+ GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4;
+ GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5;
+ GL_COLOR_TABLE_SCALE = $80D6;
+ GL_COLOR_TABLE_BIAS = $80D7;
+ GL_COLOR_TABLE_FORMAT = $80D8;
+ GL_COLOR_TABLE_WIDTH = $80D9;
+ GL_COLOR_TABLE_RED_SIZE = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE = $80DF;
+ GL_IGNORE_BORDER = $8150;
+ GL_CONSTANT_BORDER = $8151;
+ GL_WRAP_BORDER = $8152;
+ GL_REPLICATE_BORDER = $8153;
+ GL_CONVOLUTION_BORDER_COLOR = $8154;
+var
+ glColorTable: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorTableParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorTableParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyColorTable: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTable: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorSubTable: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyColorSubTable: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameterf: procedure(target: GLenum; pname: GLenum; params: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameteri: procedure(target: GLenum; pname: GLenum; params: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetSeparableFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSeparableFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogram: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogramParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogramParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmax: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmaxParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmaxParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glHistogram: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMinmax: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glResetHistogram: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glResetMinmax: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBlendEquation: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBlendColor: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_imaging: Boolean;
+
+//***** GL_version_1_3 *****//
+const
+ GL_TEXTURE0 = $84C0;
+ GL_TEXTURE1 = $84C1;
+ GL_TEXTURE2 = $84C2;
+ GL_TEXTURE3 = $84C3;
+ GL_TEXTURE4 = $84C4;
+ GL_TEXTURE5 = $84C5;
+ GL_TEXTURE6 = $84C6;
+ GL_TEXTURE7 = $84C7;
+ GL_TEXTURE8 = $84C8;
+ GL_TEXTURE9 = $84C9;
+ GL_TEXTURE10 = $84CA;
+ GL_TEXTURE11 = $84CB;
+ GL_TEXTURE12 = $84CC;
+ GL_TEXTURE13 = $84CD;
+ GL_TEXTURE14 = $84CE;
+ GL_TEXTURE15 = $84CF;
+ GL_TEXTURE16 = $84D0;
+ GL_TEXTURE17 = $84D1;
+ GL_TEXTURE18 = $84D2;
+ GL_TEXTURE19 = $84D3;
+ GL_TEXTURE20 = $84D4;
+ GL_TEXTURE21 = $84D5;
+ GL_TEXTURE22 = $84D6;
+ GL_TEXTURE23 = $84D7;
+ GL_TEXTURE24 = $84D8;
+ GL_TEXTURE25 = $84D9;
+ GL_TEXTURE26 = $84DA;
+ GL_TEXTURE27 = $84DB;
+ GL_TEXTURE28 = $84DC;
+ GL_TEXTURE29 = $84DD;
+ GL_TEXTURE30 = $84DE;
+ GL_TEXTURE31 = $84DF;
+ GL_ACTIVE_TEXTURE = $84E0;
+ GL_CLIENT_ACTIVE_TEXTURE = $84E1;
+ GL_MAX_TEXTURE_UNITS = $84E2;
+ GL_TRANSPOSE_MODELVIEW_MATRIX = $84E3;
+ GL_TRANSPOSE_PROJECTION_MATRIX = $84E4;
+ GL_TRANSPOSE_TEXTURE_MATRIX = $84E5;
+ GL_TRANSPOSE_COLOR_MATRIX = $84E6;
+ GL_MULTISAMPLE = $809D;
+ GL_SAMPLE_ALPHA_TO_COVERAGE = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE = $809F;
+ GL_SAMPLE_COVERAGE = $80A0;
+ GL_SAMPLE_BUFFERS = $80A8;
+ GL_SAMPLES = $80A9;
+ GL_SAMPLE_COVERAGE_VALUE = $80AA;
+ GL_SAMPLE_COVERAGE_INVERT = $80AB;
+ GL_MULTISAMPLE_BIT = $20000000;
+ GL_NORMAL_MAP = $8511;
+ GL_REFLECTION_MAP = $8512;
+ GL_TEXTURE_CUBE_MAP = $8513;
+ GL_TEXTURE_BINDING_CUBE_MAP = $8514;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
+ GL_PROXY_TEXTURE_CUBE_MAP = $851B;
+ GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
+ GL_COMPRESSED_ALPHA = $84E9;
+ GL_COMPRESSED_LUMINANCE = $84EA;
+ GL_COMPRESSED_LUMINANCE_ALPHA = $84EB;
+ GL_COMPRESSED_INTENSITY = $84EC;
+ GL_COMPRESSED_RGB = $84ED;
+ GL_COMPRESSED_RGBA = $84EE;
+ GL_TEXTURE_COMPRESSION_HINT = $84EF;
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE = $86A0;
+ GL_TEXTURE_COMPRESSED = $86A1;
+ GL_NUM_COMPRESSED_TEXTURE_FORMATS = $86A2;
+ GL_COMPRESSED_TEXTURE_FORMATS = $86A3;
+ GL_CLAMP_TO_BORDER = $812D;
+ GL_CLAMP_TO_BORDER_SGIS = $812D;
+ GL_COMBINE = $8570;
+ GL_COMBINE_RGB = $8571;
+ GL_COMBINE_ALPHA = $8572;
+ GL_SOURCE0_RGB = $8580;
+ GL_SOURCE1_RGB = $8581;
+ GL_SOURCE2_RGB = $8582;
+ GL_SOURCE0_ALPHA = $8588;
+ GL_SOURCE1_ALPHA = $8589;
+ GL_SOURCE2_ALPHA = $858A;
+ GL_OPERAND0_RGB = $8590;
+ GL_OPERAND1_RGB = $8591;
+ GL_OPERAND2_RGB = $8592;
+ GL_OPERAND0_ALPHA = $8598;
+ GL_OPERAND1_ALPHA = $8599;
+ GL_OPERAND2_ALPHA = $859A;
+ GL_RGB_SCALE = $8573;
+ GL_ADD_SIGNED = $8574;
+ GL_INTERPOLATE = $8575;
+ GL_SUBTRACT = $84E7;
+ GL_CONSTANT = $8576;
+ GL_PRIMARY_COLOR = $8577;
+ GL_PREVIOUS = $8578;
+ GL_DOT3_RGB = $86AE;
+ GL_DOT3_RGBA = $86AF;
+var
+ glActiveTexture: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClientActiveTexture: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1d: procedure(target: GLenum; s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1f: procedure(target: GLenum; s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1i: procedure(target: GLenum; s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1s: procedure(target: GLenum; s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2d: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2f: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2i: procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2s: procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4dv: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4fv: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4iv: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4sv: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadTransposeMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadTransposeMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultTransposeMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultTransposeMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSampleCoverage: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexImage1D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage2D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage1D: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCompressedTexImage: procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_version_1_3: Boolean;
+
+//***** GL_ARB_multitexture *****//
+const
+ GL_TEXTURE0_ARB = $84C0;
+ GL_TEXTURE1_ARB = $84C1;
+ GL_TEXTURE2_ARB = $84C2;
+ GL_TEXTURE3_ARB = $84C3;
+ GL_TEXTURE4_ARB = $84C4;
+ GL_TEXTURE5_ARB = $84C5;
+ GL_TEXTURE6_ARB = $84C6;
+ GL_TEXTURE7_ARB = $84C7;
+ GL_TEXTURE8_ARB = $84C8;
+ GL_TEXTURE9_ARB = $84C9;
+ GL_TEXTURE10_ARB = $84CA;
+ GL_TEXTURE11_ARB = $84CB;
+ GL_TEXTURE12_ARB = $84CC;
+ GL_TEXTURE13_ARB = $84CD;
+ GL_TEXTURE14_ARB = $84CE;
+ GL_TEXTURE15_ARB = $84CF;
+ GL_TEXTURE16_ARB = $84D0;
+ GL_TEXTURE17_ARB = $84D1;
+ GL_TEXTURE18_ARB = $84D2;
+ GL_TEXTURE19_ARB = $84D3;
+ GL_TEXTURE20_ARB = $84D4;
+ GL_TEXTURE21_ARB = $84D5;
+ GL_TEXTURE22_ARB = $84D6;
+ GL_TEXTURE23_ARB = $84D7;
+ GL_TEXTURE24_ARB = $84D8;
+ GL_TEXTURE25_ARB = $84D9;
+ GL_TEXTURE26_ARB = $84DA;
+ GL_TEXTURE27_ARB = $84DB;
+ GL_TEXTURE28_ARB = $84DC;
+ GL_TEXTURE29_ARB = $84DD;
+ GL_TEXTURE30_ARB = $84DE;
+ GL_TEXTURE31_ARB = $84DF;
+ GL_ACTIVE_TEXTURE_ARB = $84E0;
+ GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1;
+ GL_MAX_TEXTURE_UNITS_ARB = $84E2;
+var
+ glActiveTextureARB: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClientActiveTextureARB: procedure(texture: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1dARB: procedure(target: GLenum; s: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1fARB: procedure(target: GLenum; s: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1iARB: procedure(target: GLenum; s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1sARB: procedure(target: GLenum; s: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2iARB: procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2sARB: procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4dvARB: procedure(target: GLenum; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4fvARB: procedure(target: GLenum; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4ivARB: procedure(target: GLenum; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4svARB: procedure(target: GLenum; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_multitexture: Boolean;
+
+//***** GL_ARB_transpose_matrix *****//
+const
+ GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3;
+ GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4;
+ GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5;
+ GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6;
+var
+ glLoadTransposeMatrixfARB: procedure(m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadTransposeMatrixdARB: procedure(m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultTransposeMatrixfARB: procedure(m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultTransposeMatrixdARB: procedure(m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_transpose_matrix: Boolean;
+
+//***** GL_ARB_multisample *****//
+const
+ WGL_SAMPLE_BUFFERS_ARB = $2041;
+ WGL_SAMPLES_ARB = $2042;
+ GL_MULTISAMPLE_ARB = $809D;
+ GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F;
+ GL_SAMPLE_COVERAGE_ARB = $80A0;
+ GL_MULTISAMPLE_BIT_ARB = $20000000;
+ GL_SAMPLE_BUFFERS_ARB = $80A8;
+ GL_SAMPLES_ARB = $80A9;
+ GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA;
+ GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB;
+var
+ glSampleCoverageARB: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_multisample: Boolean;
+
+//***** GL_ARB_texture_env_add *****//
+
+function Load_GL_ARB_texture_env_add: Boolean;
+
+{$IFDEF WINDOWS}
+//***** WGL_ARB_extensions_string *****//
+var
+ wglGetExtensionsStringARB: function(hdc: HDC): Pchar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_extensions_string: Boolean;
+
+//***** WGL_ARB_buffer_region *****//
+const
+ WGL_FRONT_COLOR_BUFFER_BIT_ARB = $0001;
+ WGL_BACK_COLOR_BUFFER_BIT_ARB = $0002;
+ WGL_DEPTH_BUFFER_BIT_ARB = $0004;
+ WGL_STENCIL_BUFFER_BIT_ARB = $0008;
+var
+ wglCreateBufferRegionARB: function(hDC: HDC; iLayerPlane: GLint; uType: GLuint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDeleteBufferRegionARB: procedure(hRegion: THandle); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglSaveBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglRestoreBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint; xSrc: GLint; ySrc: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_buffer_region: Boolean;
+{$ENDIF}
+
+//***** GL_ARB_texture_cube_map *****//
+const
+ GL_NORMAL_MAP_ARB = $8511;
+ GL_REFLECTION_MAP_ARB = $8512;
+ GL_TEXTURE_CUBE_MAP_ARB = $8513;
+ GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A;
+ GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B;
+ GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C;
+
+function Load_GL_ARB_texture_cube_map: Boolean;
+
+//***** GL_ARB_depth_texture *****//
+const
+ GL_DEPTH_COMPONENT16_ARB = $81A5;
+ GL_DEPTH_COMPONENT24_ARB = $81A6;
+ GL_DEPTH_COMPONENT32_ARB = $81A7;
+ GL_TEXTURE_DEPTH_SIZE_ARB = $884A;
+ GL_DEPTH_TEXTURE_MODE_ARB = $884B;
+
+function Load_GL_ARB_depth_texture: Boolean;
+
+//***** GL_ARB_point_parameters *****//
+const
+ GL_POINT_SIZE_MIN_ARB = $8126;
+ GL_POINT_SIZE_MAX_ARB = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE_ARB = $8128;
+ GL_POINT_DISTANCE_ATTENUATION_ARB = $8129;
+var
+ glPointParameterfARB: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameterfvARB: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_point_parameters: Boolean;
+
+//***** GL_ARB_shadow *****//
+const
+ GL_TEXTURE_COMPARE_MODE_ARB = $884C;
+ GL_TEXTURE_COMPARE_FUNC_ARB = $884D;
+ GL_COMPARE_R_TO_TEXTURE_ARB = $884E;
+
+function Load_GL_ARB_shadow: Boolean;
+
+//***** GL_ARB_shadow_ambient *****//
+const
+ GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = $80BF;
+
+function Load_GL_ARB_shadow_ambient: Boolean;
+
+//***** GL_ARB_texture_border_clamp *****//
+const
+ GL_CLAMP_TO_BORDER_ARB = $812D;
+
+function Load_GL_ARB_texture_border_clamp: Boolean;
+
+//***** GL_ARB_texture_compression *****//
+const
+ GL_COMPRESSED_ALPHA_ARB = $84E9;
+ GL_COMPRESSED_LUMINANCE_ARB = $84EA;
+ GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB;
+ GL_COMPRESSED_INTENSITY_ARB = $84EC;
+ GL_COMPRESSED_RGB_ARB = $84ED;
+ GL_COMPRESSED_RGBA_ARB = $84EE;
+ GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF;
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0;
+ GL_TEXTURE_COMPRESSED_ARB = $86A1;
+ GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2;
+ GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3;
+var
+ glCompressedTexImage3DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexImage2DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexImage1DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage3DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage2DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompressedTexSubImage1DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCompressedTexImageARB: procedure(target: GLenum; lod: GLint; img: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_texture_compression: Boolean;
+
+//***** GL_ARB_texture_env_combine *****//
+const
+ GL_COMBINE_ARB = $8570;
+ GL_COMBINE_RGB_ARB = $8571;
+ GL_COMBINE_ALPHA_ARB = $8572;
+ GL_SOURCE0_RGB_ARB = $8580;
+ GL_SOURCE1_RGB_ARB = $8581;
+ GL_SOURCE2_RGB_ARB = $8582;
+ GL_SOURCE0_ALPHA_ARB = $8588;
+ GL_SOURCE1_ALPHA_ARB = $8589;
+ GL_SOURCE2_ALPHA_ARB = $858A;
+ GL_OPERAND0_RGB_ARB = $8590;
+ GL_OPERAND1_RGB_ARB = $8591;
+ GL_OPERAND2_RGB_ARB = $8592;
+ GL_OPERAND0_ALPHA_ARB = $8598;
+ GL_OPERAND1_ALPHA_ARB = $8599;
+ GL_OPERAND2_ALPHA_ARB = $859A;
+ GL_RGB_SCALE_ARB = $8573;
+ GL_ADD_SIGNED_ARB = $8574;
+ GL_INTERPOLATE_ARB = $8575;
+ GL_SUBTRACT_ARB = $84E7;
+ GL_CONSTANT_ARB = $8576;
+ GL_PRIMARY_COLOR_ARB = $8577;
+ GL_PREVIOUS_ARB = $8578;
+
+function Load_GL_ARB_texture_env_combine: Boolean;
+
+//***** GL_ARB_texture_env_crossbar *****//
+
+function Load_GL_ARB_texture_env_crossbar: Boolean;
+
+//***** GL_ARB_texture_env_dot3 *****//
+const
+ GL_DOT3_RGB_ARB = $86AE;
+ GL_DOT3_RGBA_ARB = $86AF;
+
+function Load_GL_ARB_texture_env_dot3: Boolean;
+
+//***** GL_ARB_texture_mirrored_repeat *****//
+const
+ GL_MIRRORED_REPEAT_ARB = $8370;
+
+function Load_GL_ARB_texture_mirrored_repeat: Boolean;
+
+//***** GL_ARB_vertex_blend *****//
+const
+ GL_MAX_VERTEX_UNITS_ARB = $86A4;
+ GL_ACTIVE_VERTEX_UNITS_ARB = $86A5;
+ GL_WEIGHT_SUM_UNITY_ARB = $86A6;
+ GL_VERTEX_BLEND_ARB = $86A7;
+ GL_MODELVIEW0_ARB = $1700;
+ GL_MODELVIEW1_ARB = $850A;
+ GL_MODELVIEW2_ARB = $8722;
+ GL_MODELVIEW3_ARB = $8723;
+ GL_MODELVIEW4_ARB = $8724;
+ GL_MODELVIEW5_ARB = $8725;
+ GL_MODELVIEW6_ARB = $8726;
+ GL_MODELVIEW7_ARB = $8727;
+ GL_MODELVIEW8_ARB = $8728;
+ GL_MODELVIEW9_ARB = $8729;
+ GL_MODELVIEW10_ARB = $872A;
+ GL_MODELVIEW11_ARB = $872B;
+ GL_MODELVIEW12_ARB = $872C;
+ GL_MODELVIEW13_ARB = $872D;
+ GL_MODELVIEW14_ARB = $872E;
+ GL_MODELVIEW15_ARB = $872F;
+ GL_MODELVIEW16_ARB = $8730;
+ GL_MODELVIEW17_ARB = $8731;
+ GL_MODELVIEW18_ARB = $8732;
+ GL_MODELVIEW19_ARB = $8733;
+ GL_MODELVIEW20_ARB = $8734;
+ GL_MODELVIEW21_ARB = $8735;
+ GL_MODELVIEW22_ARB = $8736;
+ GL_MODELVIEW23_ARB = $8737;
+ GL_MODELVIEW24_ARB = $8738;
+ GL_MODELVIEW25_ARB = $8739;
+ GL_MODELVIEW26_ARB = $873A;
+ GL_MODELVIEW27_ARB = $873B;
+ GL_MODELVIEW28_ARB = $873C;
+ GL_MODELVIEW29_ARB = $873D;
+ GL_MODELVIEW30_ARB = $873E;
+ GL_MODELVIEW31_ARB = $873F;
+ GL_CURRENT_WEIGHT_ARB = $86A8;
+ GL_WEIGHT_ARRAY_TYPE_ARB = $86A9;
+ GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA;
+ GL_WEIGHT_ARRAY_SIZE_ARB = $86AB;
+ GL_WEIGHT_ARRAY_POINTER_ARB = $86AC;
+ GL_WEIGHT_ARRAY_ARB = $86AD;
+var
+ glWeightbvARB: procedure(size: GLint; weights: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightsvARB: procedure(size: GLint; weights: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightivARB: procedure(size: GLint; weights: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightfvARB: procedure(size: GLint; weights: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightdvARB: procedure(size: GLint; weights: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightvARB: procedure(size: GLint; weights: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightubvARB: procedure(size: GLint; weights: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightusvARB: procedure(size: GLint; weights: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightuivARB: procedure(size: GLint; weights: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWeightPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexBlendARB: procedure(count: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_vertex_blend: Boolean;
+
+//***** GL_ARB_vertex_program *****//
+const
+ GL_VERTEX_PROGRAM_ARB = $8620;
+ GL_VERTEX_PROGRAM_POINT_SIZE_ARB = $8642;
+ GL_VERTEX_PROGRAM_TWO_SIDE_ARB = $8643;
+ GL_COLOR_SUM_ARB = $8458;
+ GL_PROGRAM_FORMAT_ASCII_ARB = $8875;
+ GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = $8622;
+ GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = $8623;
+ GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = $8624;
+ GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = $8625;
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = $886A;
+ GL_CURRENT_VERTEX_ATTRIB_ARB = $8626;
+ GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = $8645;
+ GL_PROGRAM_LENGTH_ARB = $8627;
+ GL_PROGRAM_FORMAT_ARB = $8876;
+ GL_PROGRAM_BINDING_ARB = $8677;
+ GL_PROGRAM_INSTRUCTIONS_ARB = $88A0;
+ GL_MAX_PROGRAM_INSTRUCTIONS_ARB = $88A1;
+ GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A2;
+ GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A3;
+ GL_PROGRAM_TEMPORARIES_ARB = $88A4;
+ GL_MAX_PROGRAM_TEMPORARIES_ARB = $88A5;
+ GL_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A6;
+ GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A7;
+ GL_PROGRAM_PARAMETERS_ARB = $88A8;
+ GL_MAX_PROGRAM_PARAMETERS_ARB = $88A9;
+ GL_PROGRAM_NATIVE_PARAMETERS_ARB = $88AA;
+ GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = $88AB;
+ GL_PROGRAM_ATTRIBS_ARB = $88AC;
+ GL_MAX_PROGRAM_ATTRIBS_ARB = $88AD;
+ GL_PROGRAM_NATIVE_ATTRIBS_ARB = $88AE;
+ GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = $88AF;
+ GL_PROGRAM_ADDRESS_REGISTERS_ARB = $88B0;
+ GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = $88B1;
+ GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B2;
+ GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B3;
+ GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = $88B4;
+ GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = $88B5;
+ GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = $88B6;
+ GL_PROGRAM_STRING_ARB = $8628;
+ GL_PROGRAM_ERROR_POSITION_ARB = $864B;
+ GL_CURRENT_MATRIX_ARB = $8641;
+ GL_TRANSPOSE_CURRENT_MATRIX_ARB = $88B7;
+ GL_CURRENT_MATRIX_STACK_DEPTH_ARB = $8640;
+ GL_MAX_VERTEX_ATTRIBS_ARB = $8869;
+ GL_MAX_PROGRAM_MATRICES_ARB = $862F;
+ GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = $862E;
+ GL_PROGRAM_ERROR_STRING_ARB = $8874;
+ GL_MATRIX0_ARB = $88C0;
+ GL_MATRIX1_ARB = $88C1;
+ GL_MATRIX2_ARB = $88C2;
+ GL_MATRIX3_ARB = $88C3;
+ GL_MATRIX4_ARB = $88C4;
+ GL_MATRIX5_ARB = $88C5;
+ GL_MATRIX6_ARB = $88C6;
+ GL_MATRIX7_ARB = $88C7;
+ GL_MATRIX8_ARB = $88C8;
+ GL_MATRIX9_ARB = $88C9;
+ GL_MATRIX10_ARB = $88CA;
+ GL_MATRIX11_ARB = $88CB;
+ GL_MATRIX12_ARB = $88CC;
+ GL_MATRIX13_ARB = $88CD;
+ GL_MATRIX14_ARB = $88CE;
+ GL_MATRIX15_ARB = $88CF;
+ GL_MATRIX16_ARB = $88D0;
+ GL_MATRIX17_ARB = $88D1;
+ GL_MATRIX18_ARB = $88D2;
+ GL_MATRIX19_ARB = $88D3;
+ GL_MATRIX20_ARB = $88D4;
+ GL_MATRIX21_ARB = $88D5;
+ GL_MATRIX22_ARB = $88D6;
+ GL_MATRIX23_ARB = $88D7;
+ GL_MATRIX24_ARB = $88D8;
+ GL_MATRIX25_ARB = $88D9;
+ GL_MATRIX26_ARB = $88DA;
+ GL_MATRIX27_ARB = $88DB;
+ GL_MATRIX28_ARB = $88DC;
+ GL_MATRIX29_ARB = $88DD;
+ GL_MATRIX30_ARB = $88DE;
+ GL_MATRIX31_ARB = $88DF;
+var
+ glVertexAttrib1sARB: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1fARB: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1dARB: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2sARB: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NubARB: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4bvARB: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4svARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4ivARB: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4ubvARB: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4usvARB: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4uivARB: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4fvARB: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4dvARB: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NbvARB: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NsvARB: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NivARB: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NubvARB: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NusvARB: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4NuivARB: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribPointerARB: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnableVertexAttribArrayARB: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDisableVertexAttribArrayARB: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramStringARB: procedure(target: GLenum; format: GLenum; len: GLsizei; const _string: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindProgramARB: procedure(target: GLenum; _program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteProgramsARB: procedure(n: GLsizei; const programs: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenProgramsARB: procedure(n: GLsizei; programs: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramEnvParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramEnvParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramEnvParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramEnvParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramLocalParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramLocalParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramLocalParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramLocalParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramEnvParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramEnvParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramLocalParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramLocalParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramStringARB: procedure(target: GLenum; pname: GLenum; _string: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribdvARB: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribfvARB: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribivARB: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribPointervARB: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsProgramARB: function(_program: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_vertex_program: Boolean;
+
+//***** GL_ARB_window_pos *****//
+var
+ glWindowPos2dARB: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2fARB: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2iARB: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2sARB: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2dvARB: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2fvARB: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2ivARB: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2svARB: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3dARB: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3fARB: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3iARB: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3sARB: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3dvARB: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3fvARB: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3ivARB: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3svARB: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_window_pos: Boolean;
+
+//***** GL_EXT_422_pixels *****//
+const
+ GL_422_EXT = $80CC;
+ GL_422_REV_EXT = $80CD;
+ GL_422_AVERAGE_EXT = $80CE;
+ GL_422_REV_AVERAGE_EXT = $80CF;
+
+function Load_GL_EXT_422_pixels: Boolean;
+
+//***** GL_EXT_abgr *****//
+const
+ GL_ABGR_EXT = $8000;
+
+function Load_GL_EXT_abgr: Boolean;
+
+//***** GL_EXT_bgra *****//
+const
+ GL_BGR_EXT = $80E0;
+ GL_BGRA_EXT = $80E1;
+
+function Load_GL_EXT_bgra: Boolean;
+
+//***** GL_EXT_blend_color *****//
+const
+ GL_CONSTANT_COLOR_EXT = $8001;
+ GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002;
+ GL_CONSTANT_ALPHA_EXT = $8003;
+ GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004;
+ GL_BLEND_COLOR_EXT = $8005;
+var
+ glBlendColorEXT: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_blend_color: Boolean;
+
+//***** GL_EXT_blend_func_separate *****//
+const
+ GL_BLEND_DST_RGB_EXT = $80C8;
+ GL_BLEND_SRC_RGB_EXT = $80C9;
+ GL_BLEND_DST_ALPHA_EXT = $80CA;
+ GL_BLEND_SRC_ALPHA_EXT = $80CB;
+var
+ glBlendFuncSeparateEXT: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_blend_func_separate: Boolean;
+
+//***** GL_EXT_blend_logic_op *****//
+
+function Load_GL_EXT_blend_logic_op: Boolean;
+
+//***** GL_EXT_blend_minmax *****//
+const
+ GL_FUNC_ADD_EXT = $8006;
+ GL_MIN_EXT = $8007;
+ GL_MAX_EXT = $8008;
+ GL_BLEND_EQUATION_EXT = $8009;
+var
+ glBlendEquationEXT: procedure(mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_blend_minmax: Boolean;
+
+//***** GL_EXT_blend_subtract *****//
+const
+ GL_FUNC_SUBTRACT_EXT = $800A;
+ GL_FUNC_REVERSE_SUBTRACT_EXT = $800B;
+
+function Load_GL_EXT_blend_subtract: Boolean;
+
+//***** GL_EXT_clip_volume_hint *****//
+const
+ GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0;
+
+function Load_GL_EXT_clip_volume_hint: Boolean;
+
+//***** GL_EXT_color_subtable *****//
+var
+ glColorSubTableEXT: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyColorSubTableEXT: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_color_subtable: Boolean;
+
+//***** GL_EXT_compiled_vertex_array *****//
+const
+ GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8;
+ GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9;
+var
+ glLockArraysEXT: procedure(first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUnlockArraysEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_compiled_vertex_array: Boolean;
+
+//***** GL_EXT_convolution *****//
+const
+ GL_CONVOLUTION_1D_EXT = $8010;
+ GL_CONVOLUTION_2D_EXT = $8011;
+ GL_SEPARABLE_2D_EXT = $8012;
+ GL_CONVOLUTION_BORDER_MODE_EXT = $8013;
+ GL_CONVOLUTION_FILTER_SCALE_EXT = $8014;
+ GL_CONVOLUTION_FILTER_BIAS_EXT = $8015;
+ GL_REDUCE_EXT = $8016;
+ GL_CONVOLUTION_FORMAT_EXT = $8017;
+ GL_CONVOLUTION_WIDTH_EXT = $8018;
+ GL_CONVOLUTION_HEIGHT_EXT = $8019;
+ GL_MAX_CONVOLUTION_WIDTH_EXT = $801A;
+ GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B;
+ GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C;
+ GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D;
+ GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E;
+ GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F;
+ GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020;
+ GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021;
+ GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022;
+ GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023;
+var
+ glConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSeparableFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetSeparableFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameteriEXT: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameterfEXT: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_convolution: Boolean;
+
+//***** GL_EXT_histogram *****//
+const
+ GL_HISTOGRAM_EXT = $8024;
+ GL_PROXY_HISTOGRAM_EXT = $8025;
+ GL_HISTOGRAM_WIDTH_EXT = $8026;
+ GL_HISTOGRAM_FORMAT_EXT = $8027;
+ GL_HISTOGRAM_RED_SIZE_EXT = $8028;
+ GL_HISTOGRAM_GREEN_SIZE_EXT = $8029;
+ GL_HISTOGRAM_BLUE_SIZE_EXT = $802A;
+ GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B;
+ GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C;
+ GL_HISTOGRAM_SINK_EXT = $802D;
+ GL_MINMAX_EXT = $802E;
+ GL_MINMAX_FORMAT_EXT = $802F;
+ GL_MINMAX_SINK_EXT = $8030;
+var
+ glHistogramEXT: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glResetHistogramEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogramEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogramParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHistogramParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMinmaxEXT: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glResetMinmaxEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmaxEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmaxParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMinmaxParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_histogram: Boolean;
+
+//***** GL_EXT_multi_draw_arrays *****//
+var
+ glMultiDrawArraysEXT: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawElementsEXT: procedure(mode: GLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_multi_draw_arrays: Boolean;
+
+//***** GL_EXT_packed_pixels *****//
+const
+ GL_UNSIGNED_BYTE_3_3_2_EXT = $8032;
+ GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033;
+ GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034;
+ GL_UNSIGNED_INT_8_8_8_8_EXT = $8035;
+ GL_UNSIGNED_INT_10_10_10_2_EXT = $8036;
+
+function Load_GL_EXT_packed_pixels: Boolean;
+
+//***** GL_EXT_paletted_texture *****//
+const
+ GL_COLOR_INDEX1_EXT = $80E2;
+ GL_COLOR_INDEX2_EXT = $80E3;
+ GL_COLOR_INDEX4_EXT = $80E4;
+ GL_COLOR_INDEX8_EXT = $80E5;
+ GL_COLOR_INDEX12_EXT = $80E6;
+ GL_COLOR_INDEX16_EXT = $80E7;
+ GL_COLOR_TABLE_FORMAT_EXT = $80D8;
+ GL_COLOR_TABLE_WIDTH_EXT = $80D9;
+ GL_COLOR_TABLE_RED_SIZE_EXT = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF;
+ GL_TEXTURE_INDEX_SIZE_EXT = $80ED;
+ GL_TEXTURE_1D = $0DE0;
+ GL_TEXTURE_2D = $0DE1;
+ GL_TEXTURE_3D_EXT = $806F;
+ // GL_TEXTURE_CUBE_MAP_ARB { already defined }
+ GL_PROXY_TEXTURE_1D = $8063;
+ GL_PROXY_TEXTURE_2D = $8064;
+ GL_PROXY_TEXTURE_3D_EXT = $8070;
+ // GL_PROXY_TEXTURE_CUBE_MAP_ARB { already defined }
+ // GL_TEXTURE_1D { already defined }
+ // GL_TEXTURE_2D { already defined }
+ // GL_TEXTURE_3D_EXT { already defined }
+ // GL_TEXTURE_CUBE_MAP_ARB { already defined }
+var
+ glColorTableEXT: procedure(target: GLenum; internalFormat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ // glColorSubTableEXT { already defined }
+ glGetColorTableEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_paletted_texture: Boolean;
+
+//***** GL_EXT_point_parameters *****//
+const
+ GL_POINT_SIZE_MIN_EXT = $8126;
+ GL_POINT_SIZE_MAX_EXT = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128;
+ GL_DISTANCE_ATTENUATION_EXT = $8129;
+var
+ glPointParameterfEXT: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameterfvEXT: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_point_parameters: Boolean;
+
+//***** GL_EXT_polygon_offset *****//
+const
+ GL_POLYGON_OFFSET_EXT = $8037;
+ GL_POLYGON_OFFSET_FACTOR_EXT = $8038;
+ GL_POLYGON_OFFSET_BIAS_EXT = $8039;
+var
+ glPolygonOffsetEXT: procedure(factor: GLfloat; bias: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_polygon_offset: Boolean;
+
+//***** GL_EXT_separate_specular_color *****//
+const
+ GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8;
+ GL_SINGLE_COLOR_EXT = $81F9;
+ GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA;
+
+function Load_GL_EXT_separate_specular_color: Boolean;
+
+//***** GL_EXT_shadow_funcs *****//
+
+function Load_GL_EXT_shadow_funcs: Boolean;
+
+//***** GL_EXT_shared_texture_palette *****//
+const
+ GL_SHARED_TEXTURE_PALETTE_EXT = $81FB;
+
+function Load_GL_EXT_shared_texture_palette: Boolean;
+
+//***** GL_EXT_stencil_two_side *****//
+const
+ GL_STENCIL_TEST_TWO_SIDE_EXT = $8910;
+ GL_ACTIVE_STENCIL_FACE_EXT = $8911;
+var
+ glActiveStencilFaceEXT: procedure(face: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_stencil_two_side: Boolean;
+
+//***** GL_EXT_stencil_wrap *****//
+const
+ GL_INCR_WRAP_EXT = $8507;
+ GL_DECR_WRAP_EXT = $8508;
+
+function Load_GL_EXT_stencil_wrap: Boolean;
+
+//***** GL_EXT_subtexture *****//
+var
+ glTexSubImage1DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage2DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage3DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_subtexture: Boolean;
+
+//***** GL_EXT_texture3D *****//
+const
+ GL_PACK_SKIP_IMAGES_EXT = $806B;
+ GL_PACK_IMAGE_HEIGHT_EXT = $806C;
+ GL_UNPACK_SKIP_IMAGES_EXT = $806D;
+ GL_UNPACK_IMAGE_HEIGHT_EXT = $806E;
+ // GL_TEXTURE_3D_EXT { already defined }
+ // GL_PROXY_TEXTURE_3D_EXT { already defined }
+ GL_TEXTURE_DEPTH_EXT = $8071;
+ GL_TEXTURE_WRAP_R_EXT = $8072;
+ GL_MAX_3D_TEXTURE_SIZE_EXT = $8073;
+var
+ glTexImage3DEXT: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_texture3D: Boolean;
+
+//***** GL_EXT_texture_compression_s3tc *****//
+const
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
+
+function Load_GL_EXT_texture_compression_s3tc: Boolean;
+
+//***** GL_EXT_texture_env_add *****//
+
+function Load_GL_EXT_texture_env_add: Boolean;
+
+//***** GL_EXT_texture_env_combine *****//
+const
+ GL_COMBINE_EXT = $8570;
+ GL_COMBINE_RGB_EXT = $8571;
+ GL_COMBINE_ALPHA_EXT = $8572;
+ GL_SOURCE0_RGB_EXT = $8580;
+ GL_SOURCE1_RGB_EXT = $8581;
+ GL_SOURCE2_RGB_EXT = $8582;
+ GL_SOURCE0_ALPHA_EXT = $8588;
+ GL_SOURCE1_ALPHA_EXT = $8589;
+ GL_SOURCE2_ALPHA_EXT = $858A;
+ GL_OPERAND0_RGB_EXT = $8590;
+ GL_OPERAND1_RGB_EXT = $8591;
+ GL_OPERAND2_RGB_EXT = $8592;
+ GL_OPERAND0_ALPHA_EXT = $8598;
+ GL_OPERAND1_ALPHA_EXT = $8599;
+ GL_OPERAND2_ALPHA_EXT = $859A;
+ GL_RGB_SCALE_EXT = $8573;
+ GL_ADD_SIGNED_EXT = $8574;
+ GL_INTERPOLATE_EXT = $8575;
+ GL_CONSTANT_EXT = $8576;
+ GL_PRIMARY_COLOR_EXT = $8577;
+ GL_PREVIOUS_EXT = $8578;
+
+function Load_GL_EXT_texture_env_combine: Boolean;
+
+//***** GL_EXT_texture_env_dot3 *****//
+const
+ GL_DOT3_RGB_EXT = $8740;
+ GL_DOT3_RGBA_EXT = $8741;
+
+function Load_GL_EXT_texture_env_dot3: Boolean;
+
+//***** GL_EXT_texture_filter_anisotropic *****//
+const
+ GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
+
+function Load_GL_EXT_texture_filter_anisotropic: Boolean;
+
+//***** GL_EXT_texture_lod_bias *****//
+const
+ GL_TEXTURE_FILTER_CONTROL_EXT = $8500;
+ GL_TEXTURE_LOD_BIAS_EXT = $8501;
+ GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD;
+
+function Load_GL_EXT_texture_lod_bias: Boolean;
+
+//***** GL_EXT_texture_object *****//
+const
+ GL_TEXTURE_PRIORITY_EXT = $8066;
+ GL_TEXTURE_RESIDENT_EXT = $8067;
+ GL_TEXTURE_1D_BINDING_EXT = $8068;
+ GL_TEXTURE_2D_BINDING_EXT = $8069;
+ GL_TEXTURE_3D_BINDING_EXT = $806A;
+var
+ glGenTexturesEXT: procedure(n: GLsizei; textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteTexturesEXT: procedure(n: GLsizei; const textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindTextureEXT: procedure(target: GLenum; texture: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPrioritizeTexturesEXT: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAreTexturesResidentEXT: function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsTextureEXT: function(texture: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_texture_object: Boolean;
+
+//***** GL_EXT_vertex_array *****//
+const
+ GL_VERTEX_ARRAY_EXT = $8074;
+ GL_NORMAL_ARRAY_EXT = $8075;
+ GL_COLOR_ARRAY_EXT = $8076;
+ GL_INDEX_ARRAY_EXT = $8077;
+ GL_TEXTURE_COORD_ARRAY_EXT = $8078;
+ GL_EDGE_FLAG_ARRAY_EXT = $8079;
+ GL_DOUBLE_EXT = $140A;
+ GL_VERTEX_ARRAY_SIZE_EXT = $807A;
+ GL_VERTEX_ARRAY_TYPE_EXT = $807B;
+ GL_VERTEX_ARRAY_STRIDE_EXT = $807C;
+ GL_VERTEX_ARRAY_COUNT_EXT = $807D;
+ GL_NORMAL_ARRAY_TYPE_EXT = $807E;
+ GL_NORMAL_ARRAY_STRIDE_EXT = $807F;
+ GL_NORMAL_ARRAY_COUNT_EXT = $8080;
+ GL_COLOR_ARRAY_SIZE_EXT = $8081;
+ GL_COLOR_ARRAY_TYPE_EXT = $8082;
+ GL_COLOR_ARRAY_STRIDE_EXT = $8083;
+ GL_COLOR_ARRAY_COUNT_EXT = $8084;
+ GL_INDEX_ARRAY_TYPE_EXT = $8085;
+ GL_INDEX_ARRAY_STRIDE_EXT = $8086;
+ GL_INDEX_ARRAY_COUNT_EXT = $8087;
+ GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088;
+ GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089;
+ GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A;
+ GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B;
+ GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C;
+ GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D;
+ GL_VERTEX_ARRAY_POINTER_EXT = $808E;
+ GL_NORMAL_ARRAY_POINTER_EXT = $808F;
+ GL_COLOR_ARRAY_POINTER_EXT = $8090;
+ GL_INDEX_ARRAY_POINTER_EXT = $8091;
+ GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092;
+ GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093;
+var
+ glArrayElementEXT: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawArraysEXT: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoordPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagPointerEXT: procedure(stride: GLsizei; count: GLsizei; const pointer: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPointervEXT: procedure(pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_vertex_array: Boolean;
+
+//***** GL_EXT_vertex_shader *****//
+const
+ GL_VERTEX_SHADER_EXT = $8780;
+ GL_VARIANT_VALUE_EXT = $87E4;
+ GL_VARIANT_DATATYPE_EXT = $87E5;
+ GL_VARIANT_ARRAY_STRIDE_EXT = $87E6;
+ GL_VARIANT_ARRAY_TYPE_EXT = $87E7;
+ GL_VARIANT_ARRAY_EXT = $87E8;
+ GL_VARIANT_ARRAY_POINTER_EXT = $87E9;
+ GL_INVARIANT_VALUE_EXT = $87EA;
+ GL_INVARIANT_DATATYPE_EXT = $87EB;
+ GL_LOCAL_CONSTANT_VALUE_EXT = $87EC;
+ GL_LOCAL_CONSTANT_DATATYPE_EXT = $87ED;
+ GL_OP_INDEX_EXT = $8782;
+ GL_OP_NEGATE_EXT = $8783;
+ GL_OP_DOT3_EXT = $8784;
+ GL_OP_DOT4_EXT = $8785;
+ GL_OP_MUL_EXT = $8786;
+ GL_OP_ADD_EXT = $8787;
+ GL_OP_MADD_EXT = $8788;
+ GL_OP_FRAC_EXT = $8789;
+ GL_OP_MAX_EXT = $878A;
+ GL_OP_MIN_EXT = $878B;
+ GL_OP_SET_GE_EXT = $878C;
+ GL_OP_SET_LT_EXT = $878D;
+ GL_OP_CLAMP_EXT = $878E;
+ GL_OP_FLOOR_EXT = $878F;
+ GL_OP_ROUND_EXT = $8790;
+ GL_OP_EXP_BASE_2_EXT = $8791;
+ GL_OP_LOG_BASE_2_EXT = $8792;
+ GL_OP_POWER_EXT = $8793;
+ GL_OP_RECIP_EXT = $8794;
+ GL_OP_RECIP_SQRT_EXT = $8795;
+ GL_OP_SUB_EXT = $8796;
+ GL_OP_CROSS_PRODUCT_EXT = $8797;
+ GL_OP_MULTIPLY_MATRIX_EXT = $8798;
+ GL_OP_MOV_EXT = $8799;
+ GL_OUTPUT_VERTEX_EXT = $879A;
+ GL_OUTPUT_COLOR0_EXT = $879B;
+ GL_OUTPUT_COLOR1_EXT = $879C;
+ GL_OUTPUT_TEXTURE_COORD0_EXT = $879D;
+ GL_OUTPUT_TEXTURE_COORD1_EXT = $879E;
+ GL_OUTPUT_TEXTURE_COORD2_EXT = $879F;
+ GL_OUTPUT_TEXTURE_COORD3_EXT = $87A0;
+ GL_OUTPUT_TEXTURE_COORD4_EXT = $87A1;
+ GL_OUTPUT_TEXTURE_COORD5_EXT = $87A2;
+ GL_OUTPUT_TEXTURE_COORD6_EXT = $87A3;
+ GL_OUTPUT_TEXTURE_COORD7_EXT = $87A4;
+ GL_OUTPUT_TEXTURE_COORD8_EXT = $87A5;
+ GL_OUTPUT_TEXTURE_COORD9_EXT = $87A6;
+ GL_OUTPUT_TEXTURE_COORD10_EXT = $87A7;
+ GL_OUTPUT_TEXTURE_COORD11_EXT = $87A8;
+ GL_OUTPUT_TEXTURE_COORD12_EXT = $87A9;
+ GL_OUTPUT_TEXTURE_COORD13_EXT = $87AA;
+ GL_OUTPUT_TEXTURE_COORD14_EXT = $87AB;
+ GL_OUTPUT_TEXTURE_COORD15_EXT = $87AC;
+ GL_OUTPUT_TEXTURE_COORD16_EXT = $87AD;
+ GL_OUTPUT_TEXTURE_COORD17_EXT = $87AE;
+ GL_OUTPUT_TEXTURE_COORD18_EXT = $87AF;
+ GL_OUTPUT_TEXTURE_COORD19_EXT = $87B0;
+ GL_OUTPUT_TEXTURE_COORD20_EXT = $87B1;
+ GL_OUTPUT_TEXTURE_COORD21_EXT = $87B2;
+ GL_OUTPUT_TEXTURE_COORD22_EXT = $87B3;
+ GL_OUTPUT_TEXTURE_COORD23_EXT = $87B4;
+ GL_OUTPUT_TEXTURE_COORD24_EXT = $87B5;
+ GL_OUTPUT_TEXTURE_COORD25_EXT = $87B6;
+ GL_OUTPUT_TEXTURE_COORD26_EXT = $87B7;
+ GL_OUTPUT_TEXTURE_COORD27_EXT = $87B8;
+ GL_OUTPUT_TEXTURE_COORD28_EXT = $87B9;
+ GL_OUTPUT_TEXTURE_COORD29_EXT = $87BA;
+ GL_OUTPUT_TEXTURE_COORD30_EXT = $87BB;
+ GL_OUTPUT_TEXTURE_COORD31_EXT = $87BC;
+ GL_OUTPUT_FOG_EXT = $87BD;
+ GL_SCALAR_EXT = $87BE;
+ GL_VECTOR_EXT = $87BF;
+ GL_MATRIX_EXT = $87C0;
+ GL_VARIANT_EXT = $87C1;
+ GL_INVARIANT_EXT = $87C2;
+ GL_LOCAL_CONSTANT_EXT = $87C3;
+ GL_LOCAL_EXT = $87C4;
+ GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = $87C5;
+ GL_MAX_VERTEX_SHADER_VARIANTS_EXT = $87C6;
+ GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = $87C7;
+ GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87C8;
+ GL_MAX_VERTEX_SHADER_LOCALS_EXT = $87C9;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CA;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = $87CB;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87CC;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = $87CD;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = $87CE;
+ GL_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CF;
+ GL_VERTEX_SHADER_VARIANTS_EXT = $87D0;
+ GL_VERTEX_SHADER_INVARIANTS_EXT = $87D1;
+ GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87D2;
+ GL_VERTEX_SHADER_LOCALS_EXT = $87D3;
+ GL_VERTEX_SHADER_BINDING_EXT = $8781;
+ GL_VERTEX_SHADER_OPTIMIZED_EXT = $87D4;
+ GL_X_EXT = $87D5;
+ GL_Y_EXT = $87D6;
+ GL_Z_EXT = $87D7;
+ GL_W_EXT = $87D8;
+ GL_NEGATIVE_X_EXT = $87D9;
+ GL_NEGATIVE_Y_EXT = $87DA;
+ GL_NEGATIVE_Z_EXT = $87DB;
+ GL_NEGATIVE_W_EXT = $87DC;
+ GL_ZERO_EXT = $87DD;
+ GL_ONE_EXT = $87DE;
+ GL_NEGATIVE_ONE_EXT = $87DF;
+ GL_NORMALIZED_RANGE_EXT = $87E0;
+ GL_FULL_RANGE_EXT = $87E1;
+ GL_CURRENT_VERTEX_EXT = $87E2;
+ GL_MVP_MATRIX_EXT = $87E3;
+var
+ glBeginVertexShaderEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndVertexShaderEXT: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindVertexShaderEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenVertexShadersEXT: function(range: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteVertexShaderEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShaderOp1EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShaderOp2EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShaderOp3EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint; arg3: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSwizzleEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWriteMaskEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glInsertComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glExtractComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenSymbolsEXT: function(datatype: GLenum; storagetype: GLenum; range: GLenum; components: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSetInvariantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSetLocalConstantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantbvEXT: procedure(id: GLuint; addr: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantsvEXT: procedure(id: GLuint; addr: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantivEXT: procedure(id: GLuint; addr: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantfvEXT: procedure(id: GLuint; addr: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantdvEXT: procedure(id: GLuint; addr: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantubvEXT: procedure(id: GLuint; addr: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantusvEXT: procedure(id: GLuint; addr: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantuivEXT: procedure(id: GLuint; addr: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantPointerEXT: procedure(id: GLuint; _type: GLenum; stride: GLuint; addr: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnableVariantClientStateEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDisableVariantClientStateEXT: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindLightParameterEXT: function(light: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindMaterialParameterEXT: function(face: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindTexGenParameterEXT: function(_unit: GLenum; coord: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindTextureUnitParameterEXT: function(_unit: GLenum; value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindParameterEXT: function(value: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsVariantEnabledEXT: function(id: GLuint; cap: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantPointervEXT: procedure(id: GLuint; value: GLenum; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetInvariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetInvariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetInvariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLocalConstantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLocalConstantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLocalConstantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_vertex_shader: Boolean;
+
+//***** GL_EXT_vertex_weighting *****//
+const
+ GL_VERTEX_WEIGHTING_EXT = $8509;
+ GL_MODELVIEW0_EXT = $1700;
+ GL_MODELVIEW1_EXT = $850A;
+ GL_MODELVIEW0_MATRIX_EXT = $0BA6;
+ GL_MODELVIEW1_MATRIX_EXT = $8506;
+ GL_CURRENT_VERTEX_WEIGHT_EXT = $850B;
+ GL_VERTEX_WEIGHT_ARRAY_EXT = $850C;
+ GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D;
+ GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E;
+ GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F;
+ GL_MODELVIEW0_STACK_DEPTH_EXT = $0BA3;
+ GL_MODELVIEW1_STACK_DEPTH_EXT = $8502;
+ GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510;
+var
+ glVertexWeightfEXT: procedure(weight: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexWeightfvEXT: procedure(weight: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexWeightPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_vertex_weighting: Boolean;
+
+//***** GL_HP_occlusion_test *****//
+const
+ GL_OCCLUSION_TEST_HP = $8165;
+ GL_OCCLUSION_TEST_RESULT_HP = $8166;
+
+function Load_GL_HP_occlusion_test: Boolean;
+
+//***** GL_NV_blend_square *****//
+
+function Load_GL_NV_blend_square: Boolean;
+
+//***** GL_NV_copy_depth_to_color *****//
+const
+ GL_DEPTH_STENCIL_TO_RGBA_NV = $886E;
+ GL_DEPTH_STENCIL_TO_BGRA_NV = $886F;
+
+function Load_GL_NV_copy_depth_to_color: Boolean;
+
+//***** GL_NV_depth_clamp *****//
+const
+ GL_DEPTH_CLAMP_NV = $864F;
+
+function Load_GL_NV_depth_clamp: Boolean;
+
+//***** GL_NV_evaluators *****//
+const
+ GL_EVAL_2D_NV = $86C0;
+ GL_EVAL_TRIANGULAR_2D_NV = $86C1;
+ GL_MAP_TESSELLATION_NV = $86C2;
+ GL_MAP_ATTRIB_U_ORDER_NV = $86C3;
+ GL_MAP_ATTRIB_V_ORDER_NV = $86C4;
+ GL_EVAL_FRACTIONAL_TESSELLATION_NV = $86C5;
+ GL_EVAL_VERTEX_ATTRIB0_NV = $86C6;
+ GL_EVAL_VERTEX_ATTRIB1_NV = $86C7;
+ GL_EVAL_VERTEX_ATTRIB2_NV = $86C8;
+ GL_EVAL_VERTEX_ATTRIB3_NV = $86C9;
+ GL_EVAL_VERTEX_ATTRIB4_NV = $86CA;
+ GL_EVAL_VERTEX_ATTRIB5_NV = $86CB;
+ GL_EVAL_VERTEX_ATTRIB6_NV = $86CC;
+ GL_EVAL_VERTEX_ATTRIB7_NV = $86CD;
+ GL_EVAL_VERTEX_ATTRIB8_NV = $86CE;
+ GL_EVAL_VERTEX_ATTRIB9_NV = $86CF;
+ GL_EVAL_VERTEX_ATTRIB10_NV = $86D0;
+ GL_EVAL_VERTEX_ATTRIB11_NV = $86D1;
+ GL_EVAL_VERTEX_ATTRIB12_NV = $86D2;
+ GL_EVAL_VERTEX_ATTRIB13_NV = $86D3;
+ GL_EVAL_VERTEX_ATTRIB14_NV = $86D4;
+ GL_EVAL_VERTEX_ATTRIB15_NV = $86D5;
+ GL_MAX_MAP_TESSELLATION_NV = $86D6;
+ GL_MAX_RATIONAL_EVAL_ORDER_NV = $86D7;
+var
+ glMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; uorder: GLint; vorder: GLint; _packed: GLboolean; const points: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapParameterivNV: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapParameterfvNV: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; _packed: GLboolean; points: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapParameterivNV: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapParameterfvNV: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapAttribParameterivNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapAttribParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalMapsNV: procedure(target: GLenum; mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_evaluators: Boolean;
+
+//***** GL_NV_fence *****//
+const
+ GL_ALL_COMPLETED_NV = $84F2;
+ GL_FENCE_STATUS_NV = $84F3;
+ GL_FENCE_CONDITION_NV = $84F4;
+var
+ glGenFencesNV: procedure(n: GLsizei; fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteFencesNV: procedure(n: GLsizei; const fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSetFenceNV: procedure(fence: GLuint; condition: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTestFenceNV: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFinishFenceNV: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsFenceNV: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFenceivNV: procedure(fence: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_fence: Boolean;
+
+//***** GL_NV_fog_distance *****//
+const
+ GL_FOG_DISTANCE_MODE_NV = $855A;
+ GL_EYE_RADIAL_NV = $855B;
+ GL_EYE_PLANE_ABSOLUTE_NV = $855C;
+
+function Load_GL_NV_fog_distance: Boolean;
+
+//***** GL_NV_light_max_exponent *****//
+const
+ GL_MAX_SHININESS_NV = $8504;
+ GL_MAX_SPOT_EXPONENT_NV = $8505;
+
+function Load_GL_NV_light_max_exponent: Boolean;
+
+//***** GL_NV_multisample_filter_hint *****//
+const
+ GL_MULTISAMPLE_FILTER_HINT_NV = $8534;
+
+function Load_GL_NV_multisample_filter_hint: Boolean;
+
+//***** GL_NV_occlusion_query *****//
+ // GL_OCCLUSION_TEST_HP { already defined }
+ // GL_OCCLUSION_TEST_RESULT_HP { already defined }
+const
+ GL_PIXEL_COUNTER_BITS_NV = $8864;
+ GL_CURRENT_OCCLUSION_QUERY_ID_NV = $8865;
+ GL_PIXEL_COUNT_NV = $8866;
+ GL_PIXEL_COUNT_AVAILABLE_NV = $8867;
+var
+ glGenOcclusionQueriesNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteOcclusionQueriesNV: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsOcclusionQueryNV: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBeginOcclusionQueryNV: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndOcclusionQueryNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetOcclusionQueryivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetOcclusionQueryuivNV: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_occlusion_query: Boolean;
+
+//***** GL_NV_packed_depth_stencil *****//
+const
+ GL_DEPTH_STENCIL_NV = $84F9;
+ GL_UNSIGNED_INT_24_8_NV = $84FA;
+
+function Load_GL_NV_packed_depth_stencil: Boolean;
+
+//***** GL_NV_point_sprite *****//
+const
+ GL_POINT_SPRITE_NV = $8861;
+ GL_COORD_REPLACE_NV = $8862;
+ GL_POINT_SPRITE_R_MODE_NV = $8863;
+var
+ glPointParameteriNV: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameterivNV: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_point_sprite: Boolean;
+
+//***** GL_NV_register_combiners *****//
+const
+ GL_REGISTER_COMBINERS_NV = $8522;
+ GL_COMBINER0_NV = $8550;
+ GL_COMBINER1_NV = $8551;
+ GL_COMBINER2_NV = $8552;
+ GL_COMBINER3_NV = $8553;
+ GL_COMBINER4_NV = $8554;
+ GL_COMBINER5_NV = $8555;
+ GL_COMBINER6_NV = $8556;
+ GL_COMBINER7_NV = $8557;
+ GL_VARIABLE_A_NV = $8523;
+ GL_VARIABLE_B_NV = $8524;
+ GL_VARIABLE_C_NV = $8525;
+ GL_VARIABLE_D_NV = $8526;
+ GL_VARIABLE_E_NV = $8527;
+ GL_VARIABLE_F_NV = $8528;
+ GL_VARIABLE_G_NV = $8529;
+ GL_CONSTANT_COLOR0_NV = $852A;
+ GL_CONSTANT_COLOR1_NV = $852B;
+ GL_PRIMARY_COLOR_NV = $852C;
+ GL_SECONDARY_COLOR_NV = $852D;
+ GL_SPARE0_NV = $852E;
+ GL_SPARE1_NV = $852F;
+ GL_UNSIGNED_IDENTITY_NV = $8536;
+ GL_UNSIGNED_INVERT_NV = $8537;
+ GL_EXPAND_NORMAL_NV = $8538;
+ GL_EXPAND_NEGATE_NV = $8539;
+ GL_HALF_BIAS_NORMAL_NV = $853A;
+ GL_HALF_BIAS_NEGATE_NV = $853B;
+ GL_SIGNED_IDENTITY_NV = $853C;
+ GL_SIGNED_NEGATE_NV = $853D;
+ GL_E_TIMES_F_NV = $8531;
+ GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532;
+ GL_SCALE_BY_TWO_NV = $853E;
+ GL_SCALE_BY_FOUR_NV = $853F;
+ GL_SCALE_BY_ONE_HALF_NV = $8540;
+ GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541;
+ GL_DISCARD_NV = $8530;
+ GL_COMBINER_INPUT_NV = $8542;
+ GL_COMBINER_MAPPING_NV = $8543;
+ GL_COMBINER_COMPONENT_USAGE_NV = $8544;
+ GL_COMBINER_AB_DOT_PRODUCT_NV = $8545;
+ GL_COMBINER_CD_DOT_PRODUCT_NV = $8546;
+ GL_COMBINER_MUX_SUM_NV = $8547;
+ GL_COMBINER_SCALE_NV = $8548;
+ GL_COMBINER_BIAS_NV = $8549;
+ GL_COMBINER_AB_OUTPUT_NV = $854A;
+ GL_COMBINER_CD_OUTPUT_NV = $854B;
+ GL_COMBINER_SUM_OUTPUT_NV = $854C;
+ GL_NUM_GENERAL_COMBINERS_NV = $854E;
+ GL_COLOR_SUM_CLAMP_NV = $854F;
+ GL_MAX_GENERAL_COMBINERS_NV = $854D;
+var
+ glCombinerParameterfvNV: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCombinerParameterivNV: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCombinerParameterfNV: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCombinerParameteriNV: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCombinerInputNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCombinerOutputNV: procedure(stage: GLenum; portion: GLenum; abOutput: GLenum; cdOutput: GLenum; sumOutput: GLenum; scale: GLenum; bias: GLenum; abDotProduct: GLboolean; cdDotProduct: GLboolean; muxSum: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFinalCombinerInputNV: procedure(variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCombinerInputParameterfvNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCombinerInputParameterivNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCombinerOutputParameterfvNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCombinerOutputParameterivNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFinalCombinerInputParameterfvNV: procedure(variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFinalCombinerInputParameterivNV: procedure(variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_register_combiners: Boolean;
+
+//***** GL_NV_register_combiners2 *****//
+const
+ GL_PER_STAGE_CONSTANTS_NV = $8535;
+var
+ glCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_register_combiners2: Boolean;
+
+//***** GL_NV_texgen_emboss *****//
+const
+ GL_EMBOSS_MAP_NV = $855F;
+ GL_EMBOSS_LIGHT_NV = $855D;
+ GL_EMBOSS_CONSTANT_NV = $855E;
+
+function Load_GL_NV_texgen_emboss: Boolean;
+
+//***** GL_NV_texgen_reflection *****//
+const
+ GL_NORMAL_MAP_NV = $8511;
+ GL_REFLECTION_MAP_NV = $8512;
+
+function Load_GL_NV_texgen_reflection: Boolean;
+
+//***** GL_NV_texture_compression_vtc *****//
+ // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined }
+ // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined }
+ // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT { already defined }
+ // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT { already defined }
+
+function Load_GL_NV_texture_compression_vtc: Boolean;
+
+//***** GL_NV_texture_env_combine4 *****//
+const
+ GL_COMBINE4_NV = $8503;
+ GL_SOURCE3_RGB_NV = $8583;
+ GL_SOURCE3_ALPHA_NV = $858B;
+ GL_OPERAND3_RGB_NV = $8593;
+ GL_OPERAND3_ALPHA_NV = $859B;
+
+function Load_GL_NV_texture_env_combine4: Boolean;
+
+//***** GL_NV_texture_rectangle *****//
+const
+ GL_TEXTURE_RECTANGLE_NV = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_NV = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_NV = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = $84F8;
+
+function Load_GL_NV_texture_rectangle: Boolean;
+
+//***** GL_NV_texture_shader *****//
+const
+ GL_TEXTURE_SHADER_NV = $86DE;
+ GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = $86D9;
+ GL_SHADER_OPERATION_NV = $86DF;
+ GL_CULL_MODES_NV = $86E0;
+ GL_OFFSET_TEXTURE_MATRIX_NV = $86E1;
+ GL_OFFSET_TEXTURE_SCALE_NV = $86E2;
+ GL_OFFSET_TEXTURE_BIAS_NV = $86E3;
+ GL_PREVIOUS_TEXTURE_INPUT_NV = $86E4;
+ GL_CONST_EYE_NV = $86E5;
+ GL_SHADER_CONSISTENT_NV = $86DD;
+ GL_PASS_THROUGH_NV = $86E6;
+ GL_CULL_FRAGMENT_NV = $86E7;
+ GL_OFFSET_TEXTURE_2D_NV = $86E8;
+ GL_OFFSET_TEXTURE_RECTANGLE_NV = $864C;
+ GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = $864D;
+ GL_DEPENDENT_AR_TEXTURE_2D_NV = $86E9;
+ GL_DEPENDENT_GB_TEXTURE_2D_NV = $86EA;
+ GL_DOT_PRODUCT_NV = $86EC;
+ GL_DOT_PRODUCT_DEPTH_REPLACE_NV = $86ED;
+ GL_DOT_PRODUCT_TEXTURE_2D_NV = $86EE;
+ GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = $864E;
+ GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = $86F0;
+ GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = $86F1;
+ GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = $86F2;
+ GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = $86F3;
+ GL_HILO_NV = $86F4;
+ GL_DSDT_NV = $86F5;
+ GL_DSDT_MAG_NV = $86F6;
+ GL_DSDT_MAG_VIB_NV = $86F7;
+ GL_UNSIGNED_INT_S8_S8_8_8_NV = $86DA;
+ GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = $86DB;
+ GL_SIGNED_RGBA_NV = $86FB;
+ GL_SIGNED_RGBA8_NV = $86FC;
+ GL_SIGNED_RGB_NV = $86FE;
+ GL_SIGNED_RGB8_NV = $86FF;
+ GL_SIGNED_LUMINANCE_NV = $8701;
+ GL_SIGNED_LUMINANCE8_NV = $8702;
+ GL_SIGNED_LUMINANCE_ALPHA_NV = $8703;
+ GL_SIGNED_LUMINANCE8_ALPHA8_NV = $8704;
+ GL_SIGNED_ALPHA_NV = $8705;
+ GL_SIGNED_ALPHA8_NV = $8706;
+ GL_SIGNED_INTENSITY_NV = $8707;
+ GL_SIGNED_INTENSITY8_NV = $8708;
+ GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = $870C;
+ GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = $870D;
+ GL_HILO16_NV = $86F8;
+ GL_SIGNED_HILO_NV = $86F9;
+ GL_SIGNED_HILO16_NV = $86FA;
+ GL_DSDT8_NV = $8709;
+ GL_DSDT8_MAG8_NV = $870A;
+ GL_DSDT_MAG_INTENSITY_NV = $86DC;
+ GL_DSDT8_MAG8_INTENSITY8_NV = $870B;
+ GL_HI_SCALE_NV = $870E;
+ GL_LO_SCALE_NV = $870F;
+ GL_DS_SCALE_NV = $8710;
+ GL_DT_SCALE_NV = $8711;
+ GL_MAGNITUDE_SCALE_NV = $8712;
+ GL_VIBRANCE_SCALE_NV = $8713;
+ GL_HI_BIAS_NV = $8714;
+ GL_LO_BIAS_NV = $8715;
+ GL_DS_BIAS_NV = $8716;
+ GL_DT_BIAS_NV = $8717;
+ GL_MAGNITUDE_BIAS_NV = $8718;
+ GL_VIBRANCE_BIAS_NV = $8719;
+ GL_TEXTURE_BORDER_VALUES_NV = $871A;
+ GL_TEXTURE_HI_SIZE_NV = $871B;
+ GL_TEXTURE_LO_SIZE_NV = $871C;
+ GL_TEXTURE_DS_SIZE_NV = $871D;
+ GL_TEXTURE_DT_SIZE_NV = $871E;
+ GL_TEXTURE_MAG_SIZE_NV = $871F;
+
+function Load_GL_NV_texture_shader: Boolean;
+
+//***** GL_NV_texture_shader2 *****//
+const
+ GL_DOT_PRODUCT_TEXTURE_3D_NV = $86EF;
+ // GL_HILO_NV { already defined }
+ // GL_DSDT_NV { already defined }
+ // GL_DSDT_MAG_NV { already defined }
+ // GL_DSDT_MAG_VIB_NV { already defined }
+ // GL_UNSIGNED_INT_S8_S8_8_8_NV { already defined }
+ // GL_UNSIGNED_INT_8_8_S8_S8_REV_NV { already defined }
+ // GL_SIGNED_RGBA_NV { already defined }
+ // GL_SIGNED_RGBA8_NV { already defined }
+ // GL_SIGNED_RGB_NV { already defined }
+ // GL_SIGNED_RGB8_NV { already defined }
+ // GL_SIGNED_LUMINANCE_NV { already defined }
+ // GL_SIGNED_LUMINANCE8_NV { already defined }
+ // GL_SIGNED_LUMINANCE_ALPHA_NV { already defined }
+ // GL_SIGNED_LUMINANCE8_ALPHA8_NV { already defined }
+ // GL_SIGNED_ALPHA_NV { already defined }
+ // GL_SIGNED_ALPHA8_NV { already defined }
+ // GL_SIGNED_INTENSITY_NV { already defined }
+ // GL_SIGNED_INTENSITY8_NV { already defined }
+ // GL_SIGNED_RGB_UNSIGNED_ALPHA_NV { already defined }
+ // GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV { already defined }
+ // GL_HILO16_NV { already defined }
+ // GL_SIGNED_HILO_NV { already defined }
+ // GL_SIGNED_HILO16_NV { already defined }
+ // GL_DSDT8_NV { already defined }
+ // GL_DSDT8_MAG8_NV { already defined }
+ // GL_DSDT_MAG_INTENSITY_NV { already defined }
+ // GL_DSDT8_MAG8_INTENSITY8_NV { already defined }
+
+function Load_GL_NV_texture_shader2: Boolean;
+
+//***** GL_NV_texture_shader3 *****//
+const
+ GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = $8850;
+ GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = $8851;
+ GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8852;
+ GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = $8853;
+ GL_OFFSET_HILO_TEXTURE_2D_NV = $8854;
+ GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = $8855;
+ GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = $8856;
+ GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8857;
+ GL_DEPENDENT_HILO_TEXTURE_2D_NV = $8858;
+ GL_DEPENDENT_RGB_TEXTURE_3D_NV = $8859;
+ GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = $885A;
+ GL_DOT_PRODUCT_PASS_THROUGH_NV = $885B;
+ GL_DOT_PRODUCT_TEXTURE_1D_NV = $885C;
+ GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = $885D;
+ GL_HILO8_NV = $885E;
+ GL_SIGNED_HILO8_NV = $885F;
+ GL_FORCE_BLUE_TO_ONE_NV = $8860;
+
+function Load_GL_NV_texture_shader3: Boolean;
+
+//***** GL_NV_vertex_array_range *****//
+const
+ GL_VERTEX_ARRAY_RANGE_NV = $851D;
+ GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E;
+ GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F;
+ GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520;
+ GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521;
+var
+ glVertexArrayRangeNV: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFlushVertexArrayRangeNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+{$IFDEF WINDOWS}
+ wglAllocateMemoryNV: function(size: GLsizei; readFrequency: GLfloat; writeFrequency: GLfloat; priority: GLfloat): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglFreeMemoryNV: procedure(pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+{$ENDIF}
+
+function Load_GL_NV_vertex_array_range: Boolean;
+
+//***** GL_NV_vertex_array_range2 *****//
+const
+ GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = $8533;
+
+function Load_GL_NV_vertex_array_range2: Boolean;
+
+//***** GL_NV_vertex_program *****//
+const
+ GL_VERTEX_PROGRAM_NV = $8620;
+ GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642;
+ GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643;
+ GL_VERTEX_STATE_PROGRAM_NV = $8621;
+ GL_ATTRIB_ARRAY_SIZE_NV = $8623;
+ GL_ATTRIB_ARRAY_STRIDE_NV = $8624;
+ GL_ATTRIB_ARRAY_TYPE_NV = $8625;
+ GL_CURRENT_ATTRIB_NV = $8626;
+ GL_PROGRAM_PARAMETER_NV = $8644;
+ GL_ATTRIB_ARRAY_POINTER_NV = $8645;
+ GL_PROGRAM_TARGET_NV = $8646;
+ GL_PROGRAM_LENGTH_NV = $8627;
+ GL_PROGRAM_RESIDENT_NV = $8647;
+ GL_PROGRAM_STRING_NV = $8628;
+ GL_TRACK_MATRIX_NV = $8648;
+ GL_TRACK_MATRIX_TRANSFORM_NV = $8649;
+ GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E;
+ GL_MAX_TRACK_MATRICES_NV = $862F;
+ GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640;
+ GL_CURRENT_MATRIX_NV = $8641;
+ GL_VERTEX_PROGRAM_BINDING_NV = $864A;
+ GL_PROGRAM_ERROR_POSITION_NV = $864B;
+ GL_MODELVIEW_PROJECTION_NV = $8629;
+ GL_MATRIX0_NV = $8630;
+ GL_MATRIX1_NV = $8631;
+ GL_MATRIX2_NV = $8632;
+ GL_MATRIX3_NV = $8633;
+ GL_MATRIX4_NV = $8634;
+ GL_MATRIX5_NV = $8635;
+ GL_MATRIX6_NV = $8636;
+ GL_MATRIX7_NV = $8637;
+ GL_IDENTITY_NV = $862A;
+ GL_INVERSE_NV = $862B;
+ GL_TRANSPOSE_NV = $862C;
+ GL_INVERSE_TRANSPOSE_NV = $862D;
+ GL_VERTEX_ATTRIB_ARRAY0_NV = $8650;
+ GL_VERTEX_ATTRIB_ARRAY1_NV = $8651;
+ GL_VERTEX_ATTRIB_ARRAY2_NV = $8652;
+ GL_VERTEX_ATTRIB_ARRAY3_NV = $8653;
+ GL_VERTEX_ATTRIB_ARRAY4_NV = $8654;
+ GL_VERTEX_ATTRIB_ARRAY5_NV = $8655;
+ GL_VERTEX_ATTRIB_ARRAY6_NV = $8656;
+ GL_VERTEX_ATTRIB_ARRAY7_NV = $8657;
+ GL_VERTEX_ATTRIB_ARRAY8_NV = $8658;
+ GL_VERTEX_ATTRIB_ARRAY9_NV = $8659;
+ GL_VERTEX_ATTRIB_ARRAY10_NV = $865A;
+ GL_VERTEX_ATTRIB_ARRAY11_NV = $865B;
+ GL_VERTEX_ATTRIB_ARRAY12_NV = $865C;
+ GL_VERTEX_ATTRIB_ARRAY13_NV = $865D;
+ GL_VERTEX_ATTRIB_ARRAY14_NV = $865E;
+ GL_VERTEX_ATTRIB_ARRAY15_NV = $865F;
+ GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660;
+ GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661;
+ GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662;
+ GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663;
+ GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664;
+ GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665;
+ GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666;
+ GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667;
+ GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668;
+ GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669;
+ GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A;
+ GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B;
+ GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C;
+ GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D;
+ GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E;
+ GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F;
+ GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670;
+ GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671;
+ GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672;
+ GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673;
+ GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674;
+ GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675;
+ GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676;
+ GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677;
+ GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678;
+ GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679;
+ GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A;
+ GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B;
+ GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C;
+ GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D;
+ GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E;
+ GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F;
+var
+ glBindProgramNV: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteProgramsNV: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glExecuteProgramNV: procedure(target: GLenum; id: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAreProgramsResidentNV: function(n: GLsizei; const ids: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRequestResidentProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramParameterdvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramStringNV: procedure(id: GLuint; pname: GLenum; _program: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTrackMatrixivNV: procedure(target: GLenum; address: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribdvNV: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribfvNV: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribivNV: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribPointervNV: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsProgramNV: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadProgramNV: procedure(target: GLenum; id: GLuint; len: GLsizei; const _program: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramParameter4fNV: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramParameter4fvNV: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramParameters4dvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramParameters4fvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTrackMatrixNV: procedure(target: GLenum; address: GLuint; matrix: GLenum; transform: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribPointerNV: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1sNV: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1fNV: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1dNV: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2sNV: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4ubNV: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4svNV: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4fvNV: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4dvNV: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4ubvNV: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs1svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs1fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs1dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs2svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs2fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs2dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs3svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs3fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs3dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs4svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs4fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs4dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs4ubvNV: procedure(index: GLuint; n: GLsizei; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_vertex_program: Boolean;
+
+//***** GL_NV_vertex_program1_1 *****//
+
+function Load_GL_NV_vertex_program1_1: Boolean;
+
+//***** GL_ATI_element_array *****//
+const
+ GL_ELEMENT_ARRAY_ATI = $8768;
+ GL_ELEMENT_ARRAY_TYPE_ATI = $8769;
+ GL_ELEMENT_ARRAY_POINTER_ATI = $876A;
+var
+ glElementPointerATI: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawElementArrayATI: procedure(mode: GLenum; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawRangeElementArrayATI: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_element_array: Boolean;
+
+//***** GL_ATI_envmap_bumpmap *****//
+const
+ GL_BUMP_ROT_MATRIX_ATI = $8775;
+ GL_BUMP_ROT_MATRIX_SIZE_ATI = $8776;
+ GL_BUMP_NUM_TEX_UNITS_ATI = $8777;
+ GL_BUMP_TEX_UNITS_ATI = $8778;
+ GL_DUDV_ATI = $8779;
+ GL_DU8DV8_ATI = $877A;
+ GL_BUMP_ENVMAP_ATI = $877B;
+ GL_BUMP_TARGET_ATI = $877C;
+var
+ glTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_envmap_bumpmap: Boolean;
+
+//***** GL_ATI_fragment_shader *****//
+const
+ GL_FRAGMENT_SHADER_ATI = $8920;
+ GL_REG_0_ATI = $8921;
+ GL_REG_1_ATI = $8922;
+ GL_REG_2_ATI = $8923;
+ GL_REG_3_ATI = $8924;
+ GL_REG_4_ATI = $8925;
+ GL_REG_5_ATI = $8926;
+ GL_CON_0_ATI = $8941;
+ GL_CON_1_ATI = $8942;
+ GL_CON_2_ATI = $8943;
+ GL_CON_3_ATI = $8944;
+ GL_CON_4_ATI = $8945;
+ GL_CON_5_ATI = $8946;
+ GL_CON_6_ATI = $8947;
+ GL_CON_7_ATI = $8948;
+ GL_MOV_ATI = $8961;
+ GL_ADD_ATI = $8963;
+ GL_MUL_ATI = $8964;
+ GL_SUB_ATI = $8965;
+ GL_DOT3_ATI = $8966;
+ GL_DOT4_ATI = $8967;
+ GL_MAD_ATI = $8968;
+ GL_LERP_ATI = $8969;
+ GL_CND_ATI = $896A;
+ GL_CND0_ATI = $896B;
+ GL_DOT2_ADD_ATI = $896C;
+ GL_SECONDARY_INTERPOLATOR_ATI = $896D;
+ GL_SWIZZLE_STR_ATI = $8976;
+ GL_SWIZZLE_STQ_ATI = $8977;
+ GL_SWIZZLE_STR_DR_ATI = $8978;
+ GL_SWIZZLE_STQ_DQ_ATI = $8979;
+ GL_RED_BIT_ATI = $0001;
+ GL_GREEN_BIT_ATI = $0002;
+ GL_BLUE_BIT_ATI = $0004;
+ GL_2X_BIT_ATI = $0001;
+ GL_4X_BIT_ATI = $0002;
+ GL_8X_BIT_ATI = $0004;
+ GL_HALF_BIT_ATI = $0008;
+ GL_QUARTER_BIT_ATI = $0010;
+ GL_EIGHTH_BIT_ATI = $0020;
+ GL_SATURATE_BIT_ATI = $0040;
+ // GL_2X_BIT_ATI { already defined }
+ GL_COMP_BIT_ATI = $0002;
+ GL_NEGATE_BIT_ATI = $0004;
+ GL_BIAS_BIT_ATI = $0008;
+var
+ glGenFragmentShadersATI: function(range: GLuint): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindFragmentShaderATI: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteFragmentShaderATI: procedure(id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBeginFragmentShaderATI: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndFragmentShaderATI: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPassTexCoordATI: procedure(dst: GLuint; coord: GLuint; swizzle: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSampleMapATI: procedure(dst: GLuint; interp: GLuint; swizzle: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAlphaFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAlphaFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAlphaFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSetFragmentShaderConstantATI: procedure(dst: GLuint; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_fragment_shader: Boolean;
+
+//***** GL_ATI_pn_triangles *****//
+const
+ GL_PN_TRIANGLES_ATI = $87F0;
+ GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F1;
+ GL_PN_TRIANGLES_POINT_MODE_ATI = $87F2;
+ GL_PN_TRIANGLES_NORMAL_MODE_ATI = $87F3;
+ GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F4;
+ GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = $87F5;
+ GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = $87F6;
+ GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = $87F7;
+ GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = $87F8;
+var
+ glPNTrianglesiATI: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPNTrianglesfATI: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_pn_triangles: Boolean;
+
+//***** GL_ATI_texture_mirror_once *****//
+const
+ GL_MIRROR_CLAMP_ATI = $8742;
+ GL_MIRROR_CLAMP_TO_EDGE_ATI = $8743;
+
+function Load_GL_ATI_texture_mirror_once: Boolean;
+
+//***** GL_ATI_vertex_array_object *****//
+const
+ GL_STATIC_ATI = $8760;
+ GL_DYNAMIC_ATI = $8761;
+ GL_PRESERVE_ATI = $8762;
+ GL_DISCARD_ATI = $8763;
+ GL_OBJECT_BUFFER_SIZE_ATI = $8764;
+ GL_OBJECT_BUFFER_USAGE_ATI = $8765;
+ GL_ARRAY_OBJECT_BUFFER_ATI = $8766;
+ GL_ARRAY_OBJECT_OFFSET_ATI = $8767;
+var
+ glNewObjectBufferATI: function(size: GLsizei; const pointer: PGLvoid; usage: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsObjectBufferATI: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUpdateObjectBufferATI: procedure(buffer: GLuint; offset: GLuint; size: GLsizei; const pointer: PGLvoid; preserve: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetObjectBufferfvATI: procedure(buffer: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetObjectBufferivATI: procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteObjectBufferATI: procedure(buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glArrayObjectATI: procedure(_array: GLenum; size: GLint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetArrayObjectfvATI: procedure(_array: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetArrayObjectivATI: procedure(_array: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVariantArrayObjectATI: procedure(id: GLuint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantArrayObjectfvATI: procedure(id: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVariantArrayObjectivATI: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_vertex_array_object: Boolean;
+
+//***** GL_ATI_vertex_streams *****//
+const
+ GL_MAX_VERTEX_STREAMS_ATI = $876B;
+ GL_VERTEX_STREAM0_ATI = $876C;
+ GL_VERTEX_STREAM1_ATI = $876D;
+ GL_VERTEX_STREAM2_ATI = $876E;
+ GL_VERTEX_STREAM3_ATI = $876F;
+ GL_VERTEX_STREAM4_ATI = $8770;
+ GL_VERTEX_STREAM5_ATI = $8771;
+ GL_VERTEX_STREAM6_ATI = $8772;
+ GL_VERTEX_STREAM7_ATI = $8773;
+ GL_VERTEX_SOURCE_ATI = $8774;
+var
+ glVertexStream1s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream1dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream2dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream3dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexStream4dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3b: procedure(stream: GLenum; coords: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3s: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3i: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3f: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3d: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3bv: procedure(stream: GLenum; coords: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3sv: procedure(stream: GLenum; coords: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3iv: procedure(stream: GLenum; coords: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3fv: procedure(stream: GLenum; coords: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalStream3dv: procedure(stream: GLenum; coords: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClientActiveVertexStream: procedure(stream: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexBlendEnvi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexBlendEnvf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_vertex_streams: Boolean;
+
+{$IFDEF WINDOWS}
+//***** WGL_I3D_image_buffer *****//
+const
+ WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = $0001;
+ WGL_IMAGE_BUFFER_LOCK_I3D = $0002;
+var
+ wglCreateImageBufferI3D: function(hDC: HDC; dwSize: DWORD; uFlags: UINT): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDestroyImageBufferI3D: function(hDC: HDC; pAddress: PGLvoid): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglAssociateImageBufferEventsI3D: function(hdc: HDC; pEvent: PHandle; pAddress: PGLvoid; pSize: PDWORD; count: UINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglReleaseImageBufferEventsI3D: function(hdc: HDC; pAddress: PGLvoid; count: UINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_image_buffer: Boolean;
+
+//***** WGL_I3D_swap_frame_lock *****//
+var
+ wglEnableFrameLockI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDisableFrameLockI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglIsEnabledFrameLockI3D: function(pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglQueryFrameLockMasterI3D: function(pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_swap_frame_lock: Boolean;
+
+//***** WGL_I3D_swap_frame_usage *****//
+var
+ wglGetFrameUsageI3D: function(pUsage: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglBeginFrameTrackingI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglEndFrameTrackingI3D: function(): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglQueryFrameTrackingI3D: function(pFrameCount: PDWORD; pMissedFrames: PDWORD; pLastMissedUsage: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_swap_frame_usage: Boolean;
+{$ENDIF}
+
+//***** GL_3DFX_texture_compression_FXT1 *****//
+const
+ GL_COMPRESSED_RGB_FXT1_3DFX = $86B0;
+ GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1;
+
+function Load_GL_3DFX_texture_compression_FXT1: Boolean;
+
+//***** GL_IBM_cull_vertex *****//
+const
+ GL_CULL_VERTEX_IBM = $1928A;
+
+function Load_GL_IBM_cull_vertex: Boolean;
+
+//***** GL_IBM_multimode_draw_arrays *****//
+var
+ glMultiModeDrawArraysIBM: procedure(mode: PGLenum; first: PGLint; count: PGLsizei; primcount: GLsizei; modestride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiModeDrawElementsIBM: procedure(mode: PGLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; modestride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_IBM_multimode_draw_arrays: Boolean;
+
+//***** GL_IBM_raster_pos_clip *****//
+const
+ GL_RASTER_POSITION_UNCLIPPED_IBM = $19262;
+
+function Load_GL_IBM_raster_pos_clip: Boolean;
+
+//***** GL_IBM_texture_mirrored_repeat *****//
+const
+ GL_MIRRORED_REPEAT_IBM = $8370;
+
+function Load_GL_IBM_texture_mirrored_repeat: Boolean;
+
+//***** GL_IBM_vertex_array_lists *****//
+const
+ GL_VERTEX_ARRAY_LIST_IBM = $1929E;
+ GL_NORMAL_ARRAY_LIST_IBM = $1929F;
+ GL_COLOR_ARRAY_LIST_IBM = $192A0;
+ GL_INDEX_ARRAY_LIST_IBM = $192A1;
+ GL_TEXTURE_COORD_ARRAY_LIST_IBM = $192A2;
+ GL_EDGE_FLAG_ARRAY_LIST_IBM = $192A3;
+ GL_FOG_COORDINATE_ARRAY_LIST_IBM = $192A4;
+ GL_SECONDARY_COLOR_ARRAY_LIST_IBM = $192A5;
+ GL_VERTEX_ARRAY_LIST_STRIDE_IBM = $192A8;
+ GL_NORMAL_ARRAY_LIST_STRIDE_IBM = $192A9;
+ GL_COLOR_ARRAY_LIST_STRIDE_IBM = $192AA;
+ GL_INDEX_ARRAY_LIST_STRIDE_IBM = $192AB;
+ GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = $192AC;
+ GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = $192AD;
+ GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = $192AE;
+ GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = $192AF;
+var
+ glColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagPointerListIBM: procedure(stride: GLint; const pointer: PGLboolean; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoordPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_IBM_vertex_array_lists: Boolean;
+
+//***** GL_MESA_resize_buffers *****//
+var
+ glResizeBuffersMESA: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_MESA_resize_buffers: Boolean;
+
+//***** GL_MESA_window_pos *****//
+var
+ glWindowPos2dMESA: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2fMESA: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2iMESA: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2sMESA: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3iMESA: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3sMESA: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4iMESA: procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4sMESA: procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4ivMESA: procedure(const p: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4svMESA: procedure(const p: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4fvMESA: procedure(const p: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos4dvMESA: procedure(const p: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_MESA_window_pos: Boolean;
+
+//***** GL_OML_interlace *****//
+const
+ GL_INTERLACE_OML = $8980;
+ GL_INTERLACE_READ_OML = $8981;
+
+function Load_GL_OML_interlace: Boolean;
+
+//***** GL_OML_resample *****//
+const
+ GL_PACK_RESAMPLE_OML = $8984;
+ GL_UNPACK_RESAMPLE_OML = $8985;
+ GL_RESAMPLE_REPLICATE_OML = $8986;
+ GL_RESAMPLE_ZERO_FILL_OML = $8987;
+ GL_RESAMPLE_AVERAGE_OML = $8988;
+ GL_RESAMPLE_DECIMATE_OML = $8989;
+ // GL_RESAMPLE_AVERAGE_OML { already defined }
+
+function Load_GL_OML_resample: Boolean;
+
+//***** GL_OML_subsample *****//
+const
+ GL_FORMAT_SUBSAMPLE_24_24_OML = $8982;
+ GL_FORMAT_SUBSAMPLE_244_244_OML = $8983;
+
+function Load_GL_OML_subsample: Boolean;
+
+//***** GL_SGIS_generate_mipmap *****//
+const
+ GL_GENERATE_MIPMAP_SGIS = $8191;
+ GL_GENERATE_MIPMAP_HINT_SGIS = $8192;
+
+function Load_GL_SGIS_generate_mipmap: Boolean;
+
+//***** GL_SGIS_multisample *****//
+const
+ GLX_SAMPLE_BUFFERS_SGIS = $186A0;
+ GLX_SAMPLES_SGIS = $186A1;
+ GL_MULTISAMPLE_SGIS = $809D;
+ GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F;
+ GL_SAMPLE_MASK_SGIS = $80A0;
+ GL_MULTISAMPLE_BIT_EXT = $20000000;
+ GL_1PASS_SGIS = $80A1;
+ GL_2PASS_0_SGIS = $80A2;
+ GL_2PASS_1_SGIS = $80A3;
+ GL_4PASS_0_SGIS = $80A4;
+ GL_4PASS_1_SGIS = $80A5;
+ GL_4PASS_2_SGIS = $80A6;
+ GL_4PASS_3_SGIS = $80A7;
+ GL_SAMPLE_BUFFERS_SGIS = $80A8;
+ GL_SAMPLES_SGIS = $80A9;
+ GL_SAMPLE_MASK_VALUE_SGIS = $80AA;
+ GL_SAMPLE_MASK_INVERT_SGIS = $80AB;
+ GL_SAMPLE_PATTERN_SGIS = $80AC;
+var
+ glSampleMaskSGIS: procedure(value: GLclampf; invert: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSamplePatternSGIS: procedure(pattern: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_SGIS_multisample: Boolean;
+
+//***** GL_SGIS_pixel_texture *****//
+const
+ GL_PIXEL_TEXTURE_SGIS = $8353;
+ GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354;
+ GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355;
+ GL_PIXEL_GROUP_COLOR_SGIS = $8356;
+var
+ glPixelTexGenParameteriSGIS: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelTexGenParameterfSGIS: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelTexGenParameterivSGIS: procedure(pname: GLenum; params: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelTexGenParameterfvSGIS: procedure(pname: GLenum; params: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_SGIS_pixel_texture: Boolean;
+
+//***** GL_SGIS_texture_border_clamp *****//
+ // GL_CLAMP_TO_BORDER_SGIS { already defined }
+
+function Load_GL_SGIS_texture_border_clamp: Boolean;
+
+//***** GL_SGIS_texture_color_mask *****//
+const
+ GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF;
+var
+ glTextureColorMaskSGIS: procedure(r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_SGIS_texture_color_mask: Boolean;
+
+//***** GL_SGIS_texture_edge_clamp *****//
+const
+ GL_CLAMP_TO_EDGE_SGIS = $812F;
+
+function Load_GL_SGIS_texture_edge_clamp: Boolean;
+
+//***** GL_SGIS_texture_lod *****//
+const
+ GL_TEXTURE_MIN_LOD_SGIS = $813A;
+ GL_TEXTURE_MAX_LOD_SGIS = $813B;
+ GL_TEXTURE_BASE_LEVEL_SGIS = $813C;
+ GL_TEXTURE_MAX_LEVEL_SGIS = $813D;
+
+function Load_GL_SGIS_texture_lod: Boolean;
+
+//***** GL_SGIS_depth_texture *****//
+const
+ GL_DEPTH_COMPONENT16_SGIX = $81A5;
+ GL_DEPTH_COMPONENT24_SGIX = $81A6;
+ GL_DEPTH_COMPONENT32_SGIX = $81A7;
+
+function Load_GL_SGIS_depth_texture: Boolean;
+
+//***** GL_SGIX_fog_offset *****//
+const
+ GL_FOG_OFFSET_SGIX = $8198;
+ GL_FOG_OFFSET_VALUE_SGIX = $8199;
+
+function Load_GL_SGIX_fog_offset: Boolean;
+
+//***** GL_SGIX_interlace *****//
+const
+ GL_INTERLACE_SGIX = $8094;
+
+function Load_GL_SGIX_interlace: Boolean;
+
+//***** GL_SGIX_shadow_ambient *****//
+const
+ GL_SHADOW_AMBIENT_SGIX = $80BF;
+
+function Load_GL_SGIX_shadow_ambient: Boolean;
+
+//***** GL_SGI_color_matrix *****//
+const
+ GL_COLOR_MATRIX_SGI = $80B1;
+ GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2;
+ GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3;
+ GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4;
+ GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5;
+ GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6;
+ GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7;
+ GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8;
+ GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9;
+ GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA;
+ GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB;
+
+function Load_GL_SGI_color_matrix: Boolean;
+
+//***** GL_SGI_color_table *****//
+const
+ GL_COLOR_TABLE_SGI = $80D0;
+ GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1;
+ GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2;
+ GL_PROXY_COLOR_TABLE_SGI = $80D3;
+ GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4;
+ GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5;
+ GL_COLOR_TABLE_SCALE_SGI = $80D6;
+ GL_COLOR_TABLE_BIAS_SGI = $80D7;
+ GL_COLOR_TABLE_FORMAT_SGI = $80D8;
+ GL_COLOR_TABLE_WIDTH_SGI = $80D9;
+ GL_COLOR_TABLE_RED_SIZE_SGI = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF;
+var
+ glColorTableSGI: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyColorTableSGI: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableSGI: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_SGI_color_table: Boolean;
+
+//***** GL_SGI_texture_color_table *****//
+const
+ GL_TEXTURE_COLOR_TABLE_SGI = $80BC;
+ GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD;
+
+function Load_GL_SGI_texture_color_table: Boolean;
+
+//***** GL_SUN_vertex *****//
+var
+ glColor4ubVertex2fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ubVertex2fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ubVertex3fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4ubVertex3fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3fVertex3fvSUN: procedure(const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3fVertex3fSUN: procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3fVertex3fvSUN: procedure(const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4fNormal3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4fNormal3fVertex3fvSUN: procedure(const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fVertex3fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4fVertex4fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor4ubVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor4ubVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor4fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4fColor4fNormal3fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4fColor4fNormal3fVertex4fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiVertex3fSUN: procedure(rc: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiVertex3fvSUN: procedure(const rc: PGLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor4ubVertex3fSUN: procedure(rc: GLuint; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor4ubVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLubyte; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiNormal3fVertex3fSUN: procedure(rc: GLuint; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_SUN_vertex: Boolean;
+
+//***** GL_ARB_fragment_program *****//
+const
+ GL_FRAGMENT_PROGRAM_ARB = $8804;
+ // GL_PROGRAM_FORMAT_ASCII_ARB { already defined }
+ // GL_PROGRAM_LENGTH_ARB { already defined }
+ // GL_PROGRAM_FORMAT_ARB { already defined }
+ // GL_PROGRAM_BINDING_ARB { already defined }
+ // GL_PROGRAM_INSTRUCTIONS_ARB { already defined }
+ // GL_MAX_PROGRAM_INSTRUCTIONS_ARB { already defined }
+ // GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined }
+ // GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined }
+ // GL_PROGRAM_TEMPORARIES_ARB { already defined }
+ // GL_MAX_PROGRAM_TEMPORARIES_ARB { already defined }
+ // GL_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined }
+ // GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined }
+ // GL_PROGRAM_PARAMETERS_ARB { already defined }
+ // GL_MAX_PROGRAM_PARAMETERS_ARB { already defined }
+ // GL_PROGRAM_NATIVE_PARAMETERS_ARB { already defined }
+ // GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB { already defined }
+ // GL_PROGRAM_ATTRIBS_ARB { already defined }
+ // GL_MAX_PROGRAM_ATTRIBS_ARB { already defined }
+ // GL_PROGRAM_NATIVE_ATTRIBS_ARB { already defined }
+ // GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB { already defined }
+ // GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB { already defined }
+ // GL_MAX_PROGRAM_ENV_PARAMETERS_ARB { already defined }
+ // GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB { already defined }
+ GL_PROGRAM_ALU_INSTRUCTIONS_ARB = $8805;
+ GL_PROGRAM_TEX_INSTRUCTIONS_ARB = $8806;
+ GL_PROGRAM_TEX_INDIRECTIONS_ARB = $8807;
+ GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $8808;
+ GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $8809;
+ GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $880A;
+ GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = $880B;
+ GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = $880C;
+ GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = $880D;
+ GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $880E;
+ GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $880F;
+ GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $8810;
+ // GL_PROGRAM_STRING_ARB { already defined }
+ // GL_PROGRAM_ERROR_POSITION_ARB { already defined }
+ // GL_CURRENT_MATRIX_ARB { already defined }
+ // GL_TRANSPOSE_CURRENT_MATRIX_ARB { already defined }
+ // GL_CURRENT_MATRIX_STACK_DEPTH_ARB { already defined }
+ // GL_MAX_PROGRAM_MATRICES_ARB { already defined }
+ // GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB { already defined }
+ GL_MAX_TEXTURE_COORDS_ARB = $8871;
+ GL_MAX_TEXTURE_IMAGE_UNITS_ARB = $8872;
+ // GL_PROGRAM_ERROR_STRING_ARB { already defined }
+ // GL_MATRIX0_ARB { already defined }
+ // GL_MATRIX1_ARB { already defined }
+ // GL_MATRIX2_ARB { already defined }
+ // GL_MATRIX3_ARB { already defined }
+ // GL_MATRIX4_ARB { already defined }
+ // GL_MATRIX5_ARB { already defined }
+ // GL_MATRIX6_ARB { already defined }
+ // GL_MATRIX7_ARB { already defined }
+ // GL_MATRIX8_ARB { already defined }
+ // GL_MATRIX9_ARB { already defined }
+ // GL_MATRIX10_ARB { already defined }
+ // GL_MATRIX11_ARB { already defined }
+ // GL_MATRIX12_ARB { already defined }
+ // GL_MATRIX13_ARB { already defined }
+ // GL_MATRIX14_ARB { already defined }
+ // GL_MATRIX15_ARB { already defined }
+ // GL_MATRIX16_ARB { already defined }
+ // GL_MATRIX17_ARB { already defined }
+ // GL_MATRIX18_ARB { already defined }
+ // GL_MATRIX19_ARB { already defined }
+ // GL_MATRIX20_ARB { already defined }
+ // GL_MATRIX21_ARB { already defined }
+ // GL_MATRIX22_ARB { already defined }
+ // GL_MATRIX23_ARB { already defined }
+ // GL_MATRIX24_ARB { already defined }
+ // GL_MATRIX25_ARB { already defined }
+ // GL_MATRIX26_ARB { already defined }
+ // GL_MATRIX27_ARB { already defined }
+ // GL_MATRIX28_ARB { already defined }
+ // GL_MATRIX29_ARB { already defined }
+ // GL_MATRIX30_ARB { already defined }
+ // GL_MATRIX31_ARB { already defined }
+ // glProgramStringARB { already defined }
+ // glBindProgramARB { already defined }
+ // glDeleteProgramsARB { already defined }
+ // glGenProgramsARB { already defined }
+ // glProgramEnvParameter4dARB { already defined }
+ // glProgramEnvParameter4dvARB { already defined }
+ // glProgramEnvParameter4fARB { already defined }
+ // glProgramEnvParameter4fvARB { already defined }
+ // glProgramLocalParameter4dARB { already defined }
+ // glProgramLocalParameter4dvARB { already defined }
+ // glProgramLocalParameter4fARB { already defined }
+ // glProgramLocalParameter4fvARB { already defined }
+ // glGetProgramEnvParameterdvARB { already defined }
+ // glGetProgramEnvParameterfvARB { already defined }
+ // glGetProgramLocalParameterdvARB { already defined }
+ // glGetProgramLocalParameterfvARB { already defined }
+ // glGetProgramivARB { already defined }
+ // glGetProgramStringARB { already defined }
+ // glIsProgramARB { already defined }
+
+function Load_GL_ARB_fragment_program: Boolean;
+
+//***** GL_ATI_text_fragment_shader *****//
+const
+ GL_TEXT_FRAGMENT_SHADER_ATI = $8200;
+
+function Load_GL_ATI_text_fragment_shader: Boolean;
+
+//***** GL_APPLE_client_storage *****//
+const
+ GL_UNPACK_CLIENT_STORAGE_APPLE = $85B2;
+
+function Load_GL_APPLE_client_storage: Boolean;
+
+//***** GL_APPLE_element_array *****//
+const
+ GL_ELEMENT_ARRAY_APPLE = $8768;
+ GL_ELEMENT_ARRAY_TYPE_APPLE = $8769;
+ GL_ELEMENT_ARRAY_POINTER_APPLE = $876A;
+var
+ glElementPointerAPPLE: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawElementArrayAPPLE: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawElementArrayAPPLE: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_APPLE_element_array: Boolean;
+
+//***** GL_APPLE_fence *****//
+const
+ GL_DRAW_PIXELS_APPLE = $8A0A;
+ GL_FENCE_APPLE = $8A0B;
+var
+ glGenFencesAPPLE: procedure(n: GLsizei; fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteFencesAPPLE: procedure(n: GLsizei; const fences: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSetFenceAPPLE: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsFenceAPPLE: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTestFenceAPPLE: function(fence: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFinishFenceAPPLE: procedure(fence: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTestObjectAPPLE: function(_object: GLenum; name: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFinishObjectAPPLE: procedure(_object: GLenum; name: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_APPLE_fence: Boolean;
+
+//***** GL_APPLE_vertex_array_object *****//
+const
+ GL_VERTEX_ARRAY_BINDING_APPLE = $85B5;
+var
+ glBindVertexArrayAPPLE: procedure(_array: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsVertexArrayAPPLE: function(_array: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_APPLE_vertex_array_object: Boolean;
+
+//***** GL_APPLE_vertex_array_range *****//
+const
+ GL_VERTEX_ARRAY_RANGE_APPLE = $851D;
+ GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = $851E;
+ GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE = $8520;
+ GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = $8521;
+ GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = $851F;
+ GL_STORAGE_CACHED_APPLE = $85BE;
+ GL_STORAGE_SHARED_APPLE = $85BF;
+var
+ glVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFlushVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexArrayParameteriAPPLE: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_APPLE_vertex_array_range: Boolean;
+
+{$IFDEF WINDOWS}
+//***** WGL_ARB_pixel_format *****//
+const
+ WGL_NUMBER_PIXEL_FORMATS_ARB = $2000;
+ WGL_DRAW_TO_WINDOW_ARB = $2001;
+ WGL_DRAW_TO_BITMAP_ARB = $2002;
+ WGL_ACCELERATION_ARB = $2003;
+ WGL_NEED_PALETTE_ARB = $2004;
+ WGL_NEED_SYSTEM_PALETTE_ARB = $2005;
+ WGL_SWAP_LAYER_BUFFERS_ARB = $2006;
+ WGL_SWAP_METHOD_ARB = $2007;
+ WGL_NUMBER_OVERLAYS_ARB = $2008;
+ WGL_NUMBER_UNDERLAYS_ARB = $2009;
+ WGL_TRANSPARENT_ARB = $200A;
+ WGL_TRANSPARENT_RED_VALUE_ARB = $2037;
+ WGL_TRANSPARENT_GREEN_VALUE_ARB = $2038;
+ WGL_TRANSPARENT_BLUE_VALUE_ARB = $2039;
+ WGL_TRANSPARENT_ALPHA_VALUE_ARB = $203A;
+ WGL_TRANSPARENT_INDEX_VALUE_ARB = $203B;
+ WGL_SHARE_DEPTH_ARB = $200C;
+ WGL_SHARE_STENCIL_ARB = $200D;
+ WGL_SHARE_ACCUM_ARB = $200E;
+ WGL_SUPPORT_GDI_ARB = $200F;
+ WGL_SUPPORT_OPENGL_ARB = $2010;
+ WGL_DOUBLE_BUFFER_ARB = $2011;
+ WGL_STEREO_ARB = $2012;
+ WGL_PIXEL_TYPE_ARB = $2013;
+ WGL_COLOR_BITS_ARB = $2014;
+ WGL_RED_BITS_ARB = $2015;
+ WGL_RED_SHIFT_ARB = $2016;
+ WGL_GREEN_BITS_ARB = $2017;
+ WGL_GREEN_SHIFT_ARB = $2018;
+ WGL_BLUE_BITS_ARB = $2019;
+ WGL_BLUE_SHIFT_ARB = $201A;
+ WGL_ALPHA_BITS_ARB = $201B;
+ WGL_ALPHA_SHIFT_ARB = $201C;
+ WGL_ACCUM_BITS_ARB = $201D;
+ WGL_ACCUM_RED_BITS_ARB = $201E;
+ WGL_ACCUM_GREEN_BITS_ARB = $201F;
+ WGL_ACCUM_BLUE_BITS_ARB = $2020;
+ WGL_ACCUM_ALPHA_BITS_ARB = $2021;
+ WGL_DEPTH_BITS_ARB = $2022;
+ WGL_STENCIL_BITS_ARB = $2023;
+ WGL_AUX_BUFFERS_ARB = $2024;
+ WGL_NO_ACCELERATION_ARB = $2025;
+ WGL_GENERIC_ACCELERATION_ARB = $2026;
+ WGL_FULL_ACCELERATION_ARB = $2027;
+ WGL_SWAP_EXCHANGE_ARB = $2028;
+ WGL_SWAP_COPY_ARB = $2029;
+ WGL_SWAP_UNDEFINED_ARB = $202A;
+ WGL_TYPE_RGBA_ARB = $202B;
+ WGL_TYPE_COLORINDEX_ARB = $202C;
+var
+ wglGetPixelFormatAttribivARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetPixelFormatAttribfvARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglChoosePixelFormatARB: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_pixel_format: Boolean;
+
+//***** WGL_ARB_make_current_read *****//
+const
+ WGL_ERROR_INVALID_PIXEL_TYPE_ARB = $2043;
+ WGL_ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = $2054;
+var
+ wglMakeContextCurrentARB: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetCurrentReadDCARB: function(): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_make_current_read: Boolean;
+
+//***** WGL_ARB_pbuffer *****//
+const
+ WGL_DRAW_TO_PBUFFER_ARB = $202D;
+ // WGL_DRAW_TO_PBUFFER_ARB { already defined }
+ WGL_MAX_PBUFFER_PIXELS_ARB = $202E;
+ WGL_MAX_PBUFFER_WIDTH_ARB = $202F;
+ WGL_MAX_PBUFFER_HEIGHT_ARB = $2030;
+ WGL_PBUFFER_LARGEST_ARB = $2033;
+ WGL_PBUFFER_WIDTH_ARB = $2034;
+ WGL_PBUFFER_HEIGHT_ARB = $2035;
+ WGL_PBUFFER_LOST_ARB = $2036;
+var
+ wglCreatePbufferARB: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetPbufferDCARB: function(hPbuffer: THandle): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglReleasePbufferDCARB: function(hPbuffer: THandle; hDC: HDC): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDestroyPbufferARB: function(hPbuffer: THandle): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglQueryPbufferARB: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_pbuffer: Boolean;
+
+//***** WGL_EXT_swap_control *****//
+var
+ wglSwapIntervalEXT: function(interval: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetSwapIntervalEXT: function(): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_EXT_swap_control: Boolean;
+
+//***** WGL_ARB_render_texture *****//
+const
+ WGL_BIND_TO_TEXTURE_RGB_ARB = $2070;
+ WGL_BIND_TO_TEXTURE_RGBA_ARB = $2071;
+ WGL_TEXTURE_FORMAT_ARB = $2072;
+ WGL_TEXTURE_TARGET_ARB = $2073;
+ WGL_MIPMAP_TEXTURE_ARB = $2074;
+ WGL_TEXTURE_RGB_ARB = $2075;
+ WGL_TEXTURE_RGBA_ARB = $2076;
+ WGL_NO_TEXTURE_ARB = $2077;
+ WGL_TEXTURE_CUBE_MAP_ARB = $2078;
+ WGL_TEXTURE_1D_ARB = $2079;
+ WGL_TEXTURE_2D_ARB = $207A;
+ // WGL_NO_TEXTURE_ARB { already defined }
+ WGL_MIPMAP_LEVEL_ARB = $207B;
+ WGL_CUBE_MAP_FACE_ARB = $207C;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $207D;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $207E;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $207F;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $2080;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $2081;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $2082;
+ WGL_FRONT_LEFT_ARB = $2083;
+ WGL_FRONT_RIGHT_ARB = $2084;
+ WGL_BACK_LEFT_ARB = $2085;
+ WGL_BACK_RIGHT_ARB = $2086;
+ WGL_AUX0_ARB = $2087;
+ WGL_AUX1_ARB = $2088;
+ WGL_AUX2_ARB = $2089;
+ WGL_AUX3_ARB = $208A;
+ WGL_AUX4_ARB = $208B;
+ WGL_AUX5_ARB = $208C;
+ WGL_AUX6_ARB = $208D;
+ WGL_AUX7_ARB = $208E;
+ WGL_AUX8_ARB = $208F;
+ WGL_AUX9_ARB = $2090;
+var
+ wglBindTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglReleaseTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglSetPbufferAttribARB: function(hPbuffer: THandle; const piAttribList: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_ARB_render_texture: Boolean;
+
+//***** WGL_EXT_extensions_string *****//
+var
+ wglGetExtensionsStringEXT: function(): Pchar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_EXT_extensions_string: Boolean;
+
+//***** WGL_EXT_make_current_read *****//
+var
+ wglMakeContextCurrentEXT: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetCurrentReadDCEXT: function(): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_EXT_make_current_read: Boolean;
+
+//***** WGL_EXT_pbuffer *****//
+const
+ WGL_DRAW_TO_PBUFFER_EXT = $202D;
+ WGL_MAX_PBUFFER_PIXELS_EXT = $202E;
+ WGL_MAX_PBUFFER_WIDTH_EXT = $202F;
+ WGL_MAX_PBUFFER_HEIGHT_EXT = $2030;
+ WGL_OPTIMAL_PBUFFER_WIDTH_EXT = $2031;
+ WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = $2032;
+ WGL_PBUFFER_LARGEST_EXT = $2033;
+ WGL_PBUFFER_WIDTH_EXT = $2034;
+ WGL_PBUFFER_HEIGHT_EXT = $2035;
+var
+ wglCreatePbufferEXT: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetPbufferDCEXT: function(hPbuffer: THandle): HDC; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglReleasePbufferDCEXT: function(hPbuffer: THandle; hDC: HDC): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDestroyPbufferEXT: function(hPbuffer: THandle): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglQueryPbufferEXT: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_EXT_pbuffer: Boolean;
+
+//***** WGL_EXT_pixel_format *****//
+const
+ WGL_NUMBER_PIXEL_FORMATS_EXT = $2000;
+ WGL_DRAW_TO_WINDOW_EXT = $2001;
+ WGL_DRAW_TO_BITMAP_EXT = $2002;
+ WGL_ACCELERATION_EXT = $2003;
+ WGL_NEED_PALETTE_EXT = $2004;
+ WGL_NEED_SYSTEM_PALETTE_EXT = $2005;
+ WGL_SWAP_LAYER_BUFFERS_EXT = $2006;
+ WGL_SWAP_METHOD_EXT = $2007;
+ WGL_NUMBER_OVERLAYS_EXT = $2008;
+ WGL_NUMBER_UNDERLAYS_EXT = $2009;
+ WGL_TRANSPARENT_EXT = $200A;
+ WGL_TRANSPARENT_VALUE_EXT = $200B;
+ WGL_SHARE_DEPTH_EXT = $200C;
+ WGL_SHARE_STENCIL_EXT = $200D;
+ WGL_SHARE_ACCUM_EXT = $200E;
+ WGL_SUPPORT_GDI_EXT = $200F;
+ WGL_SUPPORT_OPENGL_EXT = $2010;
+ WGL_DOUBLE_BUFFER_EXT = $2011;
+ WGL_STEREO_EXT = $2012;
+ WGL_PIXEL_TYPE_EXT = $2013;
+ WGL_COLOR_BITS_EXT = $2014;
+ WGL_RED_BITS_EXT = $2015;
+ WGL_RED_SHIFT_EXT = $2016;
+ WGL_GREEN_BITS_EXT = $2017;
+ WGL_GREEN_SHIFT_EXT = $2018;
+ WGL_BLUE_BITS_EXT = $2019;
+ WGL_BLUE_SHIFT_EXT = $201A;
+ WGL_ALPHA_BITS_EXT = $201B;
+ WGL_ALPHA_SHIFT_EXT = $201C;
+ WGL_ACCUM_BITS_EXT = $201D;
+ WGL_ACCUM_RED_BITS_EXT = $201E;
+ WGL_ACCUM_GREEN_BITS_EXT = $201F;
+ WGL_ACCUM_BLUE_BITS_EXT = $2020;
+ WGL_ACCUM_ALPHA_BITS_EXT = $2021;
+ WGL_DEPTH_BITS_EXT = $2022;
+ WGL_STENCIL_BITS_EXT = $2023;
+ WGL_AUX_BUFFERS_EXT = $2024;
+ WGL_NO_ACCELERATION_EXT = $2025;
+ WGL_GENERIC_ACCELERATION_EXT = $2026;
+ WGL_FULL_ACCELERATION_EXT = $2027;
+ WGL_SWAP_EXCHANGE_EXT = $2028;
+ WGL_SWAP_COPY_EXT = $2029;
+ WGL_SWAP_UNDEFINED_EXT = $202A;
+ WGL_TYPE_RGBA_EXT = $202B;
+ WGL_TYPE_COLORINDEX_EXT = $202C;
+var
+ wglGetPixelFormatAttribivEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; piValues: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetPixelFormatAttribfvEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglChoosePixelFormatEXT: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_EXT_pixel_format: Boolean;
+
+//***** WGL_I3D_digital_video_control *****//
+const
+ WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = $2050;
+ WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = $2051;
+ WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = $2052;
+ WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = $2053;
+var
+ wglGetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglSetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_digital_video_control: Boolean;
+
+//***** WGL_I3D_gamma *****//
+const
+ WGL_GAMMA_TABLE_SIZE_I3D = $204E;
+ WGL_GAMMA_EXCLUDE_DESKTOP_I3D = $204F;
+ // WGL_GAMMA_EXCLUDE_DESKTOP_I3D { already defined }
+var
+ wglGetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglSetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetGammaTableI3D: function(hDC: HDC; iEntries: GLint; puRed: PGLUSHORT; puGreen: PGLUSHORT; puBlue: PGLUSHORT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglSetGammaTableI3D: function(hDC: HDC; iEntries: GLint; const puRed: PGLUSHORT; const puGreen: PGLUSHORT; const puBlue: PGLUSHORT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_gamma: Boolean;
+
+//***** WGL_I3D_genlock *****//
+const
+ WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = $2044;
+ WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = $2045;
+ WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = $2046;
+ WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = $2047;
+ WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = $2048;
+ WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = $2049;
+ WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = $204A;
+ WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = $204B;
+ WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = $204C;
+var
+ wglEnableGenlockI3D: function(hDC: HDC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglDisableGenlockI3D: function(hDC: HDC): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglIsEnabledGenlockI3D: function(hDC: HDC; pFlag: PBOOL): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGenlockSourceI3D: function(hDC: HDC; uSource: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetGenlockSourceI3D: function(hDC: HDC; uSource: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGenlockSampleRateI3D: function(hDC: HDC; uRate: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetGenlockSampleRateI3D: function(hDC: HDC; uRate: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGenlockSourceDelayI3D: function(hDC: HDC; uDelay: GLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglGetGenlockSourceDelayI3D: function(hDC: HDC; uDelay: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ wglQueryGenlockMaxSourceDelayI3D: function(hDC: HDC; uMaxLineDelay: PGLUINT; uMaxPixelDelay: PGLUINT): BOOL; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_WGL_I3D_genlock: Boolean;
+{$ENDIF}
+
+//***** GL_ARB_matrix_palette *****//
+const
+ GL_MATRIX_PALETTE_ARB = $8840;
+ GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = $8841;
+ GL_MAX_PALETTE_MATRICES_ARB = $8842;
+ GL_CURRENT_PALETTE_MATRIX_ARB = $8843;
+ GL_MATRIX_INDEX_ARRAY_ARB = $8844;
+ GL_CURRENT_MATRIX_INDEX_ARB = $8845;
+ GL_MATRIX_INDEX_ARRAY_SIZE_ARB = $8846;
+ GL_MATRIX_INDEX_ARRAY_TYPE_ARB = $8847;
+ GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = $8848;
+ GL_MATRIX_INDEX_ARRAY_POINTER_ARB = $8849;
+var
+ glCurrentPaletteMatrixARB: procedure(index: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMatrixIndexubvARB: procedure(size: GLint; indices: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMatrixIndexusvARB: procedure(size: GLint; indices: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMatrixIndexuivARB: procedure(size: GLint; indices: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMatrixIndexPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_matrix_palette: Boolean;
+
+//***** GL_NV_element_array *****//
+const
+ GL_ELEMENT_ARRAY_TYPE_NV = $8769;
+ GL_ELEMENT_ARRAY_POINTER_NV = $876A;
+var
+ glElementPointerNV: procedure(_type: GLenum; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawElementArrayNV: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawElementArrayNV: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_element_array: Boolean;
+
+//***** GL_NV_float_buffer *****//
+const
+ GL_FLOAT_R_NV = $8880;
+ GL_FLOAT_RG_NV = $8881;
+ GL_FLOAT_RGB_NV = $8882;
+ GL_FLOAT_RGBA_NV = $8883;
+ GL_FLOAT_R16_NV = $8884;
+ GL_FLOAT_R32_NV = $8885;
+ GL_FLOAT_RG16_NV = $8886;
+ GL_FLOAT_RG32_NV = $8887;
+ GL_FLOAT_RGB16_NV = $8888;
+ GL_FLOAT_RGB32_NV = $8889;
+ GL_FLOAT_RGBA16_NV = $888A;
+ GL_FLOAT_RGBA32_NV = $888B;
+ GL_TEXTURE_FLOAT_COMPONENTS_NV = $888C;
+ GL_FLOAT_CLEAR_COLOR_VALUE_NV = $888D;
+ GL_FLOAT_RGBA_MODE_NV = $888E;
+{$IFDEF WINDOWS}
+ WGL_FLOAT_COMPONENTS_NV = $20B0;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = $20B1;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = $20B2;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = $20B3;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = $20B4;
+ WGL_TEXTURE_FLOAT_R_NV = $20B5;
+ WGL_TEXTURE_FLOAT_RG_NV = $20B6;
+ WGL_TEXTURE_FLOAT_RGB_NV = $20B7;
+ WGL_TEXTURE_FLOAT_RGBA_NV = $20B8;
+{$ENDIF}
+
+function Load_GL_NV_float_buffer: Boolean;
+
+//***** GL_NV_fragment_program *****//
+const
+ GL_FRAGMENT_PROGRAM_NV = $8870;
+ GL_MAX_TEXTURE_COORDS_NV = $8871;
+ GL_MAX_TEXTURE_IMAGE_UNITS_NV = $8872;
+ GL_FRAGMENT_PROGRAM_BINDING_NV = $8873;
+ GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = $8868;
+ GL_PROGRAM_ERROR_STRING_NV = $8874;
+var
+ glProgramNamedParameter4fNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glProgramNamedParameter4dNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramNamedParameterfvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramNamedParameterdvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ // glProgramLocalParameter4dARB { already defined }
+ // glProgramLocalParameter4dvARB { already defined }
+ // glProgramLocalParameter4fARB { already defined }
+ // glProgramLocalParameter4fvARB { already defined }
+ // glGetProgramLocalParameterdvARB { already defined }
+ // glGetProgramLocalParameterfvARB { already defined }
+
+function Load_GL_NV_fragment_program: Boolean;
+
+//***** GL_NV_primitive_restart *****//
+const
+ GL_PRIMITIVE_RESTART_NV = $8558;
+ GL_PRIMITIVE_RESTART_INDEX_NV = $8559;
+var
+ glPrimitiveRestartNV: procedure(); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPrimitiveRestartIndexNV: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_primitive_restart: Boolean;
+
+//***** GL_NV_vertex_program2 *****//
+
+function Load_GL_NV_vertex_program2: Boolean;
+
+{$IFDEF WINDOWS}
+//***** WGL_NV_render_texture_rectangle *****//
+const
+ WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = $20A0;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = $20A1;
+ WGL_TEXTURE_RECTANGLE_NV = $20A2;
+
+function Load_WGL_NV_render_texture_rectangle: Boolean;
+{$ENDIF}
+
+//***** GL_NV_pixel_data_range *****//
+const
+ GL_WRITE_PIXEL_DATA_RANGE_NV = $8878;
+ GL_READ_PIXEL_DATA_RANGE_NV = $8879;
+ GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = $887A;
+ GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = $887B;
+ GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = $887C;
+ GL_READ_PIXEL_DATA_RANGE_POINTER_NV = $887D;
+var
+ glPixelDataRangeNV: procedure(target: GLenum; length: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFlushPixelDataRangeNV: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ // wglAllocateMemoryNV { already defined }
+ // wglFreeMemoryNV { already defined }
+
+function Load_GL_NV_pixel_data_range: Boolean;
+
+//***** GL_EXT_texture_rectangle *****//
+const
+ GL_TEXTURE_RECTANGLE_EXT = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_EXT = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_EXT = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = $84F8;
+
+function Load_GL_EXT_texture_rectangle: Boolean;
+
+//***** GL_S3_s3tc *****//
+const
+ GL_RGB_S3TC = $83A0;
+ GL_RGB4_S3TC = $83A1;
+ GL_RGBA_S3TC = $83A2;
+ GL_RGBA4_S3TC = $83A3;
+
+function Load_GL_S3_s3tc: Boolean;
+
+//***** GL_ATI_draw_buffers *****//
+const
+ GL_MAX_DRAW_BUFFERS_ATI = $8824;
+ GL_DRAW_BUFFER0_ATI = $8825;
+ GL_DRAW_BUFFER1_ATI = $8826;
+ GL_DRAW_BUFFER2_ATI = $8827;
+ GL_DRAW_BUFFER3_ATI = $8828;
+ GL_DRAW_BUFFER4_ATI = $8829;
+ GL_DRAW_BUFFER5_ATI = $882A;
+ GL_DRAW_BUFFER6_ATI = $882B;
+ GL_DRAW_BUFFER7_ATI = $882C;
+ GL_DRAW_BUFFER8_ATI = $882D;
+ GL_DRAW_BUFFER9_ATI = $882E;
+ GL_DRAW_BUFFER10_ATI = $882F;
+ GL_DRAW_BUFFER11_ATI = $8830;
+ GL_DRAW_BUFFER12_ATI = $8831;
+ GL_DRAW_BUFFER13_ATI = $8832;
+ GL_DRAW_BUFFER14_ATI = $8833;
+ GL_DRAW_BUFFER15_ATI = $8834;
+var
+ glDrawBuffersATI: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_draw_buffers: Boolean;
+
+{$IFDEF WINDOWS}
+//***** WGL_ATI_pixel_format_float *****//
+const
+ WGL_RGBA_FLOAT_MODE_ATI = $8820;
+ WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = $8835;
+ WGL_TYPE_RGBA_FLOAT_ATI = $21A0;
+
+function Load_WGL_ATI_pixel_format_float: Boolean;
+{$ENDIF}
+
+//***** GL_ATI_texture_env_combine3 *****//
+const
+ GL_MODULATE_ADD_ATI = $8744;
+ GL_MODULATE_SIGNED_ADD_ATI = $8745;
+ GL_MODULATE_SUBTRACT_ATI = $8746;
+
+function Load_GL_ATI_texture_env_combine3: Boolean;
+
+//***** GL_ATI_texture_float *****//
+const
+ GL_RGBA_FLOAT32_ATI = $8814;
+ GL_RGB_FLOAT32_ATI = $8815;
+ GL_ALPHA_FLOAT32_ATI = $8816;
+ GL_INTENSITY_FLOAT32_ATI = $8817;
+ GL_LUMINANCE_FLOAT32_ATI = $8818;
+ GL_LUMINANCE_ALPHA_FLOAT32_ATI = $8819;
+ GL_RGBA_FLOAT16_ATI = $881A;
+ GL_RGB_FLOAT16_ATI = $881B;
+ GL_ALPHA_FLOAT16_ATI = $881C;
+ GL_INTENSITY_FLOAT16_ATI = $881D;
+ GL_LUMINANCE_FLOAT16_ATI = $881E;
+ GL_LUMINANCE_ALPHA_FLOAT16_ATI = $881F;
+
+function Load_GL_ATI_texture_float: Boolean;
+
+//***** GL_NV_texture_expand_normal *****//
+const
+ GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = $888F;
+
+function Load_GL_NV_texture_expand_normal: Boolean;
+
+//***** GL_NV_half_float *****//
+const
+ GL_HALF_FLOAT_NV = $140B;
+var
+ glVertex2hNV: procedure(x: GLushort; y: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex2hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3hNV: procedure(x: GLushort; y: GLushort; z: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4hNV: procedure(x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertex4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3hNV: procedure(nx: GLushort; ny: GLushort; nz: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4hNV: procedure(red: GLushort; green: GLushort; blue: GLushort; alpha: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColor4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1hNV: procedure(s: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord1hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2hNV: procedure(s: GLushort; t: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord2hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3hNV: procedure(s: GLushort; t: GLushort; r: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4hNV: procedure(s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexCoord4hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1hNV: procedure(target: GLenum; s: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord1hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2hNV: procedure(target: GLenum; s: GLushort; t: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord2hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord3hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiTexCoord4hvNV: procedure(target: GLenum; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordhNV: procedure(fog: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordhvNV: procedure(const fog: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3hvNV: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexWeighthNV: procedure(weight: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexWeighthvNV: procedure(const weight: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1hNV: procedure(index: GLuint; x: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2hNV: procedure(index: GLuint; x: GLushort; y: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4hvNV: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs1hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs2hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs3hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribs4hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_NV_half_float: Boolean;
+
+//***** GL_ATI_map_object_buffer *****//
+var
+ glMapObjectBufferATI: function(buffer: GLuint): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUnmapObjectBufferATI: procedure(buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_map_object_buffer: Boolean;
+
+//***** GL_ATI_separate_stencil *****//
+const
+ GL_KEEP = $1E00;
+ GL_ZERO = $0000;
+ GL_REPLACE = $1E01;
+ GL_INCR = $1E02;
+ GL_DECR = $1E03;
+ GL_INVERT = $150A;
+ GL_NEVER = $0200;
+ GL_LESS = $0201;
+ GL_LEQUAL = $0203;
+ GL_GREATER = $0204;
+ GL_GEQUAL = $0206;
+ GL_EQUAL = $0202;
+ GL_NOTEQUAL = $0205;
+ GL_ALWAYS = $0207;
+ GL_FRONT = $0404;
+ GL_BACK = $0405;
+ GL_FRONT_AND_BACK = $0408;
+ GL_STENCIL_BACK_FUNC_ATI = $8800;
+ GL_STENCIL_BACK_FAIL_ATI = $8801;
+ GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = $8802;
+ GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = $8803;
+var
+ glStencilOpSeparateATI: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilFuncSeparateATI: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_separate_stencil: Boolean;
+
+//***** GL_ATI_vertex_attrib_array_object *****//
+var
+ glVertexAttribArrayObjectATI: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribArrayObjectfvATI: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribArrayObjectivATI: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ATI_vertex_attrib_array_object: Boolean;
+
+//***** GL_ARB_vertex_buffer_object *****//
+const
+ GL_ARRAY_BUFFER_ARB = $8892;
+ GL_ELEMENT_ARRAY_BUFFER_ARB = $8893;
+ GL_ARRAY_BUFFER_BINDING_ARB = $8894;
+ GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = $8895;
+ GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = $8896;
+ GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = $8897;
+ GL_COLOR_ARRAY_BUFFER_BINDING_ARB = $8898;
+ GL_INDEX_ARRAY_BUFFER_BINDING_ARB = $8899;
+ GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = $889A;
+ GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = $889B;
+ GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = $889C;
+ GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = $889D;
+ GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = $889E;
+ GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = $889F;
+ GL_STREAM_DRAW_ARB = $88E0;
+ GL_STREAM_READ_ARB = $88E1;
+ GL_STREAM_COPY_ARB = $88E2;
+ GL_STATIC_DRAW_ARB = $88E4;
+ GL_STATIC_READ_ARB = $88E5;
+ GL_STATIC_COPY_ARB = $88E6;
+ GL_DYNAMIC_DRAW_ARB = $88E8;
+ GL_DYNAMIC_READ_ARB = $88E9;
+ GL_DYNAMIC_COPY_ARB = $88EA;
+ GL_READ_ONLY_ARB = $88B8;
+ GL_WRITE_ONLY_ARB = $88B9;
+ GL_READ_WRITE_ARB = $88BA;
+ GL_BUFFER_SIZE_ARB = $8764;
+ GL_BUFFER_USAGE_ARB = $8765;
+ GL_BUFFER_ACCESS_ARB = $88BB;
+ GL_BUFFER_MAPPED_ARB = $88BC;
+ GL_BUFFER_MAP_POINTER_ARB = $88BD;
+var
+ glBindBufferARB: procedure(target: GLenum; buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteBuffersARB: procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenBuffersARB: procedure(n: GLsizei; buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsBufferARB: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBufferDataARB: procedure(target: GLenum; size: GLsizeiptrARB; const data: PGLvoid; usage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBufferSubDataARB: procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferSubDataARB: procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapBufferARB: function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUnmapBufferARB: function(target: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferParameterivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferPointervARB: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_vertex_buffer_object: Boolean;
+
+//***** GL_ARB_occlusion_query *****//
+const
+ GL_SAMPLES_PASSED_ARB = $8914;
+ GL_QUERY_COUNTER_BITS_ARB = $8864;
+ GL_CURRENT_QUERY_ARB = $8865;
+ GL_QUERY_RESULT_ARB = $8866;
+ GL_QUERY_RESULT_AVAILABLE_ARB = $8867;
+var
+ glGenQueriesARB: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteQueriesARB: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsQueryARB: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBeginQueryARB: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndQueryARB: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryObjectivARB: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryObjectuivARB: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_occlusion_query: Boolean;
+
+//***** GL_ARB_shader_objects *****//
+const
+ GL_PROGRAM_OBJECT_ARB = $8B40;
+ GL_OBJECT_TYPE_ARB = $8B4E;
+ GL_OBJECT_SUBTYPE_ARB = $8B4F;
+ GL_OBJECT_DELETE_STATUS_ARB = $8B80;
+ GL_OBJECT_COMPILE_STATUS_ARB = $8B81;
+ GL_OBJECT_LINK_STATUS_ARB = $8B82;
+ GL_OBJECT_VALIDATE_STATUS_ARB = $8B83;
+ GL_OBJECT_INFO_LOG_LENGTH_ARB = $8B84;
+ GL_OBJECT_ATTACHED_OBJECTS_ARB = $8B85;
+ GL_OBJECT_ACTIVE_UNIFORMS_ARB = $8B86;
+ GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = $8B87;
+ GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = $8B88;
+ GL_SHADER_OBJECT_ARB = $8B48;
+ GL_FLOAT = $1406;
+ GL_FLOAT_VEC2_ARB = $8B50;
+ GL_FLOAT_VEC3_ARB = $8B51;
+ GL_FLOAT_VEC4_ARB = $8B52;
+ GL_INT = $1404;
+ GL_INT_VEC2_ARB = $8B53;
+ GL_INT_VEC3_ARB = $8B54;
+ GL_INT_VEC4_ARB = $8B55;
+ GL_BOOL_ARB = $8B56;
+ GL_BOOL_VEC2_ARB = $8B57;
+ GL_BOOL_VEC3_ARB = $8B58;
+ GL_BOOL_VEC4_ARB = $8B59;
+ GL_FLOAT_MAT2_ARB = $8B5A;
+ GL_FLOAT_MAT3_ARB = $8B5B;
+ GL_FLOAT_MAT4_ARB = $8B5C;
+var
+ glDeleteObjectARB: procedure(obj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetHandleARB: function(pname: GLenum): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDetachObjectARB: procedure(containerObj: GLhandleARB; attachedObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCreateShaderObjectARB: function(shaderType: GLenum): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShaderSourceARB: procedure(shaderObj: GLhandleARB; count: GLsizei; const _string: PGLvoid; const length: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompileShaderARB: procedure(shaderObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCreateProgramObjectARB: function(): GLhandleARB; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAttachObjectARB: procedure(containerObj: GLhandleARB; obj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLinkProgramARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUseProgramObjectARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glValidateProgramARB: procedure(programObj: GLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1fARB: procedure(location: GLint; v0: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1iARB: procedure(location: GLint; v0: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2iARB: procedure(location: GLint; v0: GLint; v1: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix2fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix3fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix4fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetObjectParameterfvARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetObjectParameterivARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetInfoLogARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; infoLog: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetAttachedObjectsARB: procedure(containerObj: GLhandleARB; maxCount: GLsizei; count: PGLsizei; obj: PGLhandleARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetActiveUniformARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformfvARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformivARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetShaderSourceARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; source: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_shader_objects: Boolean;
+
+//***** GL_ARB_vertex_shader *****//
+const
+ GL_VERTEX_SHADER_ARB = $8B31;
+ GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = $8B4A;
+ GL_MAX_VARYING_FLOATS_ARB = $8B4B;
+ // GL_MAX_VERTEX_ATTRIBS_ARB { already defined }
+ // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined }
+ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C;
+ GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = $8B4D;
+ // GL_MAX_TEXTURE_COORDS_ARB { already defined }
+ // GL_VERTEX_PROGRAM_POINT_SIZE_ARB { already defined }
+ // GL_VERTEX_PROGRAM_TWO_SIDE_ARB { already defined }
+ // GL_OBJECT_TYPE_ARB { already defined }
+ // GL_OBJECT_SUBTYPE_ARB { already defined }
+ GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = $8B89;
+ GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = $8B8A;
+ // GL_SHADER_OBJECT_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB { already defined }
+ // GL_CURRENT_VERTEX_ATTRIB_ARB { already defined }
+ // GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB { already defined }
+ // GL_FLOAT { already defined }
+ // GL_FLOAT_VEC2_ARB { already defined }
+ // GL_FLOAT_VEC3_ARB { already defined }
+ // GL_FLOAT_VEC4_ARB { already defined }
+ // GL_FLOAT_MAT2_ARB { already defined }
+ // GL_FLOAT_MAT3_ARB { already defined }
+ // GL_FLOAT_MAT4_ARB { already defined }
+ // glVertexAttrib1fARB { already defined }
+ // glVertexAttrib1sARB { already defined }
+ // glVertexAttrib1dARB { already defined }
+ // glVertexAttrib2fARB { already defined }
+ // glVertexAttrib2sARB { already defined }
+ // glVertexAttrib2dARB { already defined }
+ // glVertexAttrib3fARB { already defined }
+ // glVertexAttrib3sARB { already defined }
+ // glVertexAttrib3dARB { already defined }
+ // glVertexAttrib4fARB { already defined }
+ // glVertexAttrib4sARB { already defined }
+ // glVertexAttrib4dARB { already defined }
+ // glVertexAttrib4NubARB { already defined }
+ // glVertexAttrib1fvARB { already defined }
+ // glVertexAttrib1svARB { already defined }
+ // glVertexAttrib1dvARB { already defined }
+ // glVertexAttrib2fvARB { already defined }
+ // glVertexAttrib2svARB { already defined }
+ // glVertexAttrib2dvARB { already defined }
+ // glVertexAttrib3fvARB { already defined }
+ // glVertexAttrib3svARB { already defined }
+ // glVertexAttrib3dvARB { already defined }
+ // glVertexAttrib4fvARB { already defined }
+ // glVertexAttrib4svARB { already defined }
+ // glVertexAttrib4dvARB { already defined }
+ // glVertexAttrib4ivARB { already defined }
+ // glVertexAttrib4bvARB { already defined }
+ // glVertexAttrib4ubvARB { already defined }
+ // glVertexAttrib4usvARB { already defined }
+ // glVertexAttrib4uivARB { already defined }
+ // glVertexAttrib4NbvARB { already defined }
+ // glVertexAttrib4NsvARB { already defined }
+ // glVertexAttrib4NivARB { already defined }
+ // glVertexAttrib4NubvARB { already defined }
+ // glVertexAttrib4NusvARB { already defined }
+ // glVertexAttrib4NuivARB { already defined }
+ // glVertexAttribPointerARB { already defined }
+ // glEnableVertexAttribArrayARB { already defined }
+ // glDisableVertexAttribArrayARB { already defined }
+var
+ glBindAttribLocationARB: procedure(programObj: GLhandleARB; index: GLuint; const name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetActiveAttribARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetAttribLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ // glGetVertexAttribdvARB { already defined }
+ // glGetVertexAttribfvARB { already defined }
+ // glGetVertexAttribivARB { already defined }
+ // glGetVertexAttribPointervARB { already defined }
+
+function Load_GL_ARB_vertex_shader: Boolean;
+
+//***** GL_ARB_fragment_shader *****//
+const
+ GL_FRAGMENT_SHADER_ARB = $8B30;
+ GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = $8B49;
+ // GL_MAX_TEXTURE_COORDS_ARB { already defined }
+ // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined }
+ // GL_OBJECT_TYPE_ARB { already defined }
+ // GL_OBJECT_SUBTYPE_ARB { already defined }
+ // GL_SHADER_OBJECT_ARB { already defined }
+
+function Load_GL_ARB_fragment_shader: Boolean;
+
+//***** GL_ARB_shading_language_100 *****//
+
+function Load_GL_ARB_shading_language_100: Boolean;
+
+//***** GL_ARB_texture_non_power_of_two *****//
+
+function Load_GL_ARB_texture_non_power_of_two: Boolean;
+
+//***** GL_ARB_point_sprite *****//
+const
+ GL_POINT_SPRITE_ARB = $8861;
+ GL_COORD_REPLACE_ARB = $8862;
+
+function Load_GL_ARB_point_sprite: Boolean;
+
+//***** GL_EXT_depth_bounds_test *****//
+const
+ GL_DEPTH_BOUNDS_TEST_EXT = $8890;
+ GL_DEPTH_BOUNDS_EXT = $8891;
+var
+ glDepthBoundsEXT: procedure(zmin: GLclampd; zmax: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_depth_bounds_test: Boolean;
+
+//***** GL_EXT_secondary_color *****//
+const
+ GL_COLOR_SUM_EXT = $8458;
+ GL_CURRENT_SECONDARY_COLOR_EXT = $8459;
+ GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A;
+ GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B;
+ GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C;
+ GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D;
+ GL_SECONDARY_COLOR_ARRAY_EXT = $845E;
+var
+ glSecondaryColor3bEXT: procedure(r: GLbyte; g: GLbyte; b: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3sEXT: procedure(r: GLshort; g: GLshort; b: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3iEXT: procedure(r: GLint; g: GLint; b: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3fEXT: procedure(r: GLfloat; g: GLfloat; b: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3dEXT: procedure(r: GLdouble; g: GLdouble; b: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ubEXT: procedure(r: GLubyte; g: GLubyte; b: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3usEXT: procedure(r: GLushort; g: GLushort; b: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3uiEXT: procedure(r: GLuint; g: GLuint; b: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3bvEXT: procedure(components: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3svEXT: procedure(components: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ivEXT: procedure(components: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3fvEXT: procedure(components: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3dvEXT: procedure(components: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ubvEXT: procedure(components: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3usvEXT: procedure(components: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3uivEXT: procedure(components: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_secondary_color: Boolean;
+
+//***** GL_EXT_texture_mirror_clamp *****//
+const
+ GL_MIRROR_CLAMP_EXT = $8742;
+ GL_MIRROR_CLAMP_TO_EDGE_EXT = $8743;
+ GL_MIRROR_CLAMP_TO_BORDER_EXT = $8912;
+
+function Load_GL_EXT_texture_mirror_clamp: Boolean;
+
+//***** GL_EXT_blend_equation_separate *****//
+const
+ GL_BLEND_EQUATION_RGB_EXT = $8009;
+ GL_BLEND_EQUATION_ALPHA_EXT = $883D;
+var
+ glBlendEquationSeparateEXT: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_blend_equation_separate: Boolean;
+
+//***** GL_MESA_pack_invert *****//
+const
+ GL_PACK_INVERT_MESA = $8758;
+
+function Load_GL_MESA_pack_invert: Boolean;
+
+//***** GL_MESA_ycbcr_texture *****//
+const
+ GL_YCBCR_MESA = $8757;
+ GL_UNSIGNED_SHORT_8_8_MESA = $85BA;
+ GL_UNSIGNED_SHORT_8_8_REV_MESA = $85BB;
+
+function Load_GL_MESA_ycbcr_texture: Boolean;
+
+//***** GL_ARB_fragment_program_shadow *****//
+
+function Load_GL_ARB_fragment_program_shadow: Boolean;
+
+//***** GL_EXT_fog_coord *****//
+const
+ GL_FOG_COORDINATE_SOURCE_EXT = $8450;
+ GL_FOG_COORDINATE_EXT = $8451;
+ GL_FRAGMENT_DEPTH_EXT = $8452;
+ GL_CURRENT_FOG_COORDINATE_EXT = $8453;
+ GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454;
+ GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455;
+ GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456;
+ GL_FOG_COORDINATE_ARRAY_EXT = $8457;
+var
+ glFogCoordfEXT: procedure(coord: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoorddEXT: procedure(coord: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordfvEXT: procedure(coord: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoorddvEXT: procedure(coord: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordPointerEXT: procedure(_type: GLenum; stride: GLsizei; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_fog_coord: Boolean;
+
+//***** GL_NV_fragment_program_option *****//
+
+function Load_GL_NV_fragment_program_option: Boolean;
+
+//***** GL_EXT_pixel_buffer_object *****//
+const
+ GL_PIXEL_PACK_BUFFER_EXT = $88EB;
+ GL_PIXEL_UNPACK_BUFFER_EXT = $88EC;
+ GL_PIXEL_PACK_BUFFER_BINDING_EXT = $88ED;
+ GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = $88EF;
+
+function Load_GL_EXT_pixel_buffer_object: Boolean;
+
+//***** GL_NV_fragment_program2 *****//
+const
+ GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = $88F4;
+ GL_MAX_PROGRAM_CALL_DEPTH_NV = $88F5;
+ GL_MAX_PROGRAM_IF_DEPTH_NV = $88F6;
+ GL_MAX_PROGRAM_LOOP_DEPTH_NV = $88F7;
+ GL_MAX_PROGRAM_LOOP_COUNT_NV = $88F8;
+
+function Load_GL_NV_fragment_program2: Boolean;
+
+//***** GL_NV_vertex_program2_option *****//
+ // GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV { already defined }
+ // GL_MAX_PROGRAM_CALL_DEPTH_NV { already defined }
+
+function Load_GL_NV_vertex_program2_option: Boolean;
+
+//***** GL_NV_vertex_program3 *****//
+ // GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB { already defined }
+
+function Load_GL_NV_vertex_program3: Boolean;
+
+//***** GL_ARB_draw_buffers *****//
+const
+ GL_MAX_DRAW_BUFFERS_ARB = $8824;
+ GL_DRAW_BUFFER0_ARB = $8825;
+ GL_DRAW_BUFFER1_ARB = $8826;
+ GL_DRAW_BUFFER2_ARB = $8827;
+ GL_DRAW_BUFFER3_ARB = $8828;
+ GL_DRAW_BUFFER4_ARB = $8829;
+ GL_DRAW_BUFFER5_ARB = $882A;
+ GL_DRAW_BUFFER6_ARB = $882B;
+ GL_DRAW_BUFFER7_ARB = $882C;
+ GL_DRAW_BUFFER8_ARB = $882D;
+ GL_DRAW_BUFFER9_ARB = $882E;
+ GL_DRAW_BUFFER10_ARB = $882F;
+ GL_DRAW_BUFFER11_ARB = $8830;
+ GL_DRAW_BUFFER12_ARB = $8831;
+ GL_DRAW_BUFFER13_ARB = $8832;
+ GL_DRAW_BUFFER14_ARB = $8833;
+ GL_DRAW_BUFFER15_ARB = $8834;
+var
+ glDrawBuffersARB: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_draw_buffers: Boolean;
+
+//***** GL_ARB_texture_rectangle *****//
+const
+ GL_TEXTURE_RECTANGLE_ARB = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_ARB = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_ARB = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = $84F8;
+
+function Load_GL_ARB_texture_rectangle: Boolean;
+
+//***** GL_ARB_color_buffer_float *****//
+const
+ GL_RGBA_FLOAT_MODE_ARB = $8820;
+ GL_CLAMP_VERTEX_COLOR_ARB = $891A;
+ GL_CLAMP_FRAGMENT_COLOR_ARB = $891B;
+ GL_CLAMP_READ_COLOR_ARB = $891C;
+ GL_FIXED_ONLY_ARB = $891D;
+ WGL_TYPE_RGBA_FLOAT_ARB = $21A0;
+var
+ glClampColorARB: procedure(target: GLenum; clamp: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_ARB_color_buffer_float: Boolean;
+
+//***** GL_ARB_half_float_pixel *****//
+const
+ GL_HALF_FLOAT_ARB = $140B;
+
+function Load_GL_ARB_half_float_pixel: Boolean;
+
+//***** GL_ARB_texture_float *****//
+const
+ GL_TEXTURE_RED_TYPE_ARB = $8C10;
+ GL_TEXTURE_GREEN_TYPE_ARB = $8C11;
+ GL_TEXTURE_BLUE_TYPE_ARB = $8C12;
+ GL_TEXTURE_ALPHA_TYPE_ARB = $8C13;
+ GL_TEXTURE_LUMINANCE_TYPE_ARB = $8C14;
+ GL_TEXTURE_INTENSITY_TYPE_ARB = $8C15;
+ GL_TEXTURE_DEPTH_TYPE_ARB = $8C16;
+ GL_UNSIGNED_NORMALIZED_ARB = $8C17;
+ GL_RGBA32F_ARB = $8814;
+ GL_RGB32F_ARB = $8815;
+ GL_ALPHA32F_ARB = $8816;
+ GL_INTENSITY32F_ARB = $8817;
+ GL_LUMINANCE32F_ARB = $8818;
+ GL_LUMINANCE_ALPHA32F_ARB = $8819;
+ GL_RGBA16F_ARB = $881A;
+ GL_RGB16F_ARB = $881B;
+ GL_ALPHA16F_ARB = $881C;
+ GL_INTENSITY16F_ARB = $881D;
+ GL_LUMINANCE16F_ARB = $881E;
+ GL_LUMINANCE_ALPHA16F_ARB = $881F;
+
+function Load_GL_ARB_texture_float: Boolean;
+
+//***** GL_EXT_texture_compression_dxt1 *****//
+ // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined }
+ // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined }
+
+function Load_GL_EXT_texture_compression_dxt1: Boolean;
+
+//***** GL_ARB_pixel_buffer_object *****//
+const
+ GL_PIXEL_PACK_BUFFER_ARB = $88EB;
+ GL_PIXEL_UNPACK_BUFFER_ARB = $88EC;
+ GL_PIXEL_PACK_BUFFER_BINDING_ARB = $88ED;
+ GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = $88EF;
+
+function Load_GL_ARB_pixel_buffer_object: Boolean;
+
+//***** GL_EXT_framebuffer_object *****//
+const
+ GL_FRAMEBUFFER_EXT = $8D40;
+ GL_RENDERBUFFER_EXT = $8D41;
+ GL_STENCIL_INDEX_EXT = $8D45;
+ GL_STENCIL_INDEX1_EXT = $8D46;
+ GL_STENCIL_INDEX4_EXT = $8D47;
+ GL_STENCIL_INDEX8_EXT = $8D48;
+ GL_STENCIL_INDEX16_EXT = $8D49;
+ GL_RENDERBUFFER_WIDTH_EXT = $8D42;
+ GL_RENDERBUFFER_HEIGHT_EXT = $8D43;
+ GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = $8D44;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = $8CD0;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = $8CD1;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = $8CD2;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = $8CD3;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = $8CD4;
+ GL_COLOR_ATTACHMENT0_EXT = $8CE0;
+ GL_COLOR_ATTACHMENT1_EXT = $8CE1;
+ GL_COLOR_ATTACHMENT2_EXT = $8CE2;
+ GL_COLOR_ATTACHMENT3_EXT = $8CE3;
+ GL_COLOR_ATTACHMENT4_EXT = $8CE4;
+ GL_COLOR_ATTACHMENT5_EXT = $8CE5;
+ GL_COLOR_ATTACHMENT6_EXT = $8CE6;
+ GL_COLOR_ATTACHMENT7_EXT = $8CE7;
+ GL_COLOR_ATTACHMENT8_EXT = $8CE8;
+ GL_COLOR_ATTACHMENT9_EXT = $8CE9;
+ GL_COLOR_ATTACHMENT10_EXT = $8CEA;
+ GL_COLOR_ATTACHMENT11_EXT = $8CEB;
+ GL_COLOR_ATTACHMENT12_EXT = $8CEC;
+ GL_COLOR_ATTACHMENT13_EXT = $8CED;
+ GL_COLOR_ATTACHMENT14_EXT = $8CEE;
+ GL_COLOR_ATTACHMENT15_EXT = $8CEF;
+ GL_DEPTH_ATTACHMENT_EXT = $8D00;
+ GL_STENCIL_ATTACHMENT_EXT = $8D20;
+ GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5;
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = $8CD6;
+ GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = $8CD7;
+ GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT = $8CD8;
+ GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = $8CD9;
+ GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = $8CDA;
+ GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = $8CDB;
+ GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = $8CDC;
+ GL_FRAMEBUFFER_UNSUPPORTED_EXT = $8CDD;
+ GL_FRAMEBUFFER_STATUS_ERROR_EXT = $8CDE;
+ GL_FRAMEBUFFER_BINDING_EXT = $8CA6;
+ GL_RENDERBUFFER_BINDING_EXT = $8CA7;
+ GL_MAX_COLOR_ATTACHMENTS_EXT = $8CDF;
+ GL_MAX_RENDERBUFFER_SIZE_EXT = $84E8;
+ GL_INVALID_FRAMEBUFFER_OPERATION_EXT = $0506;
+var
+ glIsRenderbufferEXT: function(renderbuffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindRenderbufferEXT: procedure(target: GLenum; renderbuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteRenderbuffersEXT: procedure(n: GLsizei; const renderbuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenRenderbuffersEXT: procedure(n: GLsizei; renderbuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glRenderbufferStorageEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetRenderbufferParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsFramebufferEXT: function(framebuffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindFramebufferEXT: procedure(target: GLenum; framebuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteFramebuffersEXT: procedure(n: GLsizei; const framebuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenFramebuffersEXT: procedure(n: GLsizei; framebuffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCheckFramebufferStatusEXT: function(target: GLenum): GLenum; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFramebufferTexture1DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFramebufferTexture2DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFramebufferTexture3DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFramebufferRenderbufferEXT: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFramebufferAttachmentParameterivEXT: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenerateMipmapEXT: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_EXT_framebuffer_object: Boolean;
+
+//***** GL_version_1_4 *****//
+const
+ GL_BLEND_DST_RGB = $80C8;
+ GL_BLEND_SRC_RGB = $80C9;
+ GL_BLEND_DST_ALPHA = $80CA;
+ GL_BLEND_SRC_ALPHA = $80CB;
+ GL_POINT_SIZE_MIN = $8126;
+ GL_POINT_SIZE_MAX = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE = $8128;
+ GL_POINT_DISTANCE_ATTENUATION = $8129;
+ GL_GENERATE_MIPMAP = $8191;
+ GL_GENERATE_MIPMAP_HINT = $8192;
+ GL_DEPTH_COMPONENT16 = $81A5;
+ GL_DEPTH_COMPONENT24 = $81A6;
+ GL_DEPTH_COMPONENT32 = $81A7;
+ GL_MIRRORED_REPEAT = $8370;
+ GL_FOG_COORDINATE_SOURCE = $8450;
+ GL_FOG_COORDINATE = $8451;
+ GL_FRAGMENT_DEPTH = $8452;
+ GL_CURRENT_FOG_COORDINATE = $8453;
+ GL_FOG_COORDINATE_ARRAY_TYPE = $8454;
+ GL_FOG_COORDINATE_ARRAY_STRIDE = $8455;
+ GL_FOG_COORDINATE_ARRAY_POINTER = $8456;
+ GL_FOG_COORDINATE_ARRAY = $8457;
+ GL_COLOR_SUM = $8458;
+ GL_CURRENT_SECONDARY_COLOR = $8459;
+ GL_SECONDARY_COLOR_ARRAY_SIZE = $845A;
+ GL_SECONDARY_COLOR_ARRAY_TYPE = $845B;
+ GL_SECONDARY_COLOR_ARRAY_STRIDE = $845C;
+ GL_SECONDARY_COLOR_ARRAY_POINTER = $845D;
+ GL_SECONDARY_COLOR_ARRAY = $845E;
+ GL_MAX_TEXTURE_LOD_BIAS = $84FD;
+ GL_TEXTURE_FILTER_CONTROL = $8500;
+ GL_TEXTURE_LOD_BIAS = $8501;
+ GL_INCR_WRAP = $8507;
+ GL_DECR_WRAP = $8508;
+ GL_TEXTURE_DEPTH_SIZE = $884A;
+ GL_DEPTH_TEXTURE_MODE = $884B;
+ GL_TEXTURE_COMPARE_MODE = $884C;
+ GL_TEXTURE_COMPARE_FUNC = $884D;
+ GL_COMPARE_R_TO_TEXTURE = $884E;
+var
+ glBlendFuncSeparate: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordf: procedure(coord: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordfv: procedure(const coord: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordd: procedure(coord: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoorddv: procedure(const coord: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogCoordPointer: procedure(_type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawArrays: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultiDrawElements: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameterf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameterfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameteri: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointParameteriv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3b: procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3d: procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3f: procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3i: procedure(red: GLint; green: GLint; blue: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3s: procedure(red: GLshort; green: GLshort; blue: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ub: procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ubv: procedure(const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3ui: procedure(red: GLuint; green: GLuint; blue: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3uiv: procedure(const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3us: procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColor3usv: procedure(const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSecondaryColorPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2d: procedure(x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2f: procedure(x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2i: procedure(x: GLint; y: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2s: procedure(x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos2sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3d: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3f: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3i: procedure(x: GLint; y: GLint; z: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3s: procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glWindowPos3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_version_1_4: Boolean;
+
+//***** GL_version_1_5 *****//
+const
+ GL_BUFFER_SIZE = $8764;
+ GL_BUFFER_USAGE = $8765;
+ GL_QUERY_COUNTER_BITS = $8864;
+ GL_CURRENT_QUERY = $8865;
+ GL_QUERY_RESULT = $8866;
+ GL_QUERY_RESULT_AVAILABLE = $8867;
+ GL_ARRAY_BUFFER = $8892;
+ GL_ELEMENT_ARRAY_BUFFER = $8893;
+ GL_ARRAY_BUFFER_BINDING = $8894;
+ GL_ELEMENT_ARRAY_BUFFER_BINDING = $8895;
+ GL_VERTEX_ARRAY_BUFFER_BINDING = $8896;
+ GL_NORMAL_ARRAY_BUFFER_BINDING = $8897;
+ GL_COLOR_ARRAY_BUFFER_BINDING = $8898;
+ GL_INDEX_ARRAY_BUFFER_BINDING = $8899;
+ GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = $889A;
+ GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = $889B;
+ GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = $889C;
+ GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = $889D;
+ GL_WEIGHT_ARRAY_BUFFER_BINDING = $889E;
+ GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = $889F;
+ GL_READ_ONLY = $88B8;
+ GL_WRITE_ONLY = $88B9;
+ GL_READ_WRITE = $88BA;
+ GL_BUFFER_ACCESS = $88BB;
+ GL_BUFFER_MAPPED = $88BC;
+ GL_BUFFER_MAP_POINTER = $88BD;
+ GL_STREAM_DRAW = $88E0;
+ GL_STREAM_READ = $88E1;
+ GL_STREAM_COPY = $88E2;
+ GL_STATIC_DRAW = $88E4;
+ GL_STATIC_READ = $88E5;
+ GL_STATIC_COPY = $88E6;
+ GL_DYNAMIC_DRAW = $88E8;
+ GL_DYNAMIC_READ = $88E9;
+ GL_DYNAMIC_COPY = $88EA;
+ GL_SAMPLES_PASSED = $8914;
+ GL_FOG_COORD_SRC = $8450;
+ GL_FOG_COORD = $8451;
+ GL_CURRENT_FOG_COORD = $8453;
+ GL_FOG_COORD_ARRAY_TYPE = $8454;
+ GL_FOG_COORD_ARRAY_STRIDE = $8455;
+ GL_FOG_COORD_ARRAY_POINTER = $8456;
+ GL_FOG_COORD_ARRAY = $8457;
+ GL_FOG_COORD_ARRAY_BUFFER_BINDING = $889D;
+ GL_SRC0_RGB = $8580;
+ GL_SRC1_RGB = $8581;
+ GL_SRC2_RGB = $8582;
+ GL_SRC0_ALPHA = $8588;
+ GL_SRC1_ALPHA = $8589;
+ GL_SRC2_ALPHA = $858A;
+var
+ glGenQueries: procedure(n: GLsizei; ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteQueries: procedure(n: GLsizei; const ids: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsQuery: function(id: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBeginQuery: procedure(target: GLenum; id: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEndQuery: procedure(target: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryObjectiv: procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetQueryObjectuiv: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindBuffer: procedure(target: GLenum; buffer: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteBuffers: procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenBuffers: procedure(n: GLsizei; buffers: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsBuffer: function(buffer: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBufferData: procedure(target: GLenum; size: GLsizeiptr; const data: PGLvoid; usage: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapBuffer: function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUnmapBuffer: function(target: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBufferPointerv: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_version_1_5: Boolean;
+
+//***** GL_version_2_0 *****//
+const
+ GL_BLEND_EQUATION_RGB = $8009;
+ GL_VERTEX_ATTRIB_ARRAY_ENABLED = $8622;
+ GL_VERTEX_ATTRIB_ARRAY_SIZE = $8623;
+ GL_VERTEX_ATTRIB_ARRAY_STRIDE = $8624;
+ GL_VERTEX_ATTRIB_ARRAY_TYPE = $8625;
+ GL_CURRENT_VERTEX_ATTRIB = $8626;
+ GL_VERTEX_PROGRAM_POINT_SIZE = $8642;
+ GL_VERTEX_PROGRAM_TWO_SIDE = $8643;
+ GL_VERTEX_ATTRIB_ARRAY_POINTER = $8645;
+ GL_STENCIL_BACK_FUNC = $8800;
+ GL_STENCIL_BACK_FAIL = $8801;
+ GL_STENCIL_BACK_PASS_DEPTH_FAIL = $8802;
+ GL_STENCIL_BACK_PASS_DEPTH_PASS = $8803;
+ GL_MAX_DRAW_BUFFERS = $8824;
+ GL_DRAW_BUFFER0 = $8825;
+ GL_DRAW_BUFFER1 = $8826;
+ GL_DRAW_BUFFER2 = $8827;
+ GL_DRAW_BUFFER3 = $8828;
+ GL_DRAW_BUFFER4 = $8829;
+ GL_DRAW_BUFFER5 = $882A;
+ GL_DRAW_BUFFER6 = $882B;
+ GL_DRAW_BUFFER7 = $882C;
+ GL_DRAW_BUFFER8 = $882D;
+ GL_DRAW_BUFFER9 = $882E;
+ GL_DRAW_BUFFER10 = $882F;
+ GL_DRAW_BUFFER11 = $8830;
+ GL_DRAW_BUFFER12 = $8831;
+ GL_DRAW_BUFFER13 = $8832;
+ GL_DRAW_BUFFER14 = $8833;
+ GL_DRAW_BUFFER15 = $8834;
+ GL_BLEND_EQUATION_ALPHA = $883D;
+ GL_POINT_SPRITE = $8861;
+ GL_COORD_REPLACE = $8862;
+ GL_MAX_VERTEX_ATTRIBS = $8869;
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = $886A;
+ GL_MAX_TEXTURE_COORDS = $8871;
+ GL_MAX_TEXTURE_IMAGE_UNITS = $8872;
+ GL_FRAGMENT_SHADER = $8B30;
+ GL_VERTEX_SHADER = $8B31;
+ GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = $8B49;
+ GL_MAX_VERTEX_UNIFORM_COMPONENTS = $8B4A;
+ GL_MAX_VARYING_FLOATS = $8B4B;
+ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = $8B4C;
+ GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = $8B4D;
+ GL_SHADER_TYPE = $8B4F;
+ GL_FLOAT_VEC2 = $8B50;
+ GL_FLOAT_VEC3 = $8B51;
+ GL_FLOAT_VEC4 = $8B52;
+ GL_INT_VEC2 = $8B53;
+ GL_INT_VEC3 = $8B54;
+ GL_INT_VEC4 = $8B55;
+ GL_BOOL = $8B56;
+ GL_BOOL_VEC2 = $8B57;
+ GL_BOOL_VEC3 = $8B58;
+ GL_BOOL_VEC4 = $8B59;
+ GL_FLOAT_MAT2 = $8B5A;
+ GL_FLOAT_MAT3 = $8B5B;
+ GL_FLOAT_MAT4 = $8B5C;
+ GL_SAMPLER_1D = $8B5D;
+ GL_SAMPLER_2D = $8B5E;
+ GL_SAMPLER_3D = $8B5F;
+ GL_SAMPLER_CUBE = $8B60;
+ GL_SAMPLER_1D_SHADOW = $8B61;
+ GL_SAMPLER_2D_SHADOW = $8B62;
+ GL_DELETE_STATUS = $8B80;
+ GL_COMPILE_STATUS = $8B81;
+ GL_LINK_STATUS = $8B82;
+ GL_VALIDATE_STATUS = $8B83;
+ GL_INFO_LOG_LENGTH = $8B84;
+ GL_ATTACHED_SHADERS = $8B85;
+ GL_ACTIVE_UNIFORMS = $8B86;
+ GL_ACTIVE_UNIFORM_MAX_LENGTH = $8B87;
+ GL_SHADER_SOURCE_LENGTH = $8B88;
+ GL_ACTIVE_ATTRIBUTES = $8B89;
+ GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = $8B8A;
+ GL_FRAGMENT_SHADER_DERIVATIVE_HINT = $8B8B;
+ GL_SHADING_LANGUAGE_VERSION = $8B8C;
+ GL_CURRENT_PROGRAM = $8B8D;
+ GL_POINT_SPRITE_COORD_ORIGIN = $8CA0;
+ GL_LOWER_LEFT = $8CA1;
+ GL_UPPER_LEFT = $8CA2;
+ GL_STENCIL_BACK_REF = $8CA3;
+ GL_STENCIL_BACK_VALUE_MASK = $8CA4;
+ GL_STENCIL_BACK_WRITEMASK = $8CA5;
+var
+ glBlendEquationSeparate: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawBuffers: procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilOpSeparate: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilFuncSeparate: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilMaskSeparate: procedure(face: GLenum; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAttachShader: procedure(_program: GLuint; shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBindAttribLocation: procedure(_program: GLuint; index: GLuint; const name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCompileShader: procedure(shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCreateProgram: function(): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCreateShader: function(_type: GLenum): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteShader: procedure(shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDetachShader: procedure(_program: GLuint; shader: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDisableVertexAttribArray: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEnableVertexAttribArray: procedure(index: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetActiveAttrib: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetActiveUniform: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetAttachedShaders: procedure(_program: GLuint; maxCount: GLsizei; count: PGLsizei; obj: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetAttribLocation: function(_program: GLuint; const name: PGLchar): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramiv: procedure(_program: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetProgramInfoLog: procedure(_program: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetShaderiv: procedure(shader: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetShaderInfoLog: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetShaderSource: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; source: PGLchar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformLocation: function(_program: GLuint; const name: PGLchar): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformfv: procedure(_program: GLuint; location: GLint; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetUniformiv: procedure(_program: GLuint; location: GLint; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribdv: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribfv: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetVertexAttribPointerv: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsProgram: function(_program: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsShader: function(shader: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLinkProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glShaderSource: procedure(shader: GLuint; count: GLsizei; const _string: PGLchar; const length: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUseProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1f: procedure(location: GLint; v0: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2f: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1i: procedure(location: GLint; v0: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2i: procedure(location: GLint; v0: GLint; v1: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform1iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform2iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform3iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniform4iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glUniformMatrix4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glValidateProgram: procedure(_program: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1d: procedure(index: GLuint; x: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1f: procedure(index: GLuint; x: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1s: procedure(index: GLuint; x: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib1sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2d: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2f: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2s: procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib2sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib3sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nbv: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Niv: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nsv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nub: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nubv: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nuiv: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4Nusv: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4bv: procedure(index: GLuint; const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4dv: procedure(index: GLuint; const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4fv: procedure(index: GLuint; const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4iv: procedure(index: GLuint; const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4sv: procedure(index: GLuint; const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4ubv: procedure(index: GLuint; const v: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4uiv: procedure(index: GLuint; const v: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttrib4usv: procedure(index: GLuint; const v: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexAttribPointer: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+function Load_GL_version_2_0: Boolean;
+
+implementation
+
+uses
+ sdl;
+
+function glext_ExtensionSupported(const extension: PChar; const searchIn: PChar): Boolean;
+var
+ extensions: PChar;
+ start: PChar;
+ where, terminator: PChar;
+begin
+
+ if (Pos(' ', extension) <> 0) or (extension = '') then
+ begin
+ Result := FALSE;
+ Exit;
+ end;
+
+ if searchIn = '' then
+ extensions := glGetString(GL_EXTENSIONS)
+ else
+ //StrLCopy( extensions, searchIn, StrLen(searchIn)+1 );
+ extensions := searchIn;
+ start := extensions;
+ while TRUE do
+ begin
+ where := StrPos(start, extension );
+ if where = nil then Break;
+ terminator := Pointer(Integer(where) + Integer( strlen( extension ) ) );
+ if (where = start) or (PChar(Integer(where) - 1)^ = ' ') then
+ begin
+ if (terminator^ = ' ') or (terminator^ = #0) then
+ begin
+ Result := TRUE;
+ Exit;
+ end;
+ end;
+ start := terminator;
+ end;
+ Result := FALSE;
+
+end;
+
+function Load_GL_version_1_2: Boolean;
+{var
+ extstring : PChar;}
+begin
+
+ Result := FALSE;
+ //extstring := glGetString( GL_EXTENSIONS );
+
+ @glCopyTexSubImage3D := SDL_GL_GetProcAddress('glCopyTexSubImage3D');
+ if not Assigned(glCopyTexSubImage3D) then Exit;
+ @glDrawRangeElements := SDL_GL_GetProcAddress('glDrawRangeElements');
+ if not Assigned(glDrawRangeElements) then Exit;
+ @glTexImage3D := SDL_GL_GetProcAddress('glTexImage3D');
+ if not Assigned(glTexImage3D) then Exit;
+ @glTexSubImage3D := SDL_GL_GetProcAddress('glTexSubImage3D');
+ if not Assigned(glTexSubImage3D) then Exit;
+
+ Result := TRUE;
+
+end;
+
+function Load_GL_ARB_imaging: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_imaging', extstring) then
+ begin
+ @glColorTable := SDL_GL_GetProcAddress('glColorTable');
+ if not Assigned(glColorTable) then Exit;
+ @glColorTableParameterfv := SDL_GL_GetProcAddress('glColorTableParameterfv');
+ if not Assigned(glColorTableParameterfv) then Exit;
+ @glColorTableParameteriv := SDL_GL_GetProcAddress('glColorTableParameteriv');
+ if not Assigned(glColorTableParameteriv) then Exit;
+ @glCopyColorTable := SDL_GL_GetProcAddress('glCopyColorTable');
+ if not Assigned(glCopyColorTable) then Exit;
+ @glGetColorTable := SDL_GL_GetProcAddress('glGetColorTable');
+ if not Assigned(glGetColorTable) then Exit;
+ @glGetColorTableParameterfv := SDL_GL_GetProcAddress('glGetColorTableParameterfv');
+ if not Assigned(glGetColorTableParameterfv) then Exit;
+ @glGetColorTableParameteriv := SDL_GL_GetProcAddress('glGetColorTableParameteriv');
+ if not Assigned(glGetColorTableParameteriv) then Exit;
+ @glColorSubTable := SDL_GL_GetProcAddress('glColorSubTable');
+ if not Assigned(glColorSubTable) then Exit;
+ @glCopyColorSubTable := SDL_GL_GetProcAddress('glCopyColorSubTable');
+ if not Assigned(glCopyColorSubTable) then Exit;
+ @glConvolutionFilter1D := SDL_GL_GetProcAddress('glConvolutionFilter1D');
+ if not Assigned(glConvolutionFilter1D) then Exit;
+ @glConvolutionFilter2D := SDL_GL_GetProcAddress('glConvolutionFilter2D');
+ if not Assigned(glConvolutionFilter2D) then Exit;
+ @glConvolutionParameterf := SDL_GL_GetProcAddress('glConvolutionParameterf');
+ if not Assigned(glConvolutionParameterf) then Exit;
+ @glConvolutionParameterfv := SDL_GL_GetProcAddress('glConvolutionParameterfv');
+ if not Assigned(glConvolutionParameterfv) then Exit;
+ @glConvolutionParameteri := SDL_GL_GetProcAddress('glConvolutionParameteri');
+ if not Assigned(glConvolutionParameteri) then Exit;
+ @glConvolutionParameteriv := SDL_GL_GetProcAddress('glConvolutionParameteriv');
+ if not Assigned(glConvolutionParameteriv) then Exit;
+ @glCopyConvolutionFilter1D := SDL_GL_GetProcAddress('glCopyConvolutionFilter1D');
+ if not Assigned(glCopyConvolutionFilter1D) then Exit;
+ @glCopyConvolutionFilter2D := SDL_GL_GetProcAddress('glCopyConvolutionFilter2D');
+ if not Assigned(glCopyConvolutionFilter2D) then Exit;
+ @glGetConvolutionFilter := SDL_GL_GetProcAddress('glGetConvolutionFilter');
+ if not Assigned(glGetConvolutionFilter) then Exit;
+ @glGetConvolutionParameterfv := SDL_GL_GetProcAddress('glGetConvolutionParameterfv');
+ if not Assigned(glGetConvolutionParameterfv) then Exit;
+ @glGetConvolutionParameteriv := SDL_GL_GetProcAddress('glGetConvolutionParameteriv');
+ if not Assigned(glGetConvolutionParameteriv) then Exit;
+ @glGetSeparableFilter := SDL_GL_GetProcAddress('glGetSeparableFilter');
+ if not Assigned(glGetSeparableFilter) then Exit;
+ @glSeparableFilter2D := SDL_GL_GetProcAddress('glSeparableFilter2D');
+ if not Assigned(glSeparableFilter2D) then Exit;
+ @glGetHistogram := SDL_GL_GetProcAddress('glGetHistogram');
+ if not Assigned(glGetHistogram) then Exit;
+ @glGetHistogramParameterfv := SDL_GL_GetProcAddress('glGetHistogramParameterfv');
+ if not Assigned(glGetHistogramParameterfv) then Exit;
+ @glGetHistogramParameteriv := SDL_GL_GetProcAddress('glGetHistogramParameteriv');
+ if not Assigned(glGetHistogramParameteriv) then Exit;
+ @glGetMinmax := SDL_GL_GetProcAddress('glGetMinmax');
+ if not Assigned(glGetMinmax) then Exit;
+ @glGetMinmaxParameterfv := SDL_GL_GetProcAddress('glGetMinmaxParameterfv');
+ if not Assigned(glGetMinmaxParameterfv) then Exit;
+ @glGetMinmaxParameteriv := SDL_GL_GetProcAddress('glGetMinmaxParameteriv');
+ if not Assigned(glGetMinmaxParameteriv) then Exit;
+ @glHistogram := SDL_GL_GetProcAddress('glHistogram');
+ if not Assigned(glHistogram) then Exit;
+ @glMinmax := SDL_GL_GetProcAddress('glMinmax');
+ if not Assigned(glMinmax) then Exit;
+ @glResetHistogram := SDL_GL_GetProcAddress('glResetHistogram');
+ if not Assigned(glResetHistogram) then Exit;
+ @glResetMinmax := SDL_GL_GetProcAddress('glResetMinmax');
+ if not Assigned(glResetMinmax) then Exit;
+ @glBlendEquation := SDL_GL_GetProcAddress('glBlendEquation');
+ if not Assigned(glBlendEquation) then Exit;
+ @glBlendColor := SDL_GL_GetProcAddress('glBlendColor');
+ if not Assigned(glBlendColor) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_version_1_3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ @glActiveTexture := SDL_GL_GetProcAddress('glActiveTexture');
+ if not Assigned(glActiveTexture) then Exit;
+ @glClientActiveTexture := SDL_GL_GetProcAddress('glClientActiveTexture');
+ if not Assigned(glClientActiveTexture) then Exit;
+ @glMultiTexCoord1d := SDL_GL_GetProcAddress('glMultiTexCoord1d');
+ if not Assigned(glMultiTexCoord1d) then Exit;
+ @glMultiTexCoord1dv := SDL_GL_GetProcAddress('glMultiTexCoord1dv');
+ if not Assigned(glMultiTexCoord1dv) then Exit;
+ @glMultiTexCoord1f := SDL_GL_GetProcAddress('glMultiTexCoord1f');
+ if not Assigned(glMultiTexCoord1f) then Exit;
+ @glMultiTexCoord1fv := SDL_GL_GetProcAddress('glMultiTexCoord1fv');
+ if not Assigned(glMultiTexCoord1fv) then Exit;
+ @glMultiTexCoord1i := SDL_GL_GetProcAddress('glMultiTexCoord1i');
+ if not Assigned(glMultiTexCoord1i) then Exit;
+ @glMultiTexCoord1iv := SDL_GL_GetProcAddress('glMultiTexCoord1iv');
+ if not Assigned(glMultiTexCoord1iv) then Exit;
+ @glMultiTexCoord1s := SDL_GL_GetProcAddress('glMultiTexCoord1s');
+ if not Assigned(glMultiTexCoord1s) then Exit;
+ @glMultiTexCoord1sv := SDL_GL_GetProcAddress('glMultiTexCoord1sv');
+ if not Assigned(glMultiTexCoord1sv) then Exit;
+ @glMultiTexCoord2d := SDL_GL_GetProcAddress('glMultiTexCoord2d');
+ if not Assigned(glMultiTexCoord2d) then Exit;
+ @glMultiTexCoord2dv := SDL_GL_GetProcAddress('glMultiTexCoord2dv');
+ if not Assigned(glMultiTexCoord2dv) then Exit;
+ @glMultiTexCoord2f := SDL_GL_GetProcAddress('glMultiTexCoord2f');
+ if not Assigned(glMultiTexCoord2f) then Exit;
+ @glMultiTexCoord2fv := SDL_GL_GetProcAddress('glMultiTexCoord2fv');
+ if not Assigned(glMultiTexCoord2fv) then Exit;
+ @glMultiTexCoord2i := SDL_GL_GetProcAddress('glMultiTexCoord2i');
+ if not Assigned(glMultiTexCoord2i) then Exit;
+ @glMultiTexCoord2iv := SDL_GL_GetProcAddress('glMultiTexCoord2iv');
+ if not Assigned(glMultiTexCoord2iv) then Exit;
+ @glMultiTexCoord2s := SDL_GL_GetProcAddress('glMultiTexCoord2s');
+ if not Assigned(glMultiTexCoord2s) then Exit;
+ @glMultiTexCoord2sv := SDL_GL_GetProcAddress('glMultiTexCoord2sv');
+ if not Assigned(glMultiTexCoord2sv) then Exit;
+ @glMultiTexCoord3d := SDL_GL_GetProcAddress('glMultiTexCoord3d');
+ if not Assigned(glMultiTexCoord3d) then Exit;
+ @glMultiTexCoord3dv := SDL_GL_GetProcAddress('glMultiTexCoord3dv');
+ if not Assigned(glMultiTexCoord3dv) then Exit;
+ @glMultiTexCoord3f := SDL_GL_GetProcAddress('glMultiTexCoord3f');
+ if not Assigned(glMultiTexCoord3f) then Exit;
+ @glMultiTexCoord3fv := SDL_GL_GetProcAddress('glMultiTexCoord3fv');
+ if not Assigned(glMultiTexCoord3fv) then Exit;
+ @glMultiTexCoord3i := SDL_GL_GetProcAddress('glMultiTexCoord3i');
+ if not Assigned(glMultiTexCoord3i) then Exit;
+ @glMultiTexCoord3iv := SDL_GL_GetProcAddress('glMultiTexCoord3iv');
+ if not Assigned(glMultiTexCoord3iv) then Exit;
+ @glMultiTexCoord3s := SDL_GL_GetProcAddress('glMultiTexCoord3s');
+ if not Assigned(glMultiTexCoord3s) then Exit;
+ @glMultiTexCoord3sv := SDL_GL_GetProcAddress('glMultiTexCoord3sv');
+ if not Assigned(glMultiTexCoord3sv) then Exit;
+ @glMultiTexCoord4d := SDL_GL_GetProcAddress('glMultiTexCoord4d');
+ if not Assigned(glMultiTexCoord4d) then Exit;
+ @glMultiTexCoord4dv := SDL_GL_GetProcAddress('glMultiTexCoord4dv');
+ if not Assigned(glMultiTexCoord4dv) then Exit;
+ @glMultiTexCoord4f := SDL_GL_GetProcAddress('glMultiTexCoord4f');
+ if not Assigned(glMultiTexCoord4f) then Exit;
+ @glMultiTexCoord4fv := SDL_GL_GetProcAddress('glMultiTexCoord4fv');
+ if not Assigned(glMultiTexCoord4fv) then Exit;
+ @glMultiTexCoord4i := SDL_GL_GetProcAddress('glMultiTexCoord4i');
+ if not Assigned(glMultiTexCoord4i) then Exit;
+ @glMultiTexCoord4iv := SDL_GL_GetProcAddress('glMultiTexCoord4iv');
+ if not Assigned(glMultiTexCoord4iv) then Exit;
+ @glMultiTexCoord4s := SDL_GL_GetProcAddress('glMultiTexCoord4s');
+ if not Assigned(glMultiTexCoord4s) then Exit;
+ @glMultiTexCoord4sv := SDL_GL_GetProcAddress('glMultiTexCoord4sv');
+ if not Assigned(glMultiTexCoord4sv) then Exit;
+ @glLoadTransposeMatrixf := SDL_GL_GetProcAddress('glLoadTransposeMatrixf');
+ if not Assigned(glLoadTransposeMatrixf) then Exit;
+ @glLoadTransposeMatrixd := SDL_GL_GetProcAddress('glLoadTransposeMatrixd');
+ if not Assigned(glLoadTransposeMatrixd) then Exit;
+ @glMultTransposeMatrixf := SDL_GL_GetProcAddress('glMultTransposeMatrixf');
+ if not Assigned(glMultTransposeMatrixf) then Exit;
+ @glMultTransposeMatrixd := SDL_GL_GetProcAddress('glMultTransposeMatrixd');
+ if not Assigned(glMultTransposeMatrixd) then Exit;
+ @glSampleCoverage := SDL_GL_GetProcAddress('glSampleCoverage');
+ if not Assigned(glSampleCoverage) then Exit;
+ @glCompressedTexImage3D := SDL_GL_GetProcAddress('glCompressedTexImage3D');
+ if not Assigned(glCompressedTexImage3D) then Exit;
+ @glCompressedTexImage2D := SDL_GL_GetProcAddress('glCompressedTexImage2D');
+ if not Assigned(glCompressedTexImage2D) then Exit;
+ @glCompressedTexImage1D := SDL_GL_GetProcAddress('glCompressedTexImage1D');
+ if not Assigned(glCompressedTexImage1D) then Exit;
+ @glCompressedTexSubImage3D := SDL_GL_GetProcAddress('glCompressedTexSubImage3D');
+ if not Assigned(glCompressedTexSubImage3D) then Exit;
+ @glCompressedTexSubImage2D := SDL_GL_GetProcAddress('glCompressedTexSubImage2D');
+ if not Assigned(glCompressedTexSubImage2D) then Exit;
+ @glCompressedTexSubImage1D := SDL_GL_GetProcAddress('glCompressedTexSubImage1D');
+ if not Assigned(glCompressedTexSubImage1D) then Exit;
+ @glGetCompressedTexImage := SDL_GL_GetProcAddress('glGetCompressedTexImage');
+ if not Assigned(glGetCompressedTexImage) then Exit;
+ Result := TRUE;
+
+end;
+
+function Load_GL_ARB_multitexture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_multitexture', extstring) then
+ begin
+ @glActiveTextureARB := SDL_GL_GetProcAddress('glActiveTextureARB');
+ if not Assigned(glActiveTextureARB) then Exit;
+ @glClientActiveTextureARB := SDL_GL_GetProcAddress('glClientActiveTextureARB');
+ if not Assigned(glClientActiveTextureARB) then Exit;
+ @glMultiTexCoord1dARB := SDL_GL_GetProcAddress('glMultiTexCoord1dARB');
+ if not Assigned(glMultiTexCoord1dARB) then Exit;
+ @glMultiTexCoord1dvARB := SDL_GL_GetProcAddress('glMultiTexCoord1dvARB');
+ if not Assigned(glMultiTexCoord1dvARB) then Exit;
+ @glMultiTexCoord1fARB := SDL_GL_GetProcAddress('glMultiTexCoord1fARB');
+ if not Assigned(glMultiTexCoord1fARB) then Exit;
+ @glMultiTexCoord1fvARB := SDL_GL_GetProcAddress('glMultiTexCoord1fvARB');
+ if not Assigned(glMultiTexCoord1fvARB) then Exit;
+ @glMultiTexCoord1iARB := SDL_GL_GetProcAddress('glMultiTexCoord1iARB');
+ if not Assigned(glMultiTexCoord1iARB) then Exit;
+ @glMultiTexCoord1ivARB := SDL_GL_GetProcAddress('glMultiTexCoord1ivARB');
+ if not Assigned(glMultiTexCoord1ivARB) then Exit;
+ @glMultiTexCoord1sARB := SDL_GL_GetProcAddress('glMultiTexCoord1sARB');
+ if not Assigned(glMultiTexCoord1sARB) then Exit;
+ @glMultiTexCoord1svARB := SDL_GL_GetProcAddress('glMultiTexCoord1svARB');
+ if not Assigned(glMultiTexCoord1svARB) then Exit;
+ @glMultiTexCoord2dARB := SDL_GL_GetProcAddress('glMultiTexCoord2dARB');
+ if not Assigned(glMultiTexCoord2dARB) then Exit;
+ @glMultiTexCoord2dvARB := SDL_GL_GetProcAddress('glMultiTexCoord2dvARB');
+ if not Assigned(glMultiTexCoord2dvARB) then Exit;
+ @glMultiTexCoord2fARB := SDL_GL_GetProcAddress('glMultiTexCoord2fARB');
+ if not Assigned(glMultiTexCoord2fARB) then Exit;
+ @glMultiTexCoord2fvARB := SDL_GL_GetProcAddress('glMultiTexCoord2fvARB');
+ if not Assigned(glMultiTexCoord2fvARB) then Exit;
+ @glMultiTexCoord2iARB := SDL_GL_GetProcAddress('glMultiTexCoord2iARB');
+ if not Assigned(glMultiTexCoord2iARB) then Exit;
+ @glMultiTexCoord2ivARB := SDL_GL_GetProcAddress('glMultiTexCoord2ivARB');
+ if not Assigned(glMultiTexCoord2ivARB) then Exit;
+ @glMultiTexCoord2sARB := SDL_GL_GetProcAddress('glMultiTexCoord2sARB');
+ if not Assigned(glMultiTexCoord2sARB) then Exit;
+ @glMultiTexCoord2svARB := SDL_GL_GetProcAddress('glMultiTexCoord2svARB');
+ if not Assigned(glMultiTexCoord2svARB) then Exit;
+ @glMultiTexCoord3dARB := SDL_GL_GetProcAddress('glMultiTexCoord3dARB');
+ if not Assigned(glMultiTexCoord3dARB) then Exit;
+ @glMultiTexCoord3dvARB := SDL_GL_GetProcAddress('glMultiTexCoord3dvARB');
+ if not Assigned(glMultiTexCoord3dvARB) then Exit;
+ @glMultiTexCoord3fARB := SDL_GL_GetProcAddress('glMultiTexCoord3fARB');
+ if not Assigned(glMultiTexCoord3fARB) then Exit;
+ @glMultiTexCoord3fvARB := SDL_GL_GetProcAddress('glMultiTexCoord3fvARB');
+ if not Assigned(glMultiTexCoord3fvARB) then Exit;
+ @glMultiTexCoord3iARB := SDL_GL_GetProcAddress('glMultiTexCoord3iARB');
+ if not Assigned(glMultiTexCoord3iARB) then Exit;
+ @glMultiTexCoord3ivARB := SDL_GL_GetProcAddress('glMultiTexCoord3ivARB');
+ if not Assigned(glMultiTexCoord3ivARB) then Exit;
+ @glMultiTexCoord3sARB := SDL_GL_GetProcAddress('glMultiTexCoord3sARB');
+ if not Assigned(glMultiTexCoord3sARB) then Exit;
+ @glMultiTexCoord3svARB := SDL_GL_GetProcAddress('glMultiTexCoord3svARB');
+ if not Assigned(glMultiTexCoord3svARB) then Exit;
+ @glMultiTexCoord4dARB := SDL_GL_GetProcAddress('glMultiTexCoord4dARB');
+ if not Assigned(glMultiTexCoord4dARB) then Exit;
+ @glMultiTexCoord4dvARB := SDL_GL_GetProcAddress('glMultiTexCoord4dvARB');
+ if not Assigned(glMultiTexCoord4dvARB) then Exit;
+ @glMultiTexCoord4fARB := SDL_GL_GetProcAddress('glMultiTexCoord4fARB');
+ if not Assigned(glMultiTexCoord4fARB) then Exit;
+ @glMultiTexCoord4fvARB := SDL_GL_GetProcAddress('glMultiTexCoord4fvARB');
+ if not Assigned(glMultiTexCoord4fvARB) then Exit;
+ @glMultiTexCoord4iARB := SDL_GL_GetProcAddress('glMultiTexCoord4iARB');
+ if not Assigned(glMultiTexCoord4iARB) then Exit;
+ @glMultiTexCoord4ivARB := SDL_GL_GetProcAddress('glMultiTexCoord4ivARB');
+ if not Assigned(glMultiTexCoord4ivARB) then Exit;
+ @glMultiTexCoord4sARB := SDL_GL_GetProcAddress('glMultiTexCoord4sARB');
+ if not Assigned(glMultiTexCoord4sARB) then Exit;
+ @glMultiTexCoord4svARB := SDL_GL_GetProcAddress('glMultiTexCoord4svARB');
+ if not Assigned(glMultiTexCoord4svARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_transpose_matrix: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_transpose_matrix', extstring) then
+ begin
+ @glLoadTransposeMatrixfARB := SDL_GL_GetProcAddress('glLoadTransposeMatrixfARB');
+ if not Assigned(glLoadTransposeMatrixfARB) then Exit;
+ @glLoadTransposeMatrixdARB := SDL_GL_GetProcAddress('glLoadTransposeMatrixdARB');
+ if not Assigned(glLoadTransposeMatrixdARB) then Exit;
+ @glMultTransposeMatrixfARB := SDL_GL_GetProcAddress('glMultTransposeMatrixfARB');
+ if not Assigned(glMultTransposeMatrixfARB) then Exit;
+ @glMultTransposeMatrixdARB := SDL_GL_GetProcAddress('glMultTransposeMatrixdARB');
+ if not Assigned(glMultTransposeMatrixdARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_multisample: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_multisample', extstring) then
+ begin
+ @glSampleCoverageARB := SDL_GL_GetProcAddress('glSampleCoverageARB');
+ if not Assigned(glSampleCoverageARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_env_add: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_env_add', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+{$IFDEF WINDOWS}
+function Load_WGL_ARB_extensions_string: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_extensions_string', extstring) then
+ begin
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_ARB_buffer_region: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_buffer_region', extstring) then
+ begin
+ @wglCreateBufferRegionARB := SDL_GL_GetProcAddress('wglCreateBufferRegionARB');
+ if not Assigned(wglCreateBufferRegionARB) then Exit;
+ @wglDeleteBufferRegionARB := SDL_GL_GetProcAddress('wglDeleteBufferRegionARB');
+ if not Assigned(wglDeleteBufferRegionARB) then Exit;
+ @wglSaveBufferRegionARB := SDL_GL_GetProcAddress('wglSaveBufferRegionARB');
+ if not Assigned(wglSaveBufferRegionARB) then Exit;
+ @wglRestoreBufferRegionARB := SDL_GL_GetProcAddress('wglRestoreBufferRegionARB');
+ if not Assigned(wglRestoreBufferRegionARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+{$ENDIF}
+
+function Load_GL_ARB_texture_cube_map: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_cube_map', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_depth_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_depth_texture', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_point_parameters: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_point_parameters', extstring) then
+ begin
+ @glPointParameterfARB := SDL_GL_GetProcAddress('glPointParameterfARB');
+ if not Assigned(glPointParameterfARB) then Exit;
+ @glPointParameterfvARB := SDL_GL_GetProcAddress('glPointParameterfvARB');
+ if not Assigned(glPointParameterfvARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_shadow: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_shadow', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_shadow_ambient: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_shadow_ambient', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_border_clamp: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_border_clamp', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_compression: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_compression', extstring) then
+ begin
+ @glCompressedTexImage3DARB := SDL_GL_GetProcAddress('glCompressedTexImage3DARB');
+ if not Assigned(glCompressedTexImage3DARB) then Exit;
+ @glCompressedTexImage2DARB := SDL_GL_GetProcAddress('glCompressedTexImage2DARB');
+ if not Assigned(glCompressedTexImage2DARB) then Exit;
+ @glCompressedTexImage1DARB := SDL_GL_GetProcAddress('glCompressedTexImage1DARB');
+ if not Assigned(glCompressedTexImage1DARB) then Exit;
+ @glCompressedTexSubImage3DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage3DARB');
+ if not Assigned(glCompressedTexSubImage3DARB) then Exit;
+ @glCompressedTexSubImage2DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage2DARB');
+ if not Assigned(glCompressedTexSubImage2DARB) then Exit;
+ @glCompressedTexSubImage1DARB := SDL_GL_GetProcAddress('glCompressedTexSubImage1DARB');
+ if not Assigned(glCompressedTexSubImage1DARB) then Exit;
+ @glGetCompressedTexImageARB := SDL_GL_GetProcAddress('glGetCompressedTexImageARB');
+ if not Assigned(glGetCompressedTexImageARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_env_combine: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_env_combine', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_env_crossbar: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_env_crossbar', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_env_dot3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_env_dot3', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_mirrored_repeat: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_mirrored_repeat', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_vertex_blend: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_vertex_blend', extstring) then
+ begin
+ @glWeightbvARB := SDL_GL_GetProcAddress('glWeightbvARB');
+ if not Assigned(glWeightbvARB) then Exit;
+ @glWeightsvARB := SDL_GL_GetProcAddress('glWeightsvARB');
+ if not Assigned(glWeightsvARB) then Exit;
+ @glWeightivARB := SDL_GL_GetProcAddress('glWeightivARB');
+ if not Assigned(glWeightivARB) then Exit;
+ @glWeightfvARB := SDL_GL_GetProcAddress('glWeightfvARB');
+ if not Assigned(glWeightfvARB) then Exit;
+ @glWeightdvARB := SDL_GL_GetProcAddress('glWeightdvARB');
+ if not Assigned(glWeightdvARB) then Exit;
+ @glWeightvARB := SDL_GL_GetProcAddress('glWeightvARB');
+ if not Assigned(glWeightvARB) then Exit;
+ @glWeightubvARB := SDL_GL_GetProcAddress('glWeightubvARB');
+ if not Assigned(glWeightubvARB) then Exit;
+ @glWeightusvARB := SDL_GL_GetProcAddress('glWeightusvARB');
+ if not Assigned(glWeightusvARB) then Exit;
+ @glWeightuivARB := SDL_GL_GetProcAddress('glWeightuivARB');
+ if not Assigned(glWeightuivARB) then Exit;
+ @glWeightPointerARB := SDL_GL_GetProcAddress('glWeightPointerARB');
+ if not Assigned(glWeightPointerARB) then Exit;
+ @glVertexBlendARB := SDL_GL_GetProcAddress('glVertexBlendARB');
+ if not Assigned(glVertexBlendARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_vertex_program: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_vertex_program', extstring) then
+ begin
+ @glVertexAttrib1sARB := SDL_GL_GetProcAddress('glVertexAttrib1sARB');
+ if not Assigned(glVertexAttrib1sARB) then Exit;
+ @glVertexAttrib1fARB := SDL_GL_GetProcAddress('glVertexAttrib1fARB');
+ if not Assigned(glVertexAttrib1fARB) then Exit;
+ @glVertexAttrib1dARB := SDL_GL_GetProcAddress('glVertexAttrib1dARB');
+ if not Assigned(glVertexAttrib1dARB) then Exit;
+ @glVertexAttrib2sARB := SDL_GL_GetProcAddress('glVertexAttrib2sARB');
+ if not Assigned(glVertexAttrib2sARB) then Exit;
+ @glVertexAttrib2fARB := SDL_GL_GetProcAddress('glVertexAttrib2fARB');
+ if not Assigned(glVertexAttrib2fARB) then Exit;
+ @glVertexAttrib2dARB := SDL_GL_GetProcAddress('glVertexAttrib2dARB');
+ if not Assigned(glVertexAttrib2dARB) then Exit;
+ @glVertexAttrib3sARB := SDL_GL_GetProcAddress('glVertexAttrib3sARB');
+ if not Assigned(glVertexAttrib3sARB) then Exit;
+ @glVertexAttrib3fARB := SDL_GL_GetProcAddress('glVertexAttrib3fARB');
+ if not Assigned(glVertexAttrib3fARB) then Exit;
+ @glVertexAttrib3dARB := SDL_GL_GetProcAddress('glVertexAttrib3dARB');
+ if not Assigned(glVertexAttrib3dARB) then Exit;
+ @glVertexAttrib4sARB := SDL_GL_GetProcAddress('glVertexAttrib4sARB');
+ if not Assigned(glVertexAttrib4sARB) then Exit;
+ @glVertexAttrib4fARB := SDL_GL_GetProcAddress('glVertexAttrib4fARB');
+ if not Assigned(glVertexAttrib4fARB) then Exit;
+ @glVertexAttrib4dARB := SDL_GL_GetProcAddress('glVertexAttrib4dARB');
+ if not Assigned(glVertexAttrib4dARB) then Exit;
+ @glVertexAttrib4NubARB := SDL_GL_GetProcAddress('glVertexAttrib4NubARB');
+ if not Assigned(glVertexAttrib4NubARB) then Exit;
+ @glVertexAttrib1svARB := SDL_GL_GetProcAddress('glVertexAttrib1svARB');
+ if not Assigned(glVertexAttrib1svARB) then Exit;
+ @glVertexAttrib1fvARB := SDL_GL_GetProcAddress('glVertexAttrib1fvARB');
+ if not Assigned(glVertexAttrib1fvARB) then Exit;
+ @glVertexAttrib1dvARB := SDL_GL_GetProcAddress('glVertexAttrib1dvARB');
+ if not Assigned(glVertexAttrib1dvARB) then Exit;
+ @glVertexAttrib2svARB := SDL_GL_GetProcAddress('glVertexAttrib2svARB');
+ if not Assigned(glVertexAttrib2svARB) then Exit;
+ @glVertexAttrib2fvARB := SDL_GL_GetProcAddress('glVertexAttrib2fvARB');
+ if not Assigned(glVertexAttrib2fvARB) then Exit;
+ @glVertexAttrib2dvARB := SDL_GL_GetProcAddress('glVertexAttrib2dvARB');
+ if not Assigned(glVertexAttrib2dvARB) then Exit;
+ @glVertexAttrib3svARB := SDL_GL_GetProcAddress('glVertexAttrib3svARB');
+ if not Assigned(glVertexAttrib3svARB) then Exit;
+ @glVertexAttrib3fvARB := SDL_GL_GetProcAddress('glVertexAttrib3fvARB');
+ if not Assigned(glVertexAttrib3fvARB) then Exit;
+ @glVertexAttrib3dvARB := SDL_GL_GetProcAddress('glVertexAttrib3dvARB');
+ if not Assigned(glVertexAttrib3dvARB) then Exit;
+ @glVertexAttrib4bvARB := SDL_GL_GetProcAddress('glVertexAttrib4bvARB');
+ if not Assigned(glVertexAttrib4bvARB) then Exit;
+ @glVertexAttrib4svARB := SDL_GL_GetProcAddress('glVertexAttrib4svARB');
+ if not Assigned(glVertexAttrib4svARB) then Exit;
+ @glVertexAttrib4ivARB := SDL_GL_GetProcAddress('glVertexAttrib4ivARB');
+ if not Assigned(glVertexAttrib4ivARB) then Exit;
+ @glVertexAttrib4ubvARB := SDL_GL_GetProcAddress('glVertexAttrib4ubvARB');
+ if not Assigned(glVertexAttrib4ubvARB) then Exit;
+ @glVertexAttrib4usvARB := SDL_GL_GetProcAddress('glVertexAttrib4usvARB');
+ if not Assigned(glVertexAttrib4usvARB) then Exit;
+ @glVertexAttrib4uivARB := SDL_GL_GetProcAddress('glVertexAttrib4uivARB');
+ if not Assigned(glVertexAttrib4uivARB) then Exit;
+ @glVertexAttrib4fvARB := SDL_GL_GetProcAddress('glVertexAttrib4fvARB');
+ if not Assigned(glVertexAttrib4fvARB) then Exit;
+ @glVertexAttrib4dvARB := SDL_GL_GetProcAddress('glVertexAttrib4dvARB');
+ if not Assigned(glVertexAttrib4dvARB) then Exit;
+ @glVertexAttrib4NbvARB := SDL_GL_GetProcAddress('glVertexAttrib4NbvARB');
+ if not Assigned(glVertexAttrib4NbvARB) then Exit;
+ @glVertexAttrib4NsvARB := SDL_GL_GetProcAddress('glVertexAttrib4NsvARB');
+ if not Assigned(glVertexAttrib4NsvARB) then Exit;
+ @glVertexAttrib4NivARB := SDL_GL_GetProcAddress('glVertexAttrib4NivARB');
+ if not Assigned(glVertexAttrib4NivARB) then Exit;
+ @glVertexAttrib4NubvARB := SDL_GL_GetProcAddress('glVertexAttrib4NubvARB');
+ if not Assigned(glVertexAttrib4NubvARB) then Exit;
+ @glVertexAttrib4NusvARB := SDL_GL_GetProcAddress('glVertexAttrib4NusvARB');
+ if not Assigned(glVertexAttrib4NusvARB) then Exit;
+ @glVertexAttrib4NuivARB := SDL_GL_GetProcAddress('glVertexAttrib4NuivARB');
+ if not Assigned(glVertexAttrib4NuivARB) then Exit;
+ @glVertexAttribPointerARB := SDL_GL_GetProcAddress('glVertexAttribPointerARB');
+ if not Assigned(glVertexAttribPointerARB) then Exit;
+ @glEnableVertexAttribArrayARB := SDL_GL_GetProcAddress('glEnableVertexAttribArrayARB');
+ if not Assigned(glEnableVertexAttribArrayARB) then Exit;
+ @glDisableVertexAttribArrayARB := SDL_GL_GetProcAddress('glDisableVertexAttribArrayARB');
+ if not Assigned(glDisableVertexAttribArrayARB) then Exit;
+ @glProgramStringARB := SDL_GL_GetProcAddress('glProgramStringARB');
+ if not Assigned(glProgramStringARB) then Exit;
+ @glBindProgramARB := SDL_GL_GetProcAddress('glBindProgramARB');
+ if not Assigned(glBindProgramARB) then Exit;
+ @glDeleteProgramsARB := SDL_GL_GetProcAddress('glDeleteProgramsARB');
+ if not Assigned(glDeleteProgramsARB) then Exit;
+ @glGenProgramsARB := SDL_GL_GetProcAddress('glGenProgramsARB');
+ if not Assigned(glGenProgramsARB) then Exit;
+ @glProgramEnvParameter4dARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dARB');
+ if not Assigned(glProgramEnvParameter4dARB) then Exit;
+ @glProgramEnvParameter4dvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dvARB');
+ if not Assigned(glProgramEnvParameter4dvARB) then Exit;
+ @glProgramEnvParameter4fARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fARB');
+ if not Assigned(glProgramEnvParameter4fARB) then Exit;
+ @glProgramEnvParameter4fvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fvARB');
+ if not Assigned(glProgramEnvParameter4fvARB) then Exit;
+ @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
+ if not Assigned(glProgramLocalParameter4dARB) then Exit;
+ @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
+ if not Assigned(glProgramLocalParameter4dvARB) then Exit;
+ @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
+ if not Assigned(glProgramLocalParameter4fARB) then Exit;
+ @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
+ if not Assigned(glProgramLocalParameter4fvARB) then Exit;
+ @glGetProgramEnvParameterdvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterdvARB');
+ if not Assigned(glGetProgramEnvParameterdvARB) then Exit;
+ @glGetProgramEnvParameterfvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterfvARB');
+ if not Assigned(glGetProgramEnvParameterfvARB) then Exit;
+ @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
+ if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
+ @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
+ if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
+ @glGetProgramivARB := SDL_GL_GetProcAddress('glGetProgramivARB');
+ if not Assigned(glGetProgramivARB) then Exit;
+ @glGetProgramStringARB := SDL_GL_GetProcAddress('glGetProgramStringARB');
+ if not Assigned(glGetProgramStringARB) then Exit;
+ @glGetVertexAttribdvARB := SDL_GL_GetProcAddress('glGetVertexAttribdvARB');
+ if not Assigned(glGetVertexAttribdvARB) then Exit;
+ @glGetVertexAttribfvARB := SDL_GL_GetProcAddress('glGetVertexAttribfvARB');
+ if not Assigned(glGetVertexAttribfvARB) then Exit;
+ @glGetVertexAttribivARB := SDL_GL_GetProcAddress('glGetVertexAttribivARB');
+ if not Assigned(glGetVertexAttribivARB) then Exit;
+ @glGetVertexAttribPointervARB := SDL_GL_GetProcAddress('glGetVertexAttribPointervARB');
+ if not Assigned(glGetVertexAttribPointervARB) then Exit;
+ @glIsProgramARB := SDL_GL_GetProcAddress('glIsProgramARB');
+ if not Assigned(glIsProgramARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_window_pos: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_window_pos', extstring) then
+ begin
+ @glWindowPos2dARB := SDL_GL_GetProcAddress('glWindowPos2dARB');
+ if not Assigned(glWindowPos2dARB) then Exit;
+ @glWindowPos2fARB := SDL_GL_GetProcAddress('glWindowPos2fARB');
+ if not Assigned(glWindowPos2fARB) then Exit;
+ @glWindowPos2iARB := SDL_GL_GetProcAddress('glWindowPos2iARB');
+ if not Assigned(glWindowPos2iARB) then Exit;
+ @glWindowPos2sARB := SDL_GL_GetProcAddress('glWindowPos2sARB');
+ if not Assigned(glWindowPos2sARB) then Exit;
+ @glWindowPos2dvARB := SDL_GL_GetProcAddress('glWindowPos2dvARB');
+ if not Assigned(glWindowPos2dvARB) then Exit;
+ @glWindowPos2fvARB := SDL_GL_GetProcAddress('glWindowPos2fvARB');
+ if not Assigned(glWindowPos2fvARB) then Exit;
+ @glWindowPos2ivARB := SDL_GL_GetProcAddress('glWindowPos2ivARB');
+ if not Assigned(glWindowPos2ivARB) then Exit;
+ @glWindowPos2svARB := SDL_GL_GetProcAddress('glWindowPos2svARB');
+ if not Assigned(glWindowPos2svARB) then Exit;
+ @glWindowPos3dARB := SDL_GL_GetProcAddress('glWindowPos3dARB');
+ if not Assigned(glWindowPos3dARB) then Exit;
+ @glWindowPos3fARB := SDL_GL_GetProcAddress('glWindowPos3fARB');
+ if not Assigned(glWindowPos3fARB) then Exit;
+ @glWindowPos3iARB := SDL_GL_GetProcAddress('glWindowPos3iARB');
+ if not Assigned(glWindowPos3iARB) then Exit;
+ @glWindowPos3sARB := SDL_GL_GetProcAddress('glWindowPos3sARB');
+ if not Assigned(glWindowPos3sARB) then Exit;
+ @glWindowPos3dvARB := SDL_GL_GetProcAddress('glWindowPos3dvARB');
+ if not Assigned(glWindowPos3dvARB) then Exit;
+ @glWindowPos3fvARB := SDL_GL_GetProcAddress('glWindowPos3fvARB');
+ if not Assigned(glWindowPos3fvARB) then Exit;
+ @glWindowPos3ivARB := SDL_GL_GetProcAddress('glWindowPos3ivARB');
+ if not Assigned(glWindowPos3ivARB) then Exit;
+ @glWindowPos3svARB := SDL_GL_GetProcAddress('glWindowPos3svARB');
+ if not Assigned(glWindowPos3svARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_422_pixels: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_422_pixels', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_abgr: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_abgr', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_bgra: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_bgra', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_color: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_color', extstring) then
+ begin
+ @glBlendColorEXT := SDL_GL_GetProcAddress('glBlendColorEXT');
+ if not Assigned(glBlendColorEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_func_separate: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_func_separate', extstring) then
+ begin
+ @glBlendFuncSeparateEXT := SDL_GL_GetProcAddress('glBlendFuncSeparateEXT');
+ if not Assigned(glBlendFuncSeparateEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_logic_op: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_logic_op', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_minmax: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_minmax', extstring) then
+ begin
+ @glBlendEquationEXT := SDL_GL_GetProcAddress('glBlendEquationEXT');
+ if not Assigned(glBlendEquationEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_subtract: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_subtract', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_clip_volume_hint: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_clip_volume_hint', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_color_subtable: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_color_subtable', extstring) then
+ begin
+ @glColorSubTableEXT := SDL_GL_GetProcAddress('glColorSubTableEXT');
+ if not Assigned(glColorSubTableEXT) then Exit;
+ @glCopyColorSubTableEXT := SDL_GL_GetProcAddress('glCopyColorSubTableEXT');
+ if not Assigned(glCopyColorSubTableEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_compiled_vertex_array: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_compiled_vertex_array', extstring) then
+ begin
+ @glLockArraysEXT := SDL_GL_GetProcAddress('glLockArraysEXT');
+ if not Assigned(glLockArraysEXT) then Exit;
+ @glUnlockArraysEXT := SDL_GL_GetProcAddress('glUnlockArraysEXT');
+ if not Assigned(glUnlockArraysEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_convolution: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_convolution', extstring) then
+ begin
+ @glConvolutionFilter1DEXT := SDL_GL_GetProcAddress('glConvolutionFilter1DEXT');
+ if not Assigned(glConvolutionFilter1DEXT) then Exit;
+ @glConvolutionFilter2DEXT := SDL_GL_GetProcAddress('glConvolutionFilter2DEXT');
+ if not Assigned(glConvolutionFilter2DEXT) then Exit;
+ @glCopyConvolutionFilter1DEXT := SDL_GL_GetProcAddress('glCopyConvolutionFilter1DEXT');
+ if not Assigned(glCopyConvolutionFilter1DEXT) then Exit;
+ @glCopyConvolutionFilter2DEXT := SDL_GL_GetProcAddress('glCopyConvolutionFilter2DEXT');
+ if not Assigned(glCopyConvolutionFilter2DEXT) then Exit;
+ @glGetConvolutionFilterEXT := SDL_GL_GetProcAddress('glGetConvolutionFilterEXT');
+ if not Assigned(glGetConvolutionFilterEXT) then Exit;
+ @glSeparableFilter2DEXT := SDL_GL_GetProcAddress('glSeparableFilter2DEXT');
+ if not Assigned(glSeparableFilter2DEXT) then Exit;
+ @glGetSeparableFilterEXT := SDL_GL_GetProcAddress('glGetSeparableFilterEXT');
+ if not Assigned(glGetSeparableFilterEXT) then Exit;
+ @glConvolutionParameteriEXT := SDL_GL_GetProcAddress('glConvolutionParameteriEXT');
+ if not Assigned(glConvolutionParameteriEXT) then Exit;
+ @glConvolutionParameterivEXT := SDL_GL_GetProcAddress('glConvolutionParameterivEXT');
+ if not Assigned(glConvolutionParameterivEXT) then Exit;
+ @glConvolutionParameterfEXT := SDL_GL_GetProcAddress('glConvolutionParameterfEXT');
+ if not Assigned(glConvolutionParameterfEXT) then Exit;
+ @glConvolutionParameterfvEXT := SDL_GL_GetProcAddress('glConvolutionParameterfvEXT');
+ if not Assigned(glConvolutionParameterfvEXT) then Exit;
+ @glGetConvolutionParameterivEXT := SDL_GL_GetProcAddress('glGetConvolutionParameterivEXT');
+ if not Assigned(glGetConvolutionParameterivEXT) then Exit;
+ @glGetConvolutionParameterfvEXT := SDL_GL_GetProcAddress('glGetConvolutionParameterfvEXT');
+ if not Assigned(glGetConvolutionParameterfvEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_histogram: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_histogram', extstring) then
+ begin
+ @glHistogramEXT := SDL_GL_GetProcAddress('glHistogramEXT');
+ if not Assigned(glHistogramEXT) then Exit;
+ @glResetHistogramEXT := SDL_GL_GetProcAddress('glResetHistogramEXT');
+ if not Assigned(glResetHistogramEXT) then Exit;
+ @glGetHistogramEXT := SDL_GL_GetProcAddress('glGetHistogramEXT');
+ if not Assigned(glGetHistogramEXT) then Exit;
+ @glGetHistogramParameterivEXT := SDL_GL_GetProcAddress('glGetHistogramParameterivEXT');
+ if not Assigned(glGetHistogramParameterivEXT) then Exit;
+ @glGetHistogramParameterfvEXT := SDL_GL_GetProcAddress('glGetHistogramParameterfvEXT');
+ if not Assigned(glGetHistogramParameterfvEXT) then Exit;
+ @glMinmaxEXT := SDL_GL_GetProcAddress('glMinmaxEXT');
+ if not Assigned(glMinmaxEXT) then Exit;
+ @glResetMinmaxEXT := SDL_GL_GetProcAddress('glResetMinmaxEXT');
+ if not Assigned(glResetMinmaxEXT) then Exit;
+ @glGetMinmaxEXT := SDL_GL_GetProcAddress('glGetMinmaxEXT');
+ if not Assigned(glGetMinmaxEXT) then Exit;
+ @glGetMinmaxParameterivEXT := SDL_GL_GetProcAddress('glGetMinmaxParameterivEXT');
+ if not Assigned(glGetMinmaxParameterivEXT) then Exit;
+ @glGetMinmaxParameterfvEXT := SDL_GL_GetProcAddress('glGetMinmaxParameterfvEXT');
+ if not Assigned(glGetMinmaxParameterfvEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_multi_draw_arrays: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_multi_draw_arrays', extstring) then
+ begin
+ @glMultiDrawArraysEXT := SDL_GL_GetProcAddress('glMultiDrawArraysEXT');
+ if not Assigned(glMultiDrawArraysEXT) then Exit;
+ @glMultiDrawElementsEXT := SDL_GL_GetProcAddress('glMultiDrawElementsEXT');
+ if not Assigned(glMultiDrawElementsEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_packed_pixels: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_packed_pixels', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_paletted_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_paletted_texture', extstring) then
+ begin
+ @glColorTableEXT := SDL_GL_GetProcAddress('glColorTableEXT');
+ if not Assigned(glColorTableEXT) then Exit;
+ @glColorSubTableEXT := SDL_GL_GetProcAddress('glColorSubTableEXT');
+ if not Assigned(glColorSubTableEXT) then Exit;
+ @glGetColorTableEXT := SDL_GL_GetProcAddress('glGetColorTableEXT');
+ if not Assigned(glGetColorTableEXT) then Exit;
+ @glGetColorTableParameterivEXT := SDL_GL_GetProcAddress('glGetColorTableParameterivEXT');
+ if not Assigned(glGetColorTableParameterivEXT) then Exit;
+ @glGetColorTableParameterfvEXT := SDL_GL_GetProcAddress('glGetColorTableParameterfvEXT');
+ if not Assigned(glGetColorTableParameterfvEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_point_parameters: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_point_parameters', extstring) then
+ begin
+ @glPointParameterfEXT := SDL_GL_GetProcAddress('glPointParameterfEXT');
+ if not Assigned(glPointParameterfEXT) then Exit;
+ @glPointParameterfvEXT := SDL_GL_GetProcAddress('glPointParameterfvEXT');
+ if not Assigned(glPointParameterfvEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_polygon_offset: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_polygon_offset', extstring) then
+ begin
+ @glPolygonOffsetEXT := SDL_GL_GetProcAddress('glPolygonOffsetEXT');
+ if not Assigned(glPolygonOffsetEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_separate_specular_color: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_separate_specular_color', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_shadow_funcs: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_shadow_funcs', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_shared_texture_palette: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_shared_texture_palette', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_stencil_two_side: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_stencil_two_side', extstring) then
+ begin
+ @glActiveStencilFaceEXT := SDL_GL_GetProcAddress('glActiveStencilFaceEXT');
+ if not Assigned(glActiveStencilFaceEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_stencil_wrap: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_stencil_wrap', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_subtexture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_subtexture', extstring) then
+ begin
+ @glTexSubImage1DEXT := SDL_GL_GetProcAddress('glTexSubImage1DEXT');
+ if not Assigned(glTexSubImage1DEXT) then Exit;
+ @glTexSubImage2DEXT := SDL_GL_GetProcAddress('glTexSubImage2DEXT');
+ if not Assigned(glTexSubImage2DEXT) then Exit;
+ @glTexSubImage3DEXT := SDL_GL_GetProcAddress('glTexSubImage3DEXT');
+ if not Assigned(glTexSubImage3DEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture3D: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture3D', extstring) then
+ begin
+ glTexImage3DEXT := SDL_GL_GetProcAddress('glTexImage3DEXT');
+ if not Assigned(glTexImage3DEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_compression_s3tc: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_compression_s3tc', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_env_add: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_env_add', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_env_combine: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_env_combine', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_env_dot3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_env_dot3', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_filter_anisotropic: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_filter_anisotropic', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_lod_bias: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_lod_bias', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_object', extstring) then
+ begin
+ @glGenTexturesEXT := SDL_GL_GetProcAddress('glGenTexturesEXT');
+ if not Assigned(glGenTexturesEXT) then Exit;
+ @glDeleteTexturesEXT := SDL_GL_GetProcAddress('glDeleteTexturesEXT');
+ if not Assigned(glDeleteTexturesEXT) then Exit;
+ @glBindTextureEXT := SDL_GL_GetProcAddress('glBindTextureEXT');
+ if not Assigned(glBindTextureEXT) then Exit;
+ @glPrioritizeTexturesEXT := SDL_GL_GetProcAddress('glPrioritizeTexturesEXT');
+ if not Assigned(glPrioritizeTexturesEXT) then Exit;
+ @glAreTexturesResidentEXT := SDL_GL_GetProcAddress('glAreTexturesResidentEXT');
+ if not Assigned(glAreTexturesResidentEXT) then Exit;
+ @glIsTextureEXT := SDL_GL_GetProcAddress('glIsTextureEXT');
+ if not Assigned(glIsTextureEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_vertex_array: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_vertex_array', extstring) then
+ begin
+ @glArrayElementEXT := SDL_GL_GetProcAddress('glArrayElementEXT');
+ if not Assigned(glArrayElementEXT) then Exit;
+ @glDrawArraysEXT := SDL_GL_GetProcAddress('glDrawArraysEXT');
+ if not Assigned(glDrawArraysEXT) then Exit;
+ @glVertexPointerEXT := SDL_GL_GetProcAddress('glVertexPointerEXT');
+ if not Assigned(glVertexPointerEXT) then Exit;
+ @glNormalPointerEXT := SDL_GL_GetProcAddress('glNormalPointerEXT');
+ if not Assigned(glNormalPointerEXT) then Exit;
+ @glColorPointerEXT := SDL_GL_GetProcAddress('glColorPointerEXT');
+ if not Assigned(glColorPointerEXT) then Exit;
+ @glIndexPointerEXT := SDL_GL_GetProcAddress('glIndexPointerEXT');
+ if not Assigned(glIndexPointerEXT) then Exit;
+ @glTexCoordPointerEXT := SDL_GL_GetProcAddress('glTexCoordPointerEXT');
+ if not Assigned(glTexCoordPointerEXT) then Exit;
+ @glEdgeFlagPointerEXT := SDL_GL_GetProcAddress('glEdgeFlagPointerEXT');
+ if not Assigned(glEdgeFlagPointerEXT) then Exit;
+ @glGetPointervEXT := SDL_GL_GetProcAddress('glGetPointervEXT');
+ if not Assigned(glGetPointervEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_vertex_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_vertex_shader', extstring) then
+ begin
+ @glBeginVertexShaderEXT := SDL_GL_GetProcAddress('glBeginVertexShaderEXT');
+ if not Assigned(glBeginVertexShaderEXT) then Exit;
+ @glEndVertexShaderEXT := SDL_GL_GetProcAddress('glEndVertexShaderEXT');
+ if not Assigned(glEndVertexShaderEXT) then Exit;
+ @glBindVertexShaderEXT := SDL_GL_GetProcAddress('glBindVertexShaderEXT');
+ if not Assigned(glBindVertexShaderEXT) then Exit;
+ @glGenVertexShadersEXT := SDL_GL_GetProcAddress('glGenVertexShadersEXT');
+ if not Assigned(glGenVertexShadersEXT) then Exit;
+ @glDeleteVertexShaderEXT := SDL_GL_GetProcAddress('glDeleteVertexShaderEXT');
+ if not Assigned(glDeleteVertexShaderEXT) then Exit;
+ @glShaderOp1EXT := SDL_GL_GetProcAddress('glShaderOp1EXT');
+ if not Assigned(glShaderOp1EXT) then Exit;
+ @glShaderOp2EXT := SDL_GL_GetProcAddress('glShaderOp2EXT');
+ if not Assigned(glShaderOp2EXT) then Exit;
+ @glShaderOp3EXT := SDL_GL_GetProcAddress('glShaderOp3EXT');
+ if not Assigned(glShaderOp3EXT) then Exit;
+ @glSwizzleEXT := SDL_GL_GetProcAddress('glSwizzleEXT');
+ if not Assigned(glSwizzleEXT) then Exit;
+ @glWriteMaskEXT := SDL_GL_GetProcAddress('glWriteMaskEXT');
+ if not Assigned(glWriteMaskEXT) then Exit;
+ @glInsertComponentEXT := SDL_GL_GetProcAddress('glInsertComponentEXT');
+ if not Assigned(glInsertComponentEXT) then Exit;
+ @glExtractComponentEXT := SDL_GL_GetProcAddress('glExtractComponentEXT');
+ if not Assigned(glExtractComponentEXT) then Exit;
+ @glGenSymbolsEXT := SDL_GL_GetProcAddress('glGenSymbolsEXT');
+ if not Assigned(glGenSymbolsEXT) then Exit;
+ @glSetInvariantEXT := SDL_GL_GetProcAddress('glSetInvariantEXT');
+ if not Assigned(glSetInvariantEXT) then Exit;
+ @glSetLocalConstantEXT := SDL_GL_GetProcAddress('glSetLocalConstantEXT');
+ if not Assigned(glSetLocalConstantEXT) then Exit;
+ @glVariantbvEXT := SDL_GL_GetProcAddress('glVariantbvEXT');
+ if not Assigned(glVariantbvEXT) then Exit;
+ @glVariantsvEXT := SDL_GL_GetProcAddress('glVariantsvEXT');
+ if not Assigned(glVariantsvEXT) then Exit;
+ @glVariantivEXT := SDL_GL_GetProcAddress('glVariantivEXT');
+ if not Assigned(glVariantivEXT) then Exit;
+ @glVariantfvEXT := SDL_GL_GetProcAddress('glVariantfvEXT');
+ if not Assigned(glVariantfvEXT) then Exit;
+ @glVariantdvEXT := SDL_GL_GetProcAddress('glVariantdvEXT');
+ if not Assigned(glVariantdvEXT) then Exit;
+ @glVariantubvEXT := SDL_GL_GetProcAddress('glVariantubvEXT');
+ if not Assigned(glVariantubvEXT) then Exit;
+ @glVariantusvEXT := SDL_GL_GetProcAddress('glVariantusvEXT');
+ if not Assigned(glVariantusvEXT) then Exit;
+ @glVariantuivEXT := SDL_GL_GetProcAddress('glVariantuivEXT');
+ if not Assigned(glVariantuivEXT) then Exit;
+ @glVariantPointerEXT := SDL_GL_GetProcAddress('glVariantPointerEXT');
+ if not Assigned(glVariantPointerEXT) then Exit;
+ @glEnableVariantClientStateEXT := SDL_GL_GetProcAddress('glEnableVariantClientStateEXT');
+ if not Assigned(glEnableVariantClientStateEXT) then Exit;
+ @glDisableVariantClientStateEXT := SDL_GL_GetProcAddress('glDisableVariantClientStateEXT');
+ if not Assigned(glDisableVariantClientStateEXT) then Exit;
+ @glBindLightParameterEXT := SDL_GL_GetProcAddress('glBindLightParameterEXT');
+ if not Assigned(glBindLightParameterEXT) then Exit;
+ @glBindMaterialParameterEXT := SDL_GL_GetProcAddress('glBindMaterialParameterEXT');
+ if not Assigned(glBindMaterialParameterEXT) then Exit;
+ @glBindTexGenParameterEXT := SDL_GL_GetProcAddress('glBindTexGenParameterEXT');
+ if not Assigned(glBindTexGenParameterEXT) then Exit;
+ @glBindTextureUnitParameterEXT := SDL_GL_GetProcAddress('glBindTextureUnitParameterEXT');
+ if not Assigned(glBindTextureUnitParameterEXT) then Exit;
+ @glBindParameterEXT := SDL_GL_GetProcAddress('glBindParameterEXT');
+ if not Assigned(glBindParameterEXT) then Exit;
+ @glIsVariantEnabledEXT := SDL_GL_GetProcAddress('glIsVariantEnabledEXT');
+ if not Assigned(glIsVariantEnabledEXT) then Exit;
+ @glGetVariantBooleanvEXT := SDL_GL_GetProcAddress('glGetVariantBooleanvEXT');
+ if not Assigned(glGetVariantBooleanvEXT) then Exit;
+ @glGetVariantIntegervEXT := SDL_GL_GetProcAddress('glGetVariantIntegervEXT');
+ if not Assigned(glGetVariantIntegervEXT) then Exit;
+ @glGetVariantFloatvEXT := SDL_GL_GetProcAddress('glGetVariantFloatvEXT');
+ if not Assigned(glGetVariantFloatvEXT) then Exit;
+ @glGetVariantPointervEXT := SDL_GL_GetProcAddress('glGetVariantPointervEXT');
+ if not Assigned(glGetVariantPointervEXT) then Exit;
+ @glGetInvariantBooleanvEXT := SDL_GL_GetProcAddress('glGetInvariantBooleanvEXT');
+ if not Assigned(glGetInvariantBooleanvEXT) then Exit;
+ @glGetInvariantIntegervEXT := SDL_GL_GetProcAddress('glGetInvariantIntegervEXT');
+ if not Assigned(glGetInvariantIntegervEXT) then Exit;
+ @glGetInvariantFloatvEXT := SDL_GL_GetProcAddress('glGetInvariantFloatvEXT');
+ if not Assigned(glGetInvariantFloatvEXT) then Exit;
+ @glGetLocalConstantBooleanvEXT := SDL_GL_GetProcAddress('glGetLocalConstantBooleanvEXT');
+ if not Assigned(glGetLocalConstantBooleanvEXT) then Exit;
+ @glGetLocalConstantIntegervEXT := SDL_GL_GetProcAddress('glGetLocalConstantIntegervEXT');
+ if not Assigned(glGetLocalConstantIntegervEXT) then Exit;
+ @glGetLocalConstantFloatvEXT := SDL_GL_GetProcAddress('glGetLocalConstantFloatvEXT');
+ if not Assigned(glGetLocalConstantFloatvEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_vertex_weighting: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_vertex_weighting', extstring) then
+ begin
+ @glVertexWeightfEXT := SDL_GL_GetProcAddress('glVertexWeightfEXT');
+ if not Assigned(glVertexWeightfEXT) then Exit;
+ @glVertexWeightfvEXT := SDL_GL_GetProcAddress('glVertexWeightfvEXT');
+ if not Assigned(glVertexWeightfvEXT) then Exit;
+ @glVertexWeightPointerEXT := SDL_GL_GetProcAddress('glVertexWeightPointerEXT');
+ if not Assigned(glVertexWeightPointerEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_HP_occlusion_test: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_HP_occlusion_test', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_blend_square: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_blend_square', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_copy_depth_to_color: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_copy_depth_to_color', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_depth_clamp: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_depth_clamp', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_evaluators: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_evaluators', extstring) then
+ begin
+ @glMapControlPointsNV := SDL_GL_GetProcAddress('glMapControlPointsNV');
+ if not Assigned(glMapControlPointsNV) then Exit;
+ @glMapParameterivNV := SDL_GL_GetProcAddress('glMapParameterivNV');
+ if not Assigned(glMapParameterivNV) then Exit;
+ @glMapParameterfvNV := SDL_GL_GetProcAddress('glMapParameterfvNV');
+ if not Assigned(glMapParameterfvNV) then Exit;
+ @glGetMapControlPointsNV := SDL_GL_GetProcAddress('glGetMapControlPointsNV');
+ if not Assigned(glGetMapControlPointsNV) then Exit;
+ @glGetMapParameterivNV := SDL_GL_GetProcAddress('glGetMapParameterivNV');
+ if not Assigned(glGetMapParameterivNV) then Exit;
+ @glGetMapParameterfvNV := SDL_GL_GetProcAddress('glGetMapParameterfvNV');
+ if not Assigned(glGetMapParameterfvNV) then Exit;
+ @glGetMapAttribParameterivNV := SDL_GL_GetProcAddress('glGetMapAttribParameterivNV');
+ if not Assigned(glGetMapAttribParameterivNV) then Exit;
+ @glGetMapAttribParameterfvNV := SDL_GL_GetProcAddress('glGetMapAttribParameterfvNV');
+ if not Assigned(glGetMapAttribParameterfvNV) then Exit;
+ @glEvalMapsNV := SDL_GL_GetProcAddress('glEvalMapsNV');
+ if not Assigned(glEvalMapsNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_fence: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_fence', extstring) then
+ begin
+ @glGenFencesNV := SDL_GL_GetProcAddress('glGenFencesNV');
+ if not Assigned(glGenFencesNV) then Exit;
+ @glDeleteFencesNV := SDL_GL_GetProcAddress('glDeleteFencesNV');
+ if not Assigned(glDeleteFencesNV) then Exit;
+ @glSetFenceNV := SDL_GL_GetProcAddress('glSetFenceNV');
+ if not Assigned(glSetFenceNV) then Exit;
+ @glTestFenceNV := SDL_GL_GetProcAddress('glTestFenceNV');
+ if not Assigned(glTestFenceNV) then Exit;
+ @glFinishFenceNV := SDL_GL_GetProcAddress('glFinishFenceNV');
+ if not Assigned(glFinishFenceNV) then Exit;
+ @glIsFenceNV := SDL_GL_GetProcAddress('glIsFenceNV');
+ if not Assigned(glIsFenceNV) then Exit;
+ @glGetFenceivNV := SDL_GL_GetProcAddress('glGetFenceivNV');
+ if not Assigned(glGetFenceivNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_fog_distance: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_fog_distance', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_light_max_exponent: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_light_max_exponent', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_multisample_filter_hint: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_multisample_filter_hint', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_occlusion_query: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_occlusion_query', extstring) then
+ begin
+ @glGenOcclusionQueriesNV := SDL_GL_GetProcAddress('glGenOcclusionQueriesNV');
+ if not Assigned(glGenOcclusionQueriesNV) then Exit;
+ @glDeleteOcclusionQueriesNV := SDL_GL_GetProcAddress('glDeleteOcclusionQueriesNV');
+ if not Assigned(glDeleteOcclusionQueriesNV) then Exit;
+ @glIsOcclusionQueryNV := SDL_GL_GetProcAddress('glIsOcclusionQueryNV');
+ if not Assigned(glIsOcclusionQueryNV) then Exit;
+ @glBeginOcclusionQueryNV := SDL_GL_GetProcAddress('glBeginOcclusionQueryNV');
+ if not Assigned(glBeginOcclusionQueryNV) then Exit;
+ @glEndOcclusionQueryNV := SDL_GL_GetProcAddress('glEndOcclusionQueryNV');
+ if not Assigned(glEndOcclusionQueryNV) then Exit;
+ @glGetOcclusionQueryivNV := SDL_GL_GetProcAddress('glGetOcclusionQueryivNV');
+ if not Assigned(glGetOcclusionQueryivNV) then Exit;
+ @glGetOcclusionQueryuivNV := SDL_GL_GetProcAddress('glGetOcclusionQueryuivNV');
+ if not Assigned(glGetOcclusionQueryuivNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_packed_depth_stencil: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_packed_depth_stencil', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_point_sprite: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_point_sprite', extstring) then
+ begin
+ @glPointParameteriNV := SDL_GL_GetProcAddress('glPointParameteriNV');
+ if not Assigned(glPointParameteriNV) then Exit;
+ @glPointParameterivNV := SDL_GL_GetProcAddress('glPointParameterivNV');
+ if not Assigned(glPointParameterivNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_register_combiners: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_register_combiners', extstring) then
+ begin
+ @glCombinerParameterfvNV := SDL_GL_GetProcAddress('glCombinerParameterfvNV');
+ if not Assigned(glCombinerParameterfvNV) then Exit;
+ @glCombinerParameterivNV := SDL_GL_GetProcAddress('glCombinerParameterivNV');
+ if not Assigned(glCombinerParameterivNV) then Exit;
+ @glCombinerParameterfNV := SDL_GL_GetProcAddress('glCombinerParameterfNV');
+ if not Assigned(glCombinerParameterfNV) then Exit;
+ @glCombinerParameteriNV := SDL_GL_GetProcAddress('glCombinerParameteriNV');
+ if not Assigned(glCombinerParameteriNV) then Exit;
+ @glCombinerInputNV := SDL_GL_GetProcAddress('glCombinerInputNV');
+ if not Assigned(glCombinerInputNV) then Exit;
+ @glCombinerOutputNV := SDL_GL_GetProcAddress('glCombinerOutputNV');
+ if not Assigned(glCombinerOutputNV) then Exit;
+ @glFinalCombinerInputNV := SDL_GL_GetProcAddress('glFinalCombinerInputNV');
+ if not Assigned(glFinalCombinerInputNV) then Exit;
+ @glGetCombinerInputParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerInputParameterfvNV');
+ if not Assigned(glGetCombinerInputParameterfvNV) then Exit;
+ @glGetCombinerInputParameterivNV := SDL_GL_GetProcAddress('glGetCombinerInputParameterivNV');
+ if not Assigned(glGetCombinerInputParameterivNV) then Exit;
+ @glGetCombinerOutputParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerOutputParameterfvNV');
+ if not Assigned(glGetCombinerOutputParameterfvNV) then Exit;
+ @glGetCombinerOutputParameterivNV := SDL_GL_GetProcAddress('glGetCombinerOutputParameterivNV');
+ if not Assigned(glGetCombinerOutputParameterivNV) then Exit;
+ @glGetFinalCombinerInputParameterfvNV := SDL_GL_GetProcAddress('glGetFinalCombinerInputParameterfvNV');
+ if not Assigned(glGetFinalCombinerInputParameterfvNV) then Exit;
+ @glGetFinalCombinerInputParameterivNV := SDL_GL_GetProcAddress('glGetFinalCombinerInputParameterivNV');
+ if not Assigned(glGetFinalCombinerInputParameterivNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_register_combiners2: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_register_combiners2', extstring) then
+ begin
+ @glCombinerStageParameterfvNV := SDL_GL_GetProcAddress('glCombinerStageParameterfvNV');
+ if not Assigned(glCombinerStageParameterfvNV) then Exit;
+ @glGetCombinerStageParameterfvNV := SDL_GL_GetProcAddress('glGetCombinerStageParameterfvNV');
+ if not Assigned(glGetCombinerStageParameterfvNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texgen_emboss: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texgen_emboss', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texgen_reflection: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texgen_reflection', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_compression_vtc: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_compression_vtc', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_env_combine4: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_env_combine4', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_rectangle: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_rectangle', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_shader', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_shader2: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_shader2', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_shader3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_shader3', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_array_range: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_array_range', extstring) then
+ begin
+ @glVertexArrayRangeNV := SDL_GL_GetProcAddress('glVertexArrayRangeNV');
+ if not Assigned(glVertexArrayRangeNV) then Exit;
+ @glFlushVertexArrayRangeNV := SDL_GL_GetProcAddress('glFlushVertexArrayRangeNV');
+ if not Assigned(glFlushVertexArrayRangeNV) then Exit;
+ {$IFDEF WINDOWS}
+ @wglAllocateMemoryNV := SDL_GL_GetProcAddress('wglAllocateMemoryNV');
+ if not Assigned(wglAllocateMemoryNV) then Exit;
+ @wglFreeMemoryNV := SDL_GL_GetProcAddress('wglFreeMemoryNV');
+ if not Assigned(wglFreeMemoryNV) then Exit;
+ {$ENDIF}
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_array_range2: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_array_range2', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_program: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_program', extstring) then
+ begin
+ @glBindProgramNV := SDL_GL_GetProcAddress('glBindProgramNV');
+ if not Assigned(glBindProgramNV) then Exit;
+ @glDeleteProgramsNV := SDL_GL_GetProcAddress('glDeleteProgramsNV');
+ if not Assigned(glDeleteProgramsNV) then Exit;
+ @glExecuteProgramNV := SDL_GL_GetProcAddress('glExecuteProgramNV');
+ if not Assigned(glExecuteProgramNV) then Exit;
+ @glGenProgramsNV := SDL_GL_GetProcAddress('glGenProgramsNV');
+ if not Assigned(glGenProgramsNV) then Exit;
+ @glAreProgramsResidentNV := SDL_GL_GetProcAddress('glAreProgramsResidentNV');
+ if not Assigned(glAreProgramsResidentNV) then Exit;
+ @glRequestResidentProgramsNV := SDL_GL_GetProcAddress('glRequestResidentProgramsNV');
+ if not Assigned(glRequestResidentProgramsNV) then Exit;
+ @glGetProgramParameterfvNV := SDL_GL_GetProcAddress('glGetProgramParameterfvNV');
+ if not Assigned(glGetProgramParameterfvNV) then Exit;
+ @glGetProgramParameterdvNV := SDL_GL_GetProcAddress('glGetProgramParameterdvNV');
+ if not Assigned(glGetProgramParameterdvNV) then Exit;
+ @glGetProgramivNV := SDL_GL_GetProcAddress('glGetProgramivNV');
+ if not Assigned(glGetProgramivNV) then Exit;
+ @glGetProgramStringNV := SDL_GL_GetProcAddress('glGetProgramStringNV');
+ if not Assigned(glGetProgramStringNV) then Exit;
+ @glGetTrackMatrixivNV := SDL_GL_GetProcAddress('glGetTrackMatrixivNV');
+ if not Assigned(glGetTrackMatrixivNV) then Exit;
+ @glGetVertexAttribdvNV := SDL_GL_GetProcAddress('glGetVertexAttribdvNV');
+ if not Assigned(glGetVertexAttribdvNV) then Exit;
+ @glGetVertexAttribfvNV := SDL_GL_GetProcAddress('glGetVertexAttribfvNV');
+ if not Assigned(glGetVertexAttribfvNV) then Exit;
+ @glGetVertexAttribivNV := SDL_GL_GetProcAddress('glGetVertexAttribivNV');
+ if not Assigned(glGetVertexAttribivNV) then Exit;
+ @glGetVertexAttribPointervNV := SDL_GL_GetProcAddress('glGetVertexAttribPointervNV');
+ if not Assigned(glGetVertexAttribPointervNV) then Exit;
+ @glIsProgramNV := SDL_GL_GetProcAddress('glIsProgramNV');
+ if not Assigned(glIsProgramNV) then Exit;
+ @glLoadProgramNV := SDL_GL_GetProcAddress('glLoadProgramNV');
+ if not Assigned(glLoadProgramNV) then Exit;
+ @glProgramParameter4fNV := SDL_GL_GetProcAddress('glProgramParameter4fNV');
+ if not Assigned(glProgramParameter4fNV) then Exit;
+ @glProgramParameter4fvNV := SDL_GL_GetProcAddress('glProgramParameter4fvNV');
+ if not Assigned(glProgramParameter4fvNV) then Exit;
+ @glProgramParameters4dvNV := SDL_GL_GetProcAddress('glProgramParameters4dvNV');
+ if not Assigned(glProgramParameters4dvNV) then Exit;
+ @glProgramParameters4fvNV := SDL_GL_GetProcAddress('glProgramParameters4fvNV');
+ if not Assigned(glProgramParameters4fvNV) then Exit;
+ @glTrackMatrixNV := SDL_GL_GetProcAddress('glTrackMatrixNV');
+ if not Assigned(glTrackMatrixNV) then Exit;
+ @glVertexAttribPointerNV := SDL_GL_GetProcAddress('glVertexAttribPointerNV');
+ if not Assigned(glVertexAttribPointerNV) then Exit;
+ @glVertexAttrib1sNV := SDL_GL_GetProcAddress('glVertexAttrib1sNV');
+ if not Assigned(glVertexAttrib1sNV) then Exit;
+ @glVertexAttrib1fNV := SDL_GL_GetProcAddress('glVertexAttrib1fNV');
+ if not Assigned(glVertexAttrib1fNV) then Exit;
+ @glVertexAttrib1dNV := SDL_GL_GetProcAddress('glVertexAttrib1dNV');
+ if not Assigned(glVertexAttrib1dNV) then Exit;
+ @glVertexAttrib2sNV := SDL_GL_GetProcAddress('glVertexAttrib2sNV');
+ if not Assigned(glVertexAttrib2sNV) then Exit;
+ @glVertexAttrib2fNV := SDL_GL_GetProcAddress('glVertexAttrib2fNV');
+ if not Assigned(glVertexAttrib2fNV) then Exit;
+ @glVertexAttrib2dNV := SDL_GL_GetProcAddress('glVertexAttrib2dNV');
+ if not Assigned(glVertexAttrib2dNV) then Exit;
+ @glVertexAttrib3sNV := SDL_GL_GetProcAddress('glVertexAttrib3sNV');
+ if not Assigned(glVertexAttrib3sNV) then Exit;
+ @glVertexAttrib3fNV := SDL_GL_GetProcAddress('glVertexAttrib3fNV');
+ if not Assigned(glVertexAttrib3fNV) then Exit;
+ @glVertexAttrib3dNV := SDL_GL_GetProcAddress('glVertexAttrib3dNV');
+ if not Assigned(glVertexAttrib3dNV) then Exit;
+ @glVertexAttrib4sNV := SDL_GL_GetProcAddress('glVertexAttrib4sNV');
+ if not Assigned(glVertexAttrib4sNV) then Exit;
+ @glVertexAttrib4fNV := SDL_GL_GetProcAddress('glVertexAttrib4fNV');
+ if not Assigned(glVertexAttrib4fNV) then Exit;
+ @glVertexAttrib4dNV := SDL_GL_GetProcAddress('glVertexAttrib4dNV');
+ if not Assigned(glVertexAttrib4dNV) then Exit;
+ @glVertexAttrib4ubNV := SDL_GL_GetProcAddress('glVertexAttrib4ubNV');
+ if not Assigned(glVertexAttrib4ubNV) then Exit;
+ @glVertexAttrib1svNV := SDL_GL_GetProcAddress('glVertexAttrib1svNV');
+ if not Assigned(glVertexAttrib1svNV) then Exit;
+ @glVertexAttrib1fvNV := SDL_GL_GetProcAddress('glVertexAttrib1fvNV');
+ if not Assigned(glVertexAttrib1fvNV) then Exit;
+ @glVertexAttrib1dvNV := SDL_GL_GetProcAddress('glVertexAttrib1dvNV');
+ if not Assigned(glVertexAttrib1dvNV) then Exit;
+ @glVertexAttrib2svNV := SDL_GL_GetProcAddress('glVertexAttrib2svNV');
+ if not Assigned(glVertexAttrib2svNV) then Exit;
+ @glVertexAttrib2fvNV := SDL_GL_GetProcAddress('glVertexAttrib2fvNV');
+ if not Assigned(glVertexAttrib2fvNV) then Exit;
+ @glVertexAttrib2dvNV := SDL_GL_GetProcAddress('glVertexAttrib2dvNV');
+ if not Assigned(glVertexAttrib2dvNV) then Exit;
+ @glVertexAttrib3svNV := SDL_GL_GetProcAddress('glVertexAttrib3svNV');
+ if not Assigned(glVertexAttrib3svNV) then Exit;
+ @glVertexAttrib3fvNV := SDL_GL_GetProcAddress('glVertexAttrib3fvNV');
+ if not Assigned(glVertexAttrib3fvNV) then Exit;
+ @glVertexAttrib3dvNV := SDL_GL_GetProcAddress('glVertexAttrib3dvNV');
+ if not Assigned(glVertexAttrib3dvNV) then Exit;
+ @glVertexAttrib4svNV := SDL_GL_GetProcAddress('glVertexAttrib4svNV');
+ if not Assigned(glVertexAttrib4svNV) then Exit;
+ @glVertexAttrib4fvNV := SDL_GL_GetProcAddress('glVertexAttrib4fvNV');
+ if not Assigned(glVertexAttrib4fvNV) then Exit;
+ @glVertexAttrib4dvNV := SDL_GL_GetProcAddress('glVertexAttrib4dvNV');
+ if not Assigned(glVertexAttrib4dvNV) then Exit;
+ @glVertexAttrib4ubvNV := SDL_GL_GetProcAddress('glVertexAttrib4ubvNV');
+ if not Assigned(glVertexAttrib4ubvNV) then Exit;
+ @glVertexAttribs1svNV := SDL_GL_GetProcAddress('glVertexAttribs1svNV');
+ if not Assigned(glVertexAttribs1svNV) then Exit;
+ @glVertexAttribs1fvNV := SDL_GL_GetProcAddress('glVertexAttribs1fvNV');
+ if not Assigned(glVertexAttribs1fvNV) then Exit;
+ @glVertexAttribs1dvNV := SDL_GL_GetProcAddress('glVertexAttribs1dvNV');
+ if not Assigned(glVertexAttribs1dvNV) then Exit;
+ @glVertexAttribs2svNV := SDL_GL_GetProcAddress('glVertexAttribs2svNV');
+ if not Assigned(glVertexAttribs2svNV) then Exit;
+ @glVertexAttribs2fvNV := SDL_GL_GetProcAddress('glVertexAttribs2fvNV');
+ if not Assigned(glVertexAttribs2fvNV) then Exit;
+ @glVertexAttribs2dvNV := SDL_GL_GetProcAddress('glVertexAttribs2dvNV');
+ if not Assigned(glVertexAttribs2dvNV) then Exit;
+ @glVertexAttribs3svNV := SDL_GL_GetProcAddress('glVertexAttribs3svNV');
+ if not Assigned(glVertexAttribs3svNV) then Exit;
+ @glVertexAttribs3fvNV := SDL_GL_GetProcAddress('glVertexAttribs3fvNV');
+ if not Assigned(glVertexAttribs3fvNV) then Exit;
+ @glVertexAttribs3dvNV := SDL_GL_GetProcAddress('glVertexAttribs3dvNV');
+ if not Assigned(glVertexAttribs3dvNV) then Exit;
+ @glVertexAttribs4svNV := SDL_GL_GetProcAddress('glVertexAttribs4svNV');
+ if not Assigned(glVertexAttribs4svNV) then Exit;
+ @glVertexAttribs4fvNV := SDL_GL_GetProcAddress('glVertexAttribs4fvNV');
+ if not Assigned(glVertexAttribs4fvNV) then Exit;
+ @glVertexAttribs4dvNV := SDL_GL_GetProcAddress('glVertexAttribs4dvNV');
+ if not Assigned(glVertexAttribs4dvNV) then Exit;
+ @glVertexAttribs4ubvNV := SDL_GL_GetProcAddress('glVertexAttribs4ubvNV');
+ if not Assigned(glVertexAttribs4ubvNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_program1_1: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_program1_1', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_element_array: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_element_array', extstring) then
+ begin
+ @glElementPointerATI := SDL_GL_GetProcAddress('glElementPointerATI');
+ if not Assigned(glElementPointerATI) then Exit;
+ @glDrawElementArrayATI := SDL_GL_GetProcAddress('glDrawElementArrayATI');
+ if not Assigned(glDrawElementArrayATI) then Exit;
+ @glDrawRangeElementArrayATI := SDL_GL_GetProcAddress('glDrawRangeElementArrayATI');
+ if not Assigned(glDrawRangeElementArrayATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_envmap_bumpmap: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_envmap_bumpmap', extstring) then
+ begin
+ @glTexBumpParameterivATI := SDL_GL_GetProcAddress('glTexBumpParameterivATI');
+ if not Assigned(glTexBumpParameterivATI) then Exit;
+ @glTexBumpParameterfvATI := SDL_GL_GetProcAddress('glTexBumpParameterfvATI');
+ if not Assigned(glTexBumpParameterfvATI) then Exit;
+ @glGetTexBumpParameterivATI := SDL_GL_GetProcAddress('glGetTexBumpParameterivATI');
+ if not Assigned(glGetTexBumpParameterivATI) then Exit;
+ @glGetTexBumpParameterfvATI := SDL_GL_GetProcAddress('glGetTexBumpParameterfvATI');
+ if not Assigned(glGetTexBumpParameterfvATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_fragment_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_fragment_shader', extstring) then
+ begin
+ @glGenFragmentShadersATI := SDL_GL_GetProcAddress('glGenFragmentShadersATI');
+ if not Assigned(glGenFragmentShadersATI) then Exit;
+ @glBindFragmentShaderATI := SDL_GL_GetProcAddress('glBindFragmentShaderATI');
+ if not Assigned(glBindFragmentShaderATI) then Exit;
+ @glDeleteFragmentShaderATI := SDL_GL_GetProcAddress('glDeleteFragmentShaderATI');
+ if not Assigned(glDeleteFragmentShaderATI) then Exit;
+ @glBeginFragmentShaderATI := SDL_GL_GetProcAddress('glBeginFragmentShaderATI');
+ if not Assigned(glBeginFragmentShaderATI) then Exit;
+ @glEndFragmentShaderATI := SDL_GL_GetProcAddress('glEndFragmentShaderATI');
+ if not Assigned(glEndFragmentShaderATI) then Exit;
+ @glPassTexCoordATI := SDL_GL_GetProcAddress('glPassTexCoordATI');
+ if not Assigned(glPassTexCoordATI) then Exit;
+ @glSampleMapATI := SDL_GL_GetProcAddress('glSampleMapATI');
+ if not Assigned(glSampleMapATI) then Exit;
+ @glColorFragmentOp1ATI := SDL_GL_GetProcAddress('glColorFragmentOp1ATI');
+ if not Assigned(glColorFragmentOp1ATI) then Exit;
+ @glColorFragmentOp2ATI := SDL_GL_GetProcAddress('glColorFragmentOp2ATI');
+ if not Assigned(glColorFragmentOp2ATI) then Exit;
+ @glColorFragmentOp3ATI := SDL_GL_GetProcAddress('glColorFragmentOp3ATI');
+ if not Assigned(glColorFragmentOp3ATI) then Exit;
+ @glAlphaFragmentOp1ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp1ATI');
+ if not Assigned(glAlphaFragmentOp1ATI) then Exit;
+ @glAlphaFragmentOp2ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp2ATI');
+ if not Assigned(glAlphaFragmentOp2ATI) then Exit;
+ @glAlphaFragmentOp3ATI := SDL_GL_GetProcAddress('glAlphaFragmentOp3ATI');
+ if not Assigned(glAlphaFragmentOp3ATI) then Exit;
+ @glSetFragmentShaderConstantATI := SDL_GL_GetProcAddress('glSetFragmentShaderConstantATI');
+ if not Assigned(glSetFragmentShaderConstantATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_pn_triangles: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_pn_triangles', extstring) then
+ begin
+ @glPNTrianglesiATI := SDL_GL_GetProcAddress('glPNTrianglesiATI');
+ if not Assigned(glPNTrianglesiATI) then Exit;
+ @glPNTrianglesfATI := SDL_GL_GetProcAddress('glPNTrianglesfATI');
+ if not Assigned(glPNTrianglesfATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_texture_mirror_once: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_texture_mirror_once', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_vertex_array_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_vertex_array_object', extstring) then
+ begin
+ @glNewObjectBufferATI := SDL_GL_GetProcAddress('glNewObjectBufferATI');
+ if not Assigned(glNewObjectBufferATI) then Exit;
+ @glIsObjectBufferATI := SDL_GL_GetProcAddress('glIsObjectBufferATI');
+ if not Assigned(glIsObjectBufferATI) then Exit;
+ @glUpdateObjectBufferATI := SDL_GL_GetProcAddress('glUpdateObjectBufferATI');
+ if not Assigned(glUpdateObjectBufferATI) then Exit;
+ @glGetObjectBufferfvATI := SDL_GL_GetProcAddress('glGetObjectBufferfvATI');
+ if not Assigned(glGetObjectBufferfvATI) then Exit;
+ @glGetObjectBufferivATI := SDL_GL_GetProcAddress('glGetObjectBufferivATI');
+ if not Assigned(glGetObjectBufferivATI) then Exit;
+ @glDeleteObjectBufferATI := SDL_GL_GetProcAddress('glDeleteObjectBufferATI');
+ if not Assigned(glDeleteObjectBufferATI) then Exit;
+ @glArrayObjectATI := SDL_GL_GetProcAddress('glArrayObjectATI');
+ if not Assigned(glArrayObjectATI) then Exit;
+ @glGetArrayObjectfvATI := SDL_GL_GetProcAddress('glGetArrayObjectfvATI');
+ if not Assigned(glGetArrayObjectfvATI) then Exit;
+ @glGetArrayObjectivATI := SDL_GL_GetProcAddress('glGetArrayObjectivATI');
+ if not Assigned(glGetArrayObjectivATI) then Exit;
+ @glVariantArrayObjectATI := SDL_GL_GetProcAddress('glVariantArrayObjectATI');
+ if not Assigned(glVariantArrayObjectATI) then Exit;
+ @glGetVariantArrayObjectfvATI := SDL_GL_GetProcAddress('glGetVariantArrayObjectfvATI');
+ if not Assigned(glGetVariantArrayObjectfvATI) then Exit;
+ @glGetVariantArrayObjectivATI := SDL_GL_GetProcAddress('glGetVariantArrayObjectivATI');
+ if not Assigned(glGetVariantArrayObjectivATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_vertex_streams: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_vertex_streams', extstring) then
+ begin
+ @glVertexStream1s := SDL_GL_GetProcAddress('glVertexStream1s');
+ if not Assigned(glVertexStream1s) then Exit;
+ @glVertexStream1i := SDL_GL_GetProcAddress('glVertexStream1i');
+ if not Assigned(glVertexStream1i) then Exit;
+ @glVertexStream1f := SDL_GL_GetProcAddress('glVertexStream1f');
+ if not Assigned(glVertexStream1f) then Exit;
+ @glVertexStream1d := SDL_GL_GetProcAddress('glVertexStream1d');
+ if not Assigned(glVertexStream1d) then Exit;
+ @glVertexStream1sv := SDL_GL_GetProcAddress('glVertexStream1sv');
+ if not Assigned(glVertexStream1sv) then Exit;
+ @glVertexStream1iv := SDL_GL_GetProcAddress('glVertexStream1iv');
+ if not Assigned(glVertexStream1iv) then Exit;
+ @glVertexStream1fv := SDL_GL_GetProcAddress('glVertexStream1fv');
+ if not Assigned(glVertexStream1fv) then Exit;
+ @glVertexStream1dv := SDL_GL_GetProcAddress('glVertexStream1dv');
+ if not Assigned(glVertexStream1dv) then Exit;
+ @glVertexStream2s := SDL_GL_GetProcAddress('glVertexStream2s');
+ if not Assigned(glVertexStream2s) then Exit;
+ @glVertexStream2i := SDL_GL_GetProcAddress('glVertexStream2i');
+ if not Assigned(glVertexStream2i) then Exit;
+ @glVertexStream2f := SDL_GL_GetProcAddress('glVertexStream2f');
+ if not Assigned(glVertexStream2f) then Exit;
+ @glVertexStream2d := SDL_GL_GetProcAddress('glVertexStream2d');
+ if not Assigned(glVertexStream2d) then Exit;
+ @glVertexStream2sv := SDL_GL_GetProcAddress('glVertexStream2sv');
+ if not Assigned(glVertexStream2sv) then Exit;
+ @glVertexStream2iv := SDL_GL_GetProcAddress('glVertexStream2iv');
+ if not Assigned(glVertexStream2iv) then Exit;
+ @glVertexStream2fv := SDL_GL_GetProcAddress('glVertexStream2fv');
+ if not Assigned(glVertexStream2fv) then Exit;
+ @glVertexStream2dv := SDL_GL_GetProcAddress('glVertexStream2dv');
+ if not Assigned(glVertexStream2dv) then Exit;
+ @glVertexStream3s := SDL_GL_GetProcAddress('glVertexStream3s');
+ if not Assigned(glVertexStream3s) then Exit;
+ @glVertexStream3i := SDL_GL_GetProcAddress('glVertexStream3i');
+ if not Assigned(glVertexStream3i) then Exit;
+ @glVertexStream3f := SDL_GL_GetProcAddress('glVertexStream3f');
+ if not Assigned(glVertexStream3f) then Exit;
+ @glVertexStream3d := SDL_GL_GetProcAddress('glVertexStream3d');
+ if not Assigned(glVertexStream3d) then Exit;
+ @glVertexStream3sv := SDL_GL_GetProcAddress('glVertexStream3sv');
+ if not Assigned(glVertexStream3sv) then Exit;
+ @glVertexStream3iv := SDL_GL_GetProcAddress('glVertexStream3iv');
+ if not Assigned(glVertexStream3iv) then Exit;
+ @glVertexStream3fv := SDL_GL_GetProcAddress('glVertexStream3fv');
+ if not Assigned(glVertexStream3fv) then Exit;
+ @glVertexStream3dv := SDL_GL_GetProcAddress('glVertexStream3dv');
+ if not Assigned(glVertexStream3dv) then Exit;
+ @glVertexStream4s := SDL_GL_GetProcAddress('glVertexStream4s');
+ if not Assigned(glVertexStream4s) then Exit;
+ @glVertexStream4i := SDL_GL_GetProcAddress('glVertexStream4i');
+ if not Assigned(glVertexStream4i) then Exit;
+ @glVertexStream4f := SDL_GL_GetProcAddress('glVertexStream4f');
+ if not Assigned(glVertexStream4f) then Exit;
+ @glVertexStream4d := SDL_GL_GetProcAddress('glVertexStream4d');
+ if not Assigned(glVertexStream4d) then Exit;
+ @glVertexStream4sv := SDL_GL_GetProcAddress('glVertexStream4sv');
+ if not Assigned(glVertexStream4sv) then Exit;
+ @glVertexStream4iv := SDL_GL_GetProcAddress('glVertexStream4iv');
+ if not Assigned(glVertexStream4iv) then Exit;
+ @glVertexStream4fv := SDL_GL_GetProcAddress('glVertexStream4fv');
+ if not Assigned(glVertexStream4fv) then Exit;
+ @glVertexStream4dv := SDL_GL_GetProcAddress('glVertexStream4dv');
+ if not Assigned(glVertexStream4dv) then Exit;
+ @glNormalStream3b := SDL_GL_GetProcAddress('glNormalStream3b');
+ if not Assigned(glNormalStream3b) then Exit;
+ @glNormalStream3s := SDL_GL_GetProcAddress('glNormalStream3s');
+ if not Assigned(glNormalStream3s) then Exit;
+ @glNormalStream3i := SDL_GL_GetProcAddress('glNormalStream3i');
+ if not Assigned(glNormalStream3i) then Exit;
+ @glNormalStream3f := SDL_GL_GetProcAddress('glNormalStream3f');
+ if not Assigned(glNormalStream3f) then Exit;
+ @glNormalStream3d := SDL_GL_GetProcAddress('glNormalStream3d');
+ if not Assigned(glNormalStream3d) then Exit;
+ @glNormalStream3bv := SDL_GL_GetProcAddress('glNormalStream3bv');
+ if not Assigned(glNormalStream3bv) then Exit;
+ @glNormalStream3sv := SDL_GL_GetProcAddress('glNormalStream3sv');
+ if not Assigned(glNormalStream3sv) then Exit;
+ @glNormalStream3iv := SDL_GL_GetProcAddress('glNormalStream3iv');
+ if not Assigned(glNormalStream3iv) then Exit;
+ @glNormalStream3fv := SDL_GL_GetProcAddress('glNormalStream3fv');
+ if not Assigned(glNormalStream3fv) then Exit;
+ @glNormalStream3dv := SDL_GL_GetProcAddress('glNormalStream3dv');
+ if not Assigned(glNormalStream3dv) then Exit;
+ @glClientActiveVertexStream := SDL_GL_GetProcAddress('glClientActiveVertexStream');
+ if not Assigned(glClientActiveVertexStream) then Exit;
+ @glVertexBlendEnvi := SDL_GL_GetProcAddress('glVertexBlendEnvi');
+ if not Assigned(glVertexBlendEnvi) then Exit;
+ @glVertexBlendEnvf := SDL_GL_GetProcAddress('glVertexBlendEnvf');
+ if not Assigned(glVertexBlendEnvf) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+{$IFDEF WINDOWS}
+function Load_WGL_I3D_image_buffer: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_image_buffer', extstring) then
+ begin
+ @wglCreateImageBufferI3D := SDL_GL_GetProcAddress('wglCreateImageBufferI3D');
+ if not Assigned(wglCreateImageBufferI3D) then Exit;
+ @wglDestroyImageBufferI3D := SDL_GL_GetProcAddress('wglDestroyImageBufferI3D');
+ if not Assigned(wglDestroyImageBufferI3D) then Exit;
+ @wglAssociateImageBufferEventsI3D := SDL_GL_GetProcAddress('wglAssociateImageBufferEventsI3D');
+ if not Assigned(wglAssociateImageBufferEventsI3D) then Exit;
+ @wglReleaseImageBufferEventsI3D := SDL_GL_GetProcAddress('wglReleaseImageBufferEventsI3D');
+ if not Assigned(wglReleaseImageBufferEventsI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_I3D_swap_frame_lock: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_swap_frame_lock', extstring) then
+ begin
+ @wglEnableFrameLockI3D := SDL_GL_GetProcAddress('wglEnableFrameLockI3D');
+ if not Assigned(wglEnableFrameLockI3D) then Exit;
+ @wglDisableFrameLockI3D := SDL_GL_GetProcAddress('wglDisableFrameLockI3D');
+ if not Assigned(wglDisableFrameLockI3D) then Exit;
+ @wglIsEnabledFrameLockI3D := SDL_GL_GetProcAddress('wglIsEnabledFrameLockI3D');
+ if not Assigned(wglIsEnabledFrameLockI3D) then Exit;
+ @wglQueryFrameLockMasterI3D := SDL_GL_GetProcAddress('wglQueryFrameLockMasterI3D');
+ if not Assigned(wglQueryFrameLockMasterI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_I3D_swap_frame_usage: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_swap_frame_usage', extstring) then
+ begin
+ @wglGetFrameUsageI3D := SDL_GL_GetProcAddress('wglGetFrameUsageI3D');
+ if not Assigned(wglGetFrameUsageI3D) then Exit;
+ @wglBeginFrameTrackingI3D := SDL_GL_GetProcAddress('wglBeginFrameTrackingI3D');
+ if not Assigned(wglBeginFrameTrackingI3D) then Exit;
+ @wglEndFrameTrackingI3D := SDL_GL_GetProcAddress('wglEndFrameTrackingI3D');
+ if not Assigned(wglEndFrameTrackingI3D) then Exit;
+ @wglQueryFrameTrackingI3D := SDL_GL_GetProcAddress('wglQueryFrameTrackingI3D');
+ if not Assigned(wglQueryFrameTrackingI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+{$ENDIF}
+
+function Load_GL_3DFX_texture_compression_FXT1: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_3DFX_texture_compression_FXT1', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_IBM_cull_vertex: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_IBM_cull_vertex', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_IBM_multimode_draw_arrays: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_IBM_multimode_draw_arrays', extstring) then
+ begin
+ @glMultiModeDrawArraysIBM := SDL_GL_GetProcAddress('glMultiModeDrawArraysIBM');
+ if not Assigned(glMultiModeDrawArraysIBM) then Exit;
+ @glMultiModeDrawElementsIBM := SDL_GL_GetProcAddress('glMultiModeDrawElementsIBM');
+ if not Assigned(glMultiModeDrawElementsIBM) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_IBM_raster_pos_clip: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_IBM_raster_pos_clip', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_IBM_texture_mirrored_repeat: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_IBM_texture_mirrored_repeat', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_IBM_vertex_array_lists: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_IBM_vertex_array_lists', extstring) then
+ begin
+ @glColorPointerListIBM := SDL_GL_GetProcAddress('glColorPointerListIBM');
+ if not Assigned(glColorPointerListIBM) then Exit;
+ @glSecondaryColorPointerListIBM := SDL_GL_GetProcAddress('glSecondaryColorPointerListIBM');
+ if not Assigned(glSecondaryColorPointerListIBM) then Exit;
+ @glEdgeFlagPointerListIBM := SDL_GL_GetProcAddress('glEdgeFlagPointerListIBM');
+ if not Assigned(glEdgeFlagPointerListIBM) then Exit;
+ @glFogCoordPointerListIBM := SDL_GL_GetProcAddress('glFogCoordPointerListIBM');
+ if not Assigned(glFogCoordPointerListIBM) then Exit;
+ @glNormalPointerListIBM := SDL_GL_GetProcAddress('glNormalPointerListIBM');
+ if not Assigned(glNormalPointerListIBM) then Exit;
+ @glTexCoordPointerListIBM := SDL_GL_GetProcAddress('glTexCoordPointerListIBM');
+ if not Assigned(glTexCoordPointerListIBM) then Exit;
+ @glVertexPointerListIBM := SDL_GL_GetProcAddress('glVertexPointerListIBM');
+ if not Assigned(glVertexPointerListIBM) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_MESA_resize_buffers: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_MESA_resize_buffers', extstring) then
+ begin
+ @glResizeBuffersMESA := SDL_GL_GetProcAddress('glResizeBuffersMESA');
+ if not Assigned(glResizeBuffersMESA) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_MESA_window_pos: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_MESA_window_pos', extstring) then
+ begin
+ @glWindowPos2dMESA := SDL_GL_GetProcAddress('glWindowPos2dMESA');
+ if not Assigned(glWindowPos2dMESA) then Exit;
+ @glWindowPos2fMESA := SDL_GL_GetProcAddress('glWindowPos2fMESA');
+ if not Assigned(glWindowPos2fMESA) then Exit;
+ @glWindowPos2iMESA := SDL_GL_GetProcAddress('glWindowPos2iMESA');
+ if not Assigned(glWindowPos2iMESA) then Exit;
+ @glWindowPos2sMESA := SDL_GL_GetProcAddress('glWindowPos2sMESA');
+ if not Assigned(glWindowPos2sMESA) then Exit;
+ @glWindowPos2ivMESA := SDL_GL_GetProcAddress('glWindowPos2ivMESA');
+ if not Assigned(glWindowPos2ivMESA) then Exit;
+ @glWindowPos2svMESA := SDL_GL_GetProcAddress('glWindowPos2svMESA');
+ if not Assigned(glWindowPos2svMESA) then Exit;
+ @glWindowPos2fvMESA := SDL_GL_GetProcAddress('glWindowPos2fvMESA');
+ if not Assigned(glWindowPos2fvMESA) then Exit;
+ @glWindowPos2dvMESA := SDL_GL_GetProcAddress('glWindowPos2dvMESA');
+ if not Assigned(glWindowPos2dvMESA) then Exit;
+ @glWindowPos3iMESA := SDL_GL_GetProcAddress('glWindowPos3iMESA');
+ if not Assigned(glWindowPos3iMESA) then Exit;
+ @glWindowPos3sMESA := SDL_GL_GetProcAddress('glWindowPos3sMESA');
+ if not Assigned(glWindowPos3sMESA) then Exit;
+ @glWindowPos3fMESA := SDL_GL_GetProcAddress('glWindowPos3fMESA');
+ if not Assigned(glWindowPos3fMESA) then Exit;
+ @glWindowPos3dMESA := SDL_GL_GetProcAddress('glWindowPos3dMESA');
+ if not Assigned(glWindowPos3dMESA) then Exit;
+ @glWindowPos3ivMESA := SDL_GL_GetProcAddress('glWindowPos3ivMESA');
+ if not Assigned(glWindowPos3ivMESA) then Exit;
+ @glWindowPos3svMESA := SDL_GL_GetProcAddress('glWindowPos3svMESA');
+ if not Assigned(glWindowPos3svMESA) then Exit;
+ @glWindowPos3fvMESA := SDL_GL_GetProcAddress('glWindowPos3fvMESA');
+ if not Assigned(glWindowPos3fvMESA) then Exit;
+ @glWindowPos3dvMESA := SDL_GL_GetProcAddress('glWindowPos3dvMESA');
+ if not Assigned(glWindowPos3dvMESA) then Exit;
+ @glWindowPos4iMESA := SDL_GL_GetProcAddress('glWindowPos4iMESA');
+ if not Assigned(glWindowPos4iMESA) then Exit;
+ @glWindowPos4sMESA := SDL_GL_GetProcAddress('glWindowPos4sMESA');
+ if not Assigned(glWindowPos4sMESA) then Exit;
+ @glWindowPos4fMESA := SDL_GL_GetProcAddress('glWindowPos4fMESA');
+ if not Assigned(glWindowPos4fMESA) then Exit;
+ @glWindowPos4dMESA := SDL_GL_GetProcAddress('glWindowPos4dMESA');
+ if not Assigned(glWindowPos4dMESA) then Exit;
+ @glWindowPos4ivMESA := SDL_GL_GetProcAddress('glWindowPos4ivMESA');
+ if not Assigned(glWindowPos4ivMESA) then Exit;
+ @glWindowPos4svMESA := SDL_GL_GetProcAddress('glWindowPos4svMESA');
+ if not Assigned(glWindowPos4svMESA) then Exit;
+ @glWindowPos4fvMESA := SDL_GL_GetProcAddress('glWindowPos4fvMESA');
+ if not Assigned(glWindowPos4fvMESA) then Exit;
+ @glWindowPos4dvMESA := SDL_GL_GetProcAddress('glWindowPos4dvMESA');
+ if not Assigned(glWindowPos4dvMESA) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_OML_interlace: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_OML_interlace', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_OML_resample: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_OML_resample', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_OML_subsample: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_OML_subsample', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_generate_mipmap: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_generate_mipmap', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_multisample: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_multisample', extstring) then
+ begin
+ @glSampleMaskSGIS := SDL_GL_GetProcAddress('glSampleMaskSGIS');
+ if not Assigned(glSampleMaskSGIS) then Exit;
+ @glSamplePatternSGIS := SDL_GL_GetProcAddress('glSamplePatternSGIS');
+ if not Assigned(glSamplePatternSGIS) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_pixel_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_pixel_texture', extstring) then
+ begin
+ @glPixelTexGenParameteriSGIS := SDL_GL_GetProcAddress('glPixelTexGenParameteriSGIS');
+ if not Assigned(glPixelTexGenParameteriSGIS) then Exit;
+ @glPixelTexGenParameterfSGIS := SDL_GL_GetProcAddress('glPixelTexGenParameterfSGIS');
+ if not Assigned(glPixelTexGenParameterfSGIS) then Exit;
+ @glGetPixelTexGenParameterivSGIS := SDL_GL_GetProcAddress('glGetPixelTexGenParameterivSGIS');
+ if not Assigned(glGetPixelTexGenParameterivSGIS) then Exit;
+ @glGetPixelTexGenParameterfvSGIS := SDL_GL_GetProcAddress('glGetPixelTexGenParameterfvSGIS');
+ if not Assigned(glGetPixelTexGenParameterfvSGIS) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_texture_border_clamp: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_texture_border_clamp', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_texture_color_mask: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_texture_color_mask', extstring) then
+ begin
+ @glTextureColorMaskSGIS := SDL_GL_GetProcAddress('glTextureColorMaskSGIS');
+ if not Assigned(glTextureColorMaskSGIS) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_texture_edge_clamp: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_texture_edge_clamp', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_texture_lod: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_texture_lod', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIS_depth_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIS_depth_texture', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIX_fog_offset: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIX_fog_offset', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIX_interlace: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIX_interlace', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGIX_shadow_ambient: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGIX_shadow_ambient', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGI_color_matrix: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGI_color_matrix', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGI_color_table: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGI_color_table', extstring) then
+ begin
+ @glColorTableSGI := SDL_GL_GetProcAddress('glColorTableSGI');
+ if not Assigned(glColorTableSGI) then Exit;
+ @glCopyColorTableSGI := SDL_GL_GetProcAddress('glCopyColorTableSGI');
+ if not Assigned(glCopyColorTableSGI) then Exit;
+ @glColorTableParameterivSGI := SDL_GL_GetProcAddress('glColorTableParameterivSGI');
+ if not Assigned(glColorTableParameterivSGI) then Exit;
+ @glColorTableParameterfvSGI := SDL_GL_GetProcAddress('glColorTableParameterfvSGI');
+ if not Assigned(glColorTableParameterfvSGI) then Exit;
+ @glGetColorTableSGI := SDL_GL_GetProcAddress('glGetColorTableSGI');
+ if not Assigned(glGetColorTableSGI) then Exit;
+ @glGetColorTableParameterivSGI := SDL_GL_GetProcAddress('glGetColorTableParameterivSGI');
+ if not Assigned(glGetColorTableParameterivSGI) then Exit;
+ @glGetColorTableParameterfvSGI := SDL_GL_GetProcAddress('glGetColorTableParameterfvSGI');
+ if not Assigned(glGetColorTableParameterfvSGI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SGI_texture_color_table: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SGI_texture_color_table', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_SUN_vertex: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_SUN_vertex', extstring) then
+ begin
+ @glColor4ubVertex2fSUN := SDL_GL_GetProcAddress('glColor4ubVertex2fSUN');
+ if not Assigned(glColor4ubVertex2fSUN) then Exit;
+ @glColor4ubVertex2fvSUN := SDL_GL_GetProcAddress('glColor4ubVertex2fvSUN');
+ if not Assigned(glColor4ubVertex2fvSUN) then Exit;
+ @glColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glColor4ubVertex3fSUN');
+ if not Assigned(glColor4ubVertex3fSUN) then Exit;
+ @glColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glColor4ubVertex3fvSUN');
+ if not Assigned(glColor4ubVertex3fvSUN) then Exit;
+ @glColor3fVertex3fSUN := SDL_GL_GetProcAddress('glColor3fVertex3fSUN');
+ if not Assigned(glColor3fVertex3fSUN) then Exit;
+ @glColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glColor3fVertex3fvSUN');
+ if not Assigned(glColor3fVertex3fvSUN) then Exit;
+ @glNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glNormal3fVertex3fSUN');
+ if not Assigned(glNormal3fVertex3fSUN) then Exit;
+ @glNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glNormal3fVertex3fvSUN');
+ if not Assigned(glNormal3fVertex3fvSUN) then Exit;
+ @glColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glColor4fNormal3fVertex3fSUN');
+ if not Assigned(glColor4fNormal3fVertex3fSUN) then Exit;
+ @glColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glColor4fNormal3fVertex3fvSUN');
+ if not Assigned(glColor4fNormal3fVertex3fvSUN) then Exit;
+ @glTexCoord2fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fVertex3fSUN');
+ if not Assigned(glTexCoord2fVertex3fSUN) then Exit;
+ @glTexCoord2fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fVertex3fvSUN');
+ if not Assigned(glTexCoord2fVertex3fvSUN) then Exit;
+ @glTexCoord4fVertex4fSUN := SDL_GL_GetProcAddress('glTexCoord4fVertex4fSUN');
+ if not Assigned(glTexCoord4fVertex4fSUN) then Exit;
+ @glTexCoord4fVertex4fvSUN := SDL_GL_GetProcAddress('glTexCoord4fVertex4fvSUN');
+ if not Assigned(glTexCoord4fVertex4fvSUN) then Exit;
+ @glTexCoord2fColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4ubVertex3fSUN');
+ if not Assigned(glTexCoord2fColor4ubVertex3fSUN) then Exit;
+ @glTexCoord2fColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4ubVertex3fvSUN');
+ if not Assigned(glTexCoord2fColor4ubVertex3fvSUN) then Exit;
+ @glTexCoord2fColor3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor3fVertex3fSUN');
+ if not Assigned(glTexCoord2fColor3fVertex3fSUN) then Exit;
+ @glTexCoord2fColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor3fVertex3fvSUN');
+ if not Assigned(glTexCoord2fColor3fVertex3fvSUN) then Exit;
+ @glTexCoord2fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fNormal3fVertex3fSUN');
+ if not Assigned(glTexCoord2fNormal3fVertex3fSUN) then Exit;
+ @glTexCoord2fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fNormal3fVertex3fvSUN');
+ if not Assigned(glTexCoord2fNormal3fVertex3fvSUN) then Exit;
+ @glTexCoord2fColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4fNormal3fVertex3fSUN');
+ if not Assigned(glTexCoord2fColor4fNormal3fVertex3fSUN) then Exit;
+ @glTexCoord2fColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glTexCoord2fColor4fNormal3fVertex3fvSUN');
+ if not Assigned(glTexCoord2fColor4fNormal3fVertex3fvSUN) then Exit;
+ @glTexCoord4fColor4fNormal3fVertex4fSUN := SDL_GL_GetProcAddress('glTexCoord4fColor4fNormal3fVertex4fSUN');
+ if not Assigned(glTexCoord4fColor4fNormal3fVertex4fSUN) then Exit;
+ @glTexCoord4fColor4fNormal3fVertex4fvSUN := SDL_GL_GetProcAddress('glTexCoord4fColor4fNormal3fVertex4fvSUN');
+ if not Assigned(glTexCoord4fColor4fNormal3fVertex4fvSUN) then Exit;
+ @glReplacementCodeuiVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiVertex3fSUN');
+ if not Assigned(glReplacementCodeuiVertex3fSUN) then Exit;
+ @glReplacementCodeuiVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiVertex3fvSUN) then Exit;
+ @glReplacementCodeuiColor4ubVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4ubVertex3fSUN');
+ if not Assigned(glReplacementCodeuiColor4ubVertex3fSUN) then Exit;
+ @glReplacementCodeuiColor4ubVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4ubVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiColor4ubVertex3fvSUN) then Exit;
+ @glReplacementCodeuiColor3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor3fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiColor3fVertex3fSUN) then Exit;
+ @glReplacementCodeuiColor3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor3fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiColor3fVertex3fvSUN) then Exit;
+ @glReplacementCodeuiNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiNormal3fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiNormal3fVertex3fSUN) then Exit;
+ @glReplacementCodeuiNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiNormal3fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiNormal3fVertex3fvSUN) then Exit;
+ @glReplacementCodeuiColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiColor4fNormal3fVertex3fSUN) then Exit;
+ @glReplacementCodeuiColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiColor4fNormal3fVertex3fvSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fVertex3fSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fVertex3fvSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) then Exit;
+ @glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN := SDL_GL_GetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN');
+ if not Assigned(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_fragment_program: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_fragment_program', extstring) then
+ begin
+ @glProgramStringARB := SDL_GL_GetProcAddress('glProgramStringARB');
+ if not Assigned(glProgramStringARB) then Exit;
+ @glBindProgramARB := SDL_GL_GetProcAddress('glBindProgramARB');
+ if not Assigned(glBindProgramARB) then Exit;
+ @glDeleteProgramsARB := SDL_GL_GetProcAddress('glDeleteProgramsARB');
+ if not Assigned(glDeleteProgramsARB) then Exit;
+ @glGenProgramsARB := SDL_GL_GetProcAddress('glGenProgramsARB');
+ if not Assigned(glGenProgramsARB) then Exit;
+ @glProgramEnvParameter4dARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dARB');
+ if not Assigned(glProgramEnvParameter4dARB) then Exit;
+ @glProgramEnvParameter4dvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4dvARB');
+ if not Assigned(glProgramEnvParameter4dvARB) then Exit;
+ @glProgramEnvParameter4fARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fARB');
+ if not Assigned(glProgramEnvParameter4fARB) then Exit;
+ @glProgramEnvParameter4fvARB := SDL_GL_GetProcAddress('glProgramEnvParameter4fvARB');
+ if not Assigned(glProgramEnvParameter4fvARB) then Exit;
+ @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
+ if not Assigned(glProgramLocalParameter4dARB) then Exit;
+ @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
+ if not Assigned(glProgramLocalParameter4dvARB) then Exit;
+ @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
+ if not Assigned(glProgramLocalParameter4fARB) then Exit;
+ @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
+ if not Assigned(glProgramLocalParameter4fvARB) then Exit;
+ @glGetProgramEnvParameterdvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterdvARB');
+ if not Assigned(glGetProgramEnvParameterdvARB) then Exit;
+ @glGetProgramEnvParameterfvARB := SDL_GL_GetProcAddress('glGetProgramEnvParameterfvARB');
+ if not Assigned(glGetProgramEnvParameterfvARB) then Exit;
+ @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
+ if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
+ @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
+ if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
+ @glGetProgramivARB := SDL_GL_GetProcAddress('glGetProgramivARB');
+ if not Assigned(glGetProgramivARB) then Exit;
+ @glGetProgramStringARB := SDL_GL_GetProcAddress('glGetProgramStringARB');
+ if not Assigned(glGetProgramStringARB) then Exit;
+ @glIsProgramARB := SDL_GL_GetProcAddress('glIsProgramARB');
+ if not Assigned(glIsProgramARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_text_fragment_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_text_fragment_shader', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_APPLE_client_storage: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_APPLE_client_storage', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_APPLE_element_array: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_APPLE_element_array', extstring) then
+ begin
+ @glElementPointerAPPLE := SDL_GL_GetProcAddress('glElementPointerAPPLE');
+ if not Assigned(glElementPointerAPPLE) then Exit;
+ @glDrawElementArrayAPPLE := SDL_GL_GetProcAddress('glDrawElementArrayAPPLE');
+ if not Assigned(glDrawElementArrayAPPLE) then Exit;
+ @glDrawRangeElementArrayAPPLE := SDL_GL_GetProcAddress('glDrawRangeElementArrayAPPLE');
+ if not Assigned(glDrawRangeElementArrayAPPLE) then Exit;
+ @glMultiDrawElementArrayAPPLE := SDL_GL_GetProcAddress('glMultiDrawElementArrayAPPLE');
+ if not Assigned(glMultiDrawElementArrayAPPLE) then Exit;
+ @glMultiDrawRangeElementArrayAPPLE := SDL_GL_GetProcAddress('glMultiDrawRangeElementArrayAPPLE');
+ if not Assigned(glMultiDrawRangeElementArrayAPPLE) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_APPLE_fence: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_APPLE_fence', extstring) then
+ begin
+ @glGenFencesAPPLE := SDL_GL_GetProcAddress('glGenFencesAPPLE');
+ if not Assigned(glGenFencesAPPLE) then Exit;
+ @glDeleteFencesAPPLE := SDL_GL_GetProcAddress('glDeleteFencesAPPLE');
+ if not Assigned(glDeleteFencesAPPLE) then Exit;
+ @glSetFenceAPPLE := SDL_GL_GetProcAddress('glSetFenceAPPLE');
+ if not Assigned(glSetFenceAPPLE) then Exit;
+ @glIsFenceAPPLE := SDL_GL_GetProcAddress('glIsFenceAPPLE');
+ if not Assigned(glIsFenceAPPLE) then Exit;
+ @glTestFenceAPPLE := SDL_GL_GetProcAddress('glTestFenceAPPLE');
+ if not Assigned(glTestFenceAPPLE) then Exit;
+ @glFinishFenceAPPLE := SDL_GL_GetProcAddress('glFinishFenceAPPLE');
+ if not Assigned(glFinishFenceAPPLE) then Exit;
+ @glTestObjectAPPLE := SDL_GL_GetProcAddress('glTestObjectAPPLE');
+ if not Assigned(glTestObjectAPPLE) then Exit;
+ @glFinishObjectAPPLE := SDL_GL_GetProcAddress('glFinishObjectAPPLE');
+ if not Assigned(glFinishObjectAPPLE) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_APPLE_vertex_array_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_APPLE_vertex_array_object', extstring) then
+ begin
+ @glBindVertexArrayAPPLE := SDL_GL_GetProcAddress('glBindVertexArrayAPPLE');
+ if not Assigned(glBindVertexArrayAPPLE) then Exit;
+ @glDeleteVertexArraysAPPLE := SDL_GL_GetProcAddress('glDeleteVertexArraysAPPLE');
+ if not Assigned(glDeleteVertexArraysAPPLE) then Exit;
+ @glGenVertexArraysAPPLE := SDL_GL_GetProcAddress('glGenVertexArraysAPPLE');
+ if not Assigned(glGenVertexArraysAPPLE) then Exit;
+ @glIsVertexArrayAPPLE := SDL_GL_GetProcAddress('glIsVertexArrayAPPLE');
+ if not Assigned(glIsVertexArrayAPPLE) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_APPLE_vertex_array_range: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_APPLE_vertex_array_range', extstring) then
+ begin
+ @glVertexArrayRangeAPPLE := SDL_GL_GetProcAddress('glVertexArrayRangeAPPLE');
+ if not Assigned(glVertexArrayRangeAPPLE) then Exit;
+ @glFlushVertexArrayRangeAPPLE := SDL_GL_GetProcAddress('glFlushVertexArrayRangeAPPLE');
+ if not Assigned(glFlushVertexArrayRangeAPPLE) then Exit;
+ @glVertexArrayParameteriAPPLE := SDL_GL_GetProcAddress('glVertexArrayParameteriAPPLE');
+ if not Assigned(glVertexArrayParameteriAPPLE) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+{$IFDEF WINDOWS}
+function Load_WGL_ARB_pixel_format: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_pixel_format', extstring) then
+ begin
+ @wglGetPixelFormatAttribivARB := SDL_GL_GetProcAddress('wglGetPixelFormatAttribivARB');
+ if not Assigned(wglGetPixelFormatAttribivARB) then Exit;
+ @wglGetPixelFormatAttribfvARB := SDL_GL_GetProcAddress('wglGetPixelFormatAttribfvARB');
+ if not Assigned(wglGetPixelFormatAttribfvARB) then Exit;
+ @wglChoosePixelFormatARB := SDL_GL_GetProcAddress('wglChoosePixelFormatARB');
+ if not Assigned(wglChoosePixelFormatARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_ARB_make_current_read: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_make_current_read', extstring) then
+ begin
+ @wglMakeContextCurrentARB := SDL_GL_GetProcAddress('wglMakeContextCurrentARB');
+ if not Assigned(wglMakeContextCurrentARB) then Exit;
+ @wglGetCurrentReadDCARB := SDL_GL_GetProcAddress('wglGetCurrentReadDCARB');
+ if not Assigned(wglGetCurrentReadDCARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_ARB_pbuffer: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_pbuffer', extstring) then
+ begin
+ @wglCreatePbufferARB := SDL_GL_GetProcAddress('wglCreatePbufferARB');
+ if not Assigned(wglCreatePbufferARB) then Exit;
+ @wglGetPbufferDCARB := SDL_GL_GetProcAddress('wglGetPbufferDCARB');
+ if not Assigned(wglGetPbufferDCARB) then Exit;
+ @wglReleasePbufferDCARB := SDL_GL_GetProcAddress('wglReleasePbufferDCARB');
+ if not Assigned(wglReleasePbufferDCARB) then Exit;
+ @wglDestroyPbufferARB := SDL_GL_GetProcAddress('wglDestroyPbufferARB');
+ if not Assigned(wglDestroyPbufferARB) then Exit;
+ @wglQueryPbufferARB := SDL_GL_GetProcAddress('wglQueryPbufferARB');
+ if not Assigned(wglQueryPbufferARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_EXT_swap_control: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_EXT_swap_control', extstring) then
+ begin
+ @wglSwapIntervalEXT := SDL_GL_GetProcAddress('wglSwapIntervalEXT');
+ if not Assigned(wglSwapIntervalEXT) then Exit;
+ @wglGetSwapIntervalEXT := SDL_GL_GetProcAddress('wglGetSwapIntervalEXT');
+ if not Assigned(wglGetSwapIntervalEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_ARB_render_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ARB_render_texture', extstring) then
+ begin
+ @wglBindTexImageARB := SDL_GL_GetProcAddress('wglBindTexImageARB');
+ if not Assigned(wglBindTexImageARB) then Exit;
+ @wglReleaseTexImageARB := SDL_GL_GetProcAddress('wglReleaseTexImageARB');
+ if not Assigned(wglReleaseTexImageARB) then Exit;
+ @wglSetPbufferAttribARB := SDL_GL_GetProcAddress('wglSetPbufferAttribARB');
+ if not Assigned(wglSetPbufferAttribARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_EXT_extensions_string: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_EXT_extensions_string', extstring) then
+ begin
+ @wglGetExtensionsStringEXT := SDL_GL_GetProcAddress('wglGetExtensionsStringEXT');
+ if not Assigned(wglGetExtensionsStringEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_EXT_make_current_read: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_EXT_make_current_read', extstring) then
+ begin
+ @wglMakeContextCurrentEXT := SDL_GL_GetProcAddress('wglMakeContextCurrentEXT');
+ if not Assigned(wglMakeContextCurrentEXT) then Exit;
+ @wglGetCurrentReadDCEXT := SDL_GL_GetProcAddress('wglGetCurrentReadDCEXT');
+ if not Assigned(wglGetCurrentReadDCEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_EXT_pbuffer: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_EXT_pbuffer', extstring) then
+ begin
+ @wglCreatePbufferEXT := SDL_GL_GetProcAddress('wglCreatePbufferEXT');
+ if not Assigned(wglCreatePbufferEXT) then Exit;
+ @wglGetPbufferDCEXT := SDL_GL_GetProcAddress('wglGetPbufferDCEXT');
+ if not Assigned(wglGetPbufferDCEXT) then Exit;
+ @wglReleasePbufferDCEXT := SDL_GL_GetProcAddress('wglReleasePbufferDCEXT');
+ if not Assigned(wglReleasePbufferDCEXT) then Exit;
+ @wglDestroyPbufferEXT := SDL_GL_GetProcAddress('wglDestroyPbufferEXT');
+ if not Assigned(wglDestroyPbufferEXT) then Exit;
+ @wglQueryPbufferEXT := SDL_GL_GetProcAddress('wglQueryPbufferEXT');
+ if not Assigned(wglQueryPbufferEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_EXT_pixel_format: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_EXT_pixel_format', extstring) then
+ begin
+ @wglGetPixelFormatAttribivEXT := SDL_GL_GetProcAddress('wglGetPixelFormatAttribivEXT');
+ if not Assigned(wglGetPixelFormatAttribivEXT) then Exit;
+ @wglGetPixelFormatAttribfvEXT := SDL_GL_GetProcAddress('wglGetPixelFormatAttribfvEXT');
+ if not Assigned(wglGetPixelFormatAttribfvEXT) then Exit;
+ @wglChoosePixelFormatEXT := SDL_GL_GetProcAddress('wglChoosePixelFormatEXT');
+ if not Assigned(wglChoosePixelFormatEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_I3D_digital_video_control: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_digital_video_control', extstring) then
+ begin
+ @wglGetDigitalVideoParametersI3D := SDL_GL_GetProcAddress('wglGetDigitalVideoParametersI3D');
+ if not Assigned(wglGetDigitalVideoParametersI3D) then Exit;
+ @wglSetDigitalVideoParametersI3D := SDL_GL_GetProcAddress('wglSetDigitalVideoParametersI3D');
+ if not Assigned(wglSetDigitalVideoParametersI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_I3D_gamma: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_gamma', extstring) then
+ begin
+ @wglGetGammaTableParametersI3D := SDL_GL_GetProcAddress('wglGetGammaTableParametersI3D');
+ if not Assigned(wglGetGammaTableParametersI3D) then Exit;
+ @wglSetGammaTableParametersI3D := SDL_GL_GetProcAddress('wglSetGammaTableParametersI3D');
+ if not Assigned(wglSetGammaTableParametersI3D) then Exit;
+ @wglGetGammaTableI3D := SDL_GL_GetProcAddress('wglGetGammaTableI3D');
+ if not Assigned(wglGetGammaTableI3D) then Exit;
+ @wglSetGammaTableI3D := SDL_GL_GetProcAddress('wglSetGammaTableI3D');
+ if not Assigned(wglSetGammaTableI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_WGL_I3D_genlock: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_I3D_genlock', extstring) then
+ begin
+ @wglEnableGenlockI3D := SDL_GL_GetProcAddress('wglEnableGenlockI3D');
+ if not Assigned(wglEnableGenlockI3D) then Exit;
+ @wglDisableGenlockI3D := SDL_GL_GetProcAddress('wglDisableGenlockI3D');
+ if not Assigned(wglDisableGenlockI3D) then Exit;
+ @wglIsEnabledGenlockI3D := SDL_GL_GetProcAddress('wglIsEnabledGenlockI3D');
+ if not Assigned(wglIsEnabledGenlockI3D) then Exit;
+ @wglGenlockSourceI3D := SDL_GL_GetProcAddress('wglGenlockSourceI3D');
+ if not Assigned(wglGenlockSourceI3D) then Exit;
+ @wglGetGenlockSourceI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceI3D');
+ if not Assigned(wglGetGenlockSourceI3D) then Exit;
+ @wglGenlockSourceEdgeI3D := SDL_GL_GetProcAddress('wglGenlockSourceEdgeI3D');
+ if not Assigned(wglGenlockSourceEdgeI3D) then Exit;
+ @wglGetGenlockSourceEdgeI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceEdgeI3D');
+ if not Assigned(wglGetGenlockSourceEdgeI3D) then Exit;
+ @wglGenlockSampleRateI3D := SDL_GL_GetProcAddress('wglGenlockSampleRateI3D');
+ if not Assigned(wglGenlockSampleRateI3D) then Exit;
+ @wglGetGenlockSampleRateI3D := SDL_GL_GetProcAddress('wglGetGenlockSampleRateI3D');
+ if not Assigned(wglGetGenlockSampleRateI3D) then Exit;
+ @wglGenlockSourceDelayI3D := SDL_GL_GetProcAddress('wglGenlockSourceDelayI3D');
+ if not Assigned(wglGenlockSourceDelayI3D) then Exit;
+ @wglGetGenlockSourceDelayI3D := SDL_GL_GetProcAddress('wglGetGenlockSourceDelayI3D');
+ if not Assigned(wglGetGenlockSourceDelayI3D) then Exit;
+ @wglQueryGenlockMaxSourceDelayI3D := SDL_GL_GetProcAddress('wglQueryGenlockMaxSourceDelayI3D');
+ if not Assigned(wglQueryGenlockMaxSourceDelayI3D) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+{$ENDIF}
+
+function Load_GL_ARB_matrix_palette: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_matrix_palette', extstring) then
+ begin
+ @glCurrentPaletteMatrixARB := SDL_GL_GetProcAddress('glCurrentPaletteMatrixARB');
+ if not Assigned(glCurrentPaletteMatrixARB) then Exit;
+ @glMatrixIndexubvARB := SDL_GL_GetProcAddress('glMatrixIndexubvARB');
+ if not Assigned(glMatrixIndexubvARB) then Exit;
+ @glMatrixIndexusvARB := SDL_GL_GetProcAddress('glMatrixIndexusvARB');
+ if not Assigned(glMatrixIndexusvARB) then Exit;
+ @glMatrixIndexuivARB := SDL_GL_GetProcAddress('glMatrixIndexuivARB');
+ if not Assigned(glMatrixIndexuivARB) then Exit;
+ @glMatrixIndexPointerARB := SDL_GL_GetProcAddress('glMatrixIndexPointerARB');
+ if not Assigned(glMatrixIndexPointerARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_element_array: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_element_array', extstring) then
+ begin
+ @glElementPointerNV := SDL_GL_GetProcAddress('glElementPointerNV');
+ if not Assigned(glElementPointerNV) then Exit;
+ @glDrawElementArrayNV := SDL_GL_GetProcAddress('glDrawElementArrayNV');
+ if not Assigned(glDrawElementArrayNV) then Exit;
+ @glDrawRangeElementArrayNV := SDL_GL_GetProcAddress('glDrawRangeElementArrayNV');
+ if not Assigned(glDrawRangeElementArrayNV) then Exit;
+ @glMultiDrawElementArrayNV := SDL_GL_GetProcAddress('glMultiDrawElementArrayNV');
+ if not Assigned(glMultiDrawElementArrayNV) then Exit;
+ @glMultiDrawRangeElementArrayNV := SDL_GL_GetProcAddress('glMultiDrawRangeElementArrayNV');
+ if not Assigned(glMultiDrawRangeElementArrayNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_float_buffer: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_float_buffer', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_fragment_program: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_fragment_program', extstring) then
+ begin
+ @glProgramNamedParameter4fNV := SDL_GL_GetProcAddress('glProgramNamedParameter4fNV');
+ if not Assigned(glProgramNamedParameter4fNV) then Exit;
+ @glProgramNamedParameter4dNV := SDL_GL_GetProcAddress('glProgramNamedParameter4dNV');
+ if not Assigned(glProgramNamedParameter4dNV) then Exit;
+ @glGetProgramNamedParameterfvNV := SDL_GL_GetProcAddress('glGetProgramNamedParameterfvNV');
+ if not Assigned(glGetProgramNamedParameterfvNV) then Exit;
+ @glGetProgramNamedParameterdvNV := SDL_GL_GetProcAddress('glGetProgramNamedParameterdvNV');
+ if not Assigned(glGetProgramNamedParameterdvNV) then Exit;
+ @glProgramLocalParameter4dARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dARB');
+ if not Assigned(glProgramLocalParameter4dARB) then Exit;
+ @glProgramLocalParameter4dvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4dvARB');
+ if not Assigned(glProgramLocalParameter4dvARB) then Exit;
+ @glProgramLocalParameter4fARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fARB');
+ if not Assigned(glProgramLocalParameter4fARB) then Exit;
+ @glProgramLocalParameter4fvARB := SDL_GL_GetProcAddress('glProgramLocalParameter4fvARB');
+ if not Assigned(glProgramLocalParameter4fvARB) then Exit;
+ @glGetProgramLocalParameterdvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterdvARB');
+ if not Assigned(glGetProgramLocalParameterdvARB) then Exit;
+ @glGetProgramLocalParameterfvARB := SDL_GL_GetProcAddress('glGetProgramLocalParameterfvARB');
+ if not Assigned(glGetProgramLocalParameterfvARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_primitive_restart: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_primitive_restart', extstring) then
+ begin
+ @glPrimitiveRestartNV := SDL_GL_GetProcAddress('glPrimitiveRestartNV');
+ if not Assigned(glPrimitiveRestartNV) then Exit;
+ @glPrimitiveRestartIndexNV := SDL_GL_GetProcAddress('glPrimitiveRestartIndexNV');
+ if not Assigned(glPrimitiveRestartIndexNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_program2: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_program2', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+{$IFDEF WINDOWS}
+function Load_WGL_NV_render_texture_rectangle: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_NV_render_texture_rectangle', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+{$ENDIF}
+
+function Load_GL_NV_pixel_data_range: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_pixel_data_range', extstring) then
+ begin
+ @glPixelDataRangeNV := SDL_GL_GetProcAddress('glPixelDataRangeNV');
+ if not Assigned(glPixelDataRangeNV) then Exit;
+ @glFlushPixelDataRangeNV := SDL_GL_GetProcAddress('glFlushPixelDataRangeNV');
+ if not Assigned(glFlushPixelDataRangeNV) then Exit;
+ {$IFDEF WINDOWS}
+ @wglAllocateMemoryNV := SDL_GL_GetProcAddress('wglAllocateMemoryNV');
+ if not Assigned(wglAllocateMemoryNV) then Exit;
+ @wglFreeMemoryNV := SDL_GL_GetProcAddress('wglFreeMemoryNV');
+ if not Assigned(wglFreeMemoryNV) then Exit;
+ {$ENDIF}
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_rectangle: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_rectangle', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_S3_s3tc: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_S3_s3tc', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_draw_buffers: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_draw_buffers', extstring) then
+ begin
+ @glDrawBuffersATI := SDL_GL_GetProcAddress('glDrawBuffersATI');
+ if not Assigned(glDrawBuffersATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+{$IFDEF WINDOWS}
+function Load_WGL_ATI_pixel_format_float: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ @wglGetExtensionsStringARB := SDL_GL_GetProcAddress('wglGetExtensionsStringARB');
+ if not Assigned(wglGetExtensionsStringARB) then Exit;
+ extstring := wglGetExtensionsStringARB(wglGetCurrentDC);
+
+ if glext_ExtensionSupported('WGL_ATI_pixel_format_float', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+{$ENDIF}
+
+function Load_GL_ATI_texture_env_combine3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_texture_env_combine3', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_texture_float: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_texture_float', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_texture_expand_normal: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_texture_expand_normal', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_half_float: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_half_float', extstring) then
+ begin
+ @glVertex2hNV := SDL_GL_GetProcAddress('glVertex2hNV');
+ if not Assigned(glVertex2hNV) then Exit;
+ @glVertex2hvNV := SDL_GL_GetProcAddress('glVertex2hvNV');
+ if not Assigned(glVertex2hvNV) then Exit;
+ @glVertex3hNV := SDL_GL_GetProcAddress('glVertex3hNV');
+ if not Assigned(glVertex3hNV) then Exit;
+ @glVertex3hvNV := SDL_GL_GetProcAddress('glVertex3hvNV');
+ if not Assigned(glVertex3hvNV) then Exit;
+ @glVertex4hNV := SDL_GL_GetProcAddress('glVertex4hNV');
+ if not Assigned(glVertex4hNV) then Exit;
+ @glVertex4hvNV := SDL_GL_GetProcAddress('glVertex4hvNV');
+ if not Assigned(glVertex4hvNV) then Exit;
+ @glNormal3hNV := SDL_GL_GetProcAddress('glNormal3hNV');
+ if not Assigned(glNormal3hNV) then Exit;
+ @glNormal3hvNV := SDL_GL_GetProcAddress('glNormal3hvNV');
+ if not Assigned(glNormal3hvNV) then Exit;
+ @glColor3hNV := SDL_GL_GetProcAddress('glColor3hNV');
+ if not Assigned(glColor3hNV) then Exit;
+ @glColor3hvNV := SDL_GL_GetProcAddress('glColor3hvNV');
+ if not Assigned(glColor3hvNV) then Exit;
+ @glColor4hNV := SDL_GL_GetProcAddress('glColor4hNV');
+ if not Assigned(glColor4hNV) then Exit;
+ @glColor4hvNV := SDL_GL_GetProcAddress('glColor4hvNV');
+ if not Assigned(glColor4hvNV) then Exit;
+ @glTexCoord1hNV := SDL_GL_GetProcAddress('glTexCoord1hNV');
+ if not Assigned(glTexCoord1hNV) then Exit;
+ @glTexCoord1hvNV := SDL_GL_GetProcAddress('glTexCoord1hvNV');
+ if not Assigned(glTexCoord1hvNV) then Exit;
+ @glTexCoord2hNV := SDL_GL_GetProcAddress('glTexCoord2hNV');
+ if not Assigned(glTexCoord2hNV) then Exit;
+ @glTexCoord2hvNV := SDL_GL_GetProcAddress('glTexCoord2hvNV');
+ if not Assigned(glTexCoord2hvNV) then Exit;
+ @glTexCoord3hNV := SDL_GL_GetProcAddress('glTexCoord3hNV');
+ if not Assigned(glTexCoord3hNV) then Exit;
+ @glTexCoord3hvNV := SDL_GL_GetProcAddress('glTexCoord3hvNV');
+ if not Assigned(glTexCoord3hvNV) then Exit;
+ @glTexCoord4hNV := SDL_GL_GetProcAddress('glTexCoord4hNV');
+ if not Assigned(glTexCoord4hNV) then Exit;
+ @glTexCoord4hvNV := SDL_GL_GetProcAddress('glTexCoord4hvNV');
+ if not Assigned(glTexCoord4hvNV) then Exit;
+ @glMultiTexCoord1hNV := SDL_GL_GetProcAddress('glMultiTexCoord1hNV');
+ if not Assigned(glMultiTexCoord1hNV) then Exit;
+ @glMultiTexCoord1hvNV := SDL_GL_GetProcAddress('glMultiTexCoord1hvNV');
+ if not Assigned(glMultiTexCoord1hvNV) then Exit;
+ @glMultiTexCoord2hNV := SDL_GL_GetProcAddress('glMultiTexCoord2hNV');
+ if not Assigned(glMultiTexCoord2hNV) then Exit;
+ @glMultiTexCoord2hvNV := SDL_GL_GetProcAddress('glMultiTexCoord2hvNV');
+ if not Assigned(glMultiTexCoord2hvNV) then Exit;
+ @glMultiTexCoord3hNV := SDL_GL_GetProcAddress('glMultiTexCoord3hNV');
+ if not Assigned(glMultiTexCoord3hNV) then Exit;
+ @glMultiTexCoord3hvNV := SDL_GL_GetProcAddress('glMultiTexCoord3hvNV');
+ if not Assigned(glMultiTexCoord3hvNV) then Exit;
+ @glMultiTexCoord4hNV := SDL_GL_GetProcAddress('glMultiTexCoord4hNV');
+ if not Assigned(glMultiTexCoord4hNV) then Exit;
+ @glMultiTexCoord4hvNV := SDL_GL_GetProcAddress('glMultiTexCoord4hvNV');
+ if not Assigned(glMultiTexCoord4hvNV) then Exit;
+ @glFogCoordhNV := SDL_GL_GetProcAddress('glFogCoordhNV');
+ if not Assigned(glFogCoordhNV) then Exit;
+ @glFogCoordhvNV := SDL_GL_GetProcAddress('glFogCoordhvNV');
+ if not Assigned(glFogCoordhvNV) then Exit;
+ @glSecondaryColor3hNV := SDL_GL_GetProcAddress('glSecondaryColor3hNV');
+ if not Assigned(glSecondaryColor3hNV) then Exit;
+ @glSecondaryColor3hvNV := SDL_GL_GetProcAddress('glSecondaryColor3hvNV');
+ if not Assigned(glSecondaryColor3hvNV) then Exit;
+ @glVertexWeighthNV := SDL_GL_GetProcAddress('glVertexWeighthNV');
+ if not Assigned(glVertexWeighthNV) then Exit;
+ @glVertexWeighthvNV := SDL_GL_GetProcAddress('glVertexWeighthvNV');
+ if not Assigned(glVertexWeighthvNV) then Exit;
+ @glVertexAttrib1hNV := SDL_GL_GetProcAddress('glVertexAttrib1hNV');
+ if not Assigned(glVertexAttrib1hNV) then Exit;
+ @glVertexAttrib1hvNV := SDL_GL_GetProcAddress('glVertexAttrib1hvNV');
+ if not Assigned(glVertexAttrib1hvNV) then Exit;
+ @glVertexAttrib2hNV := SDL_GL_GetProcAddress('glVertexAttrib2hNV');
+ if not Assigned(glVertexAttrib2hNV) then Exit;
+ @glVertexAttrib2hvNV := SDL_GL_GetProcAddress('glVertexAttrib2hvNV');
+ if not Assigned(glVertexAttrib2hvNV) then Exit;
+ @glVertexAttrib3hNV := SDL_GL_GetProcAddress('glVertexAttrib3hNV');
+ if not Assigned(glVertexAttrib3hNV) then Exit;
+ @glVertexAttrib3hvNV := SDL_GL_GetProcAddress('glVertexAttrib3hvNV');
+ if not Assigned(glVertexAttrib3hvNV) then Exit;
+ @glVertexAttrib4hNV := SDL_GL_GetProcAddress('glVertexAttrib4hNV');
+ if not Assigned(glVertexAttrib4hNV) then Exit;
+ @glVertexAttrib4hvNV := SDL_GL_GetProcAddress('glVertexAttrib4hvNV');
+ if not Assigned(glVertexAttrib4hvNV) then Exit;
+ @glVertexAttribs1hvNV := SDL_GL_GetProcAddress('glVertexAttribs1hvNV');
+ if not Assigned(glVertexAttribs1hvNV) then Exit;
+ @glVertexAttribs2hvNV := SDL_GL_GetProcAddress('glVertexAttribs2hvNV');
+ if not Assigned(glVertexAttribs2hvNV) then Exit;
+ @glVertexAttribs3hvNV := SDL_GL_GetProcAddress('glVertexAttribs3hvNV');
+ if not Assigned(glVertexAttribs3hvNV) then Exit;
+ @glVertexAttribs4hvNV := SDL_GL_GetProcAddress('glVertexAttribs4hvNV');
+ if not Assigned(glVertexAttribs4hvNV) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_map_object_buffer: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_map_object_buffer', extstring) then
+ begin
+ @glMapObjectBufferATI := SDL_GL_GetProcAddress('glMapObjectBufferATI');
+ if not Assigned(glMapObjectBufferATI) then Exit;
+ @glUnmapObjectBufferATI := SDL_GL_GetProcAddress('glUnmapObjectBufferATI');
+ if not Assigned(glUnmapObjectBufferATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_separate_stencil: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_separate_stencil', extstring) then
+ begin
+ @glStencilOpSeparateATI := SDL_GL_GetProcAddress('glStencilOpSeparateATI');
+ if not Assigned(glStencilOpSeparateATI) then Exit;
+ @glStencilFuncSeparateATI := SDL_GL_GetProcAddress('glStencilFuncSeparateATI');
+ if not Assigned(glStencilFuncSeparateATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ATI_vertex_attrib_array_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ATI_vertex_attrib_array_object', extstring) then
+ begin
+ @glVertexAttribArrayObjectATI := SDL_GL_GetProcAddress('glVertexAttribArrayObjectATI');
+ if not Assigned(glVertexAttribArrayObjectATI) then Exit;
+ @glGetVertexAttribArrayObjectfvATI := SDL_GL_GetProcAddress('glGetVertexAttribArrayObjectfvATI');
+ if not Assigned(glGetVertexAttribArrayObjectfvATI) then Exit;
+ @glGetVertexAttribArrayObjectivATI := SDL_GL_GetProcAddress('glGetVertexAttribArrayObjectivATI');
+ if not Assigned(glGetVertexAttribArrayObjectivATI) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_vertex_buffer_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_vertex_buffer_object', extstring) then
+ begin
+ @glBindBufferARB := SDL_GL_GetProcAddress('glBindBufferARB');
+ if not Assigned(glBindBufferARB) then Exit;
+ @glDeleteBuffersARB := SDL_GL_GetProcAddress('glDeleteBuffersARB');
+ if not Assigned(glDeleteBuffersARB) then Exit;
+ @glGenBuffersARB := SDL_GL_GetProcAddress('glGenBuffersARB');
+ if not Assigned(glGenBuffersARB) then Exit;
+ @glIsBufferARB := SDL_GL_GetProcAddress('glIsBufferARB');
+ if not Assigned(glIsBufferARB) then Exit;
+ @glBufferDataARB := SDL_GL_GetProcAddress('glBufferDataARB');
+ if not Assigned(glBufferDataARB) then Exit;
+ @glBufferSubDataARB := SDL_GL_GetProcAddress('glBufferSubDataARB');
+ if not Assigned(glBufferSubDataARB) then Exit;
+ @glGetBufferSubDataARB := SDL_GL_GetProcAddress('glGetBufferSubDataARB');
+ if not Assigned(glGetBufferSubDataARB) then Exit;
+ @glMapBufferARB := SDL_GL_GetProcAddress('glMapBufferARB');
+ if not Assigned(glMapBufferARB) then Exit;
+ @glUnmapBufferARB := SDL_GL_GetProcAddress('glUnmapBufferARB');
+ if not Assigned(glUnmapBufferARB) then Exit;
+ @glGetBufferParameterivARB := SDL_GL_GetProcAddress('glGetBufferParameterivARB');
+ if not Assigned(glGetBufferParameterivARB) then Exit;
+ @glGetBufferPointervARB := SDL_GL_GetProcAddress('glGetBufferPointervARB');
+ if not Assigned(glGetBufferPointervARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_occlusion_query: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_occlusion_query', extstring) then
+ begin
+ @glGenQueriesARB := SDL_GL_GetProcAddress('glGenQueriesARB');
+ if not Assigned(glGenQueriesARB) then Exit;
+ @glDeleteQueriesARB := SDL_GL_GetProcAddress('glDeleteQueriesARB');
+ if not Assigned(glDeleteQueriesARB) then Exit;
+ @glIsQueryARB := SDL_GL_GetProcAddress('glIsQueryARB');
+ if not Assigned(glIsQueryARB) then Exit;
+ @glBeginQueryARB := SDL_GL_GetProcAddress('glBeginQueryARB');
+ if not Assigned(glBeginQueryARB) then Exit;
+ @glEndQueryARB := SDL_GL_GetProcAddress('glEndQueryARB');
+ if not Assigned(glEndQueryARB) then Exit;
+ @glGetQueryivARB := SDL_GL_GetProcAddress('glGetQueryivARB');
+ if not Assigned(glGetQueryivARB) then Exit;
+ @glGetQueryObjectivARB := SDL_GL_GetProcAddress('glGetQueryObjectivARB');
+ if not Assigned(glGetQueryObjectivARB) then Exit;
+ @glGetQueryObjectuivARB := SDL_GL_GetProcAddress('glGetQueryObjectuivARB');
+ if not Assigned(glGetQueryObjectuivARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_shader_objects: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_shader_objects', extstring) then
+ begin
+ @glDeleteObjectARB := SDL_GL_GetProcAddress('glDeleteObjectARB');
+ if not Assigned(glDeleteObjectARB) then Exit;
+ @glGetHandleARB := SDL_GL_GetProcAddress('glGetHandleARB');
+ if not Assigned(glGetHandleARB) then Exit;
+ @glDetachObjectARB := SDL_GL_GetProcAddress('glDetachObjectARB');
+ if not Assigned(glDetachObjectARB) then Exit;
+ @glCreateShaderObjectARB := SDL_GL_GetProcAddress('glCreateShaderObjectARB');
+ if not Assigned(glCreateShaderObjectARB) then Exit;
+ @glShaderSourceARB := SDL_GL_GetProcAddress('glShaderSourceARB');
+ if not Assigned(glShaderSourceARB) then Exit;
+ @glCompileShaderARB := SDL_GL_GetProcAddress('glCompileShaderARB');
+ if not Assigned(glCompileShaderARB) then Exit;
+ @glCreateProgramObjectARB := SDL_GL_GetProcAddress('glCreateProgramObjectARB');
+ if not Assigned(glCreateProgramObjectARB) then Exit;
+ @glAttachObjectARB := SDL_GL_GetProcAddress('glAttachObjectARB');
+ if not Assigned(glAttachObjectARB) then Exit;
+ @glLinkProgramARB := SDL_GL_GetProcAddress('glLinkProgramARB');
+ if not Assigned(glLinkProgramARB) then Exit;
+ @glUseProgramObjectARB := SDL_GL_GetProcAddress('glUseProgramObjectARB');
+ if not Assigned(glUseProgramObjectARB) then Exit;
+ @glValidateProgramARB := SDL_GL_GetProcAddress('glValidateProgramARB');
+ if not Assigned(glValidateProgramARB) then Exit;
+ @glUniform1fARB := SDL_GL_GetProcAddress('glUniform1fARB');
+ if not Assigned(glUniform1fARB) then Exit;
+ @glUniform2fARB := SDL_GL_GetProcAddress('glUniform2fARB');
+ if not Assigned(glUniform2fARB) then Exit;
+ @glUniform3fARB := SDL_GL_GetProcAddress('glUniform3fARB');
+ if not Assigned(glUniform3fARB) then Exit;
+ @glUniform4fARB := SDL_GL_GetProcAddress('glUniform4fARB');
+ if not Assigned(glUniform4fARB) then Exit;
+ @glUniform1iARB := SDL_GL_GetProcAddress('glUniform1iARB');
+ if not Assigned(glUniform1iARB) then Exit;
+ @glUniform2iARB := SDL_GL_GetProcAddress('glUniform2iARB');
+ if not Assigned(glUniform2iARB) then Exit;
+ @glUniform3iARB := SDL_GL_GetProcAddress('glUniform3iARB');
+ if not Assigned(glUniform3iARB) then Exit;
+ @glUniform4iARB := SDL_GL_GetProcAddress('glUniform4iARB');
+ if not Assigned(glUniform4iARB) then Exit;
+ @glUniform1fvARB := SDL_GL_GetProcAddress('glUniform1fvARB');
+ if not Assigned(glUniform1fvARB) then Exit;
+ @glUniform2fvARB := SDL_GL_GetProcAddress('glUniform2fvARB');
+ if not Assigned(glUniform2fvARB) then Exit;
+ @glUniform3fvARB := SDL_GL_GetProcAddress('glUniform3fvARB');
+ if not Assigned(glUniform3fvARB) then Exit;
+ @glUniform4fvARB := SDL_GL_GetProcAddress('glUniform4fvARB');
+ if not Assigned(glUniform4fvARB) then Exit;
+ @glUniform1ivARB := SDL_GL_GetProcAddress('glUniform1ivARB');
+ if not Assigned(glUniform1ivARB) then Exit;
+ @glUniform2ivARB := SDL_GL_GetProcAddress('glUniform2ivARB');
+ if not Assigned(glUniform2ivARB) then Exit;
+ @glUniform3ivARB := SDL_GL_GetProcAddress('glUniform3ivARB');
+ if not Assigned(glUniform3ivARB) then Exit;
+ @glUniform4ivARB := SDL_GL_GetProcAddress('glUniform4ivARB');
+ if not Assigned(glUniform4ivARB) then Exit;
+ @glUniformMatrix2fvARB := SDL_GL_GetProcAddress('glUniformMatrix2fvARB');
+ if not Assigned(glUniformMatrix2fvARB) then Exit;
+ @glUniformMatrix3fvARB := SDL_GL_GetProcAddress('glUniformMatrix3fvARB');
+ if not Assigned(glUniformMatrix3fvARB) then Exit;
+ @glUniformMatrix4fvARB := SDL_GL_GetProcAddress('glUniformMatrix4fvARB');
+ if not Assigned(glUniformMatrix4fvARB) then Exit;
+ @glGetObjectParameterfvARB := SDL_GL_GetProcAddress('glGetObjectParameterfvARB');
+ if not Assigned(glGetObjectParameterfvARB) then Exit;
+ @glGetObjectParameterivARB := SDL_GL_GetProcAddress('glGetObjectParameterivARB');
+ if not Assigned(glGetObjectParameterivARB) then Exit;
+ @glGetInfoLogARB := SDL_GL_GetProcAddress('glGetInfoLogARB');
+ if not Assigned(glGetInfoLogARB) then Exit;
+ @glGetAttachedObjectsARB := SDL_GL_GetProcAddress('glGetAttachedObjectsARB');
+ if not Assigned(glGetAttachedObjectsARB) then Exit;
+ @glGetUniformLocationARB := SDL_GL_GetProcAddress('glGetUniformLocationARB');
+ if not Assigned(glGetUniformLocationARB) then Exit;
+ @glGetActiveUniformARB := SDL_GL_GetProcAddress('glGetActiveUniformARB');
+ if not Assigned(glGetActiveUniformARB) then Exit;
+ @glGetUniformfvARB := SDL_GL_GetProcAddress('glGetUniformfvARB');
+ if not Assigned(glGetUniformfvARB) then Exit;
+ @glGetUniformivARB := SDL_GL_GetProcAddress('glGetUniformivARB');
+ if not Assigned(glGetUniformivARB) then Exit;
+ @glGetShaderSourceARB := SDL_GL_GetProcAddress('glGetShaderSourceARB');
+ if not Assigned(glGetShaderSourceARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_vertex_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_vertex_shader', extstring) then
+ begin
+ @glVertexAttrib1fARB := SDL_GL_GetProcAddress('glVertexAttrib1fARB');
+ if not Assigned(glVertexAttrib1fARB) then Exit;
+ @glVertexAttrib1sARB := SDL_GL_GetProcAddress('glVertexAttrib1sARB');
+ if not Assigned(glVertexAttrib1sARB) then Exit;
+ @glVertexAttrib1dARB := SDL_GL_GetProcAddress('glVertexAttrib1dARB');
+ if not Assigned(glVertexAttrib1dARB) then Exit;
+ @glVertexAttrib2fARB := SDL_GL_GetProcAddress('glVertexAttrib2fARB');
+ if not Assigned(glVertexAttrib2fARB) then Exit;
+ @glVertexAttrib2sARB := SDL_GL_GetProcAddress('glVertexAttrib2sARB');
+ if not Assigned(glVertexAttrib2sARB) then Exit;
+ @glVertexAttrib2dARB := SDL_GL_GetProcAddress('glVertexAttrib2dARB');
+ if not Assigned(glVertexAttrib2dARB) then Exit;
+ @glVertexAttrib3fARB := SDL_GL_GetProcAddress('glVertexAttrib3fARB');
+ if not Assigned(glVertexAttrib3fARB) then Exit;
+ @glVertexAttrib3sARB := SDL_GL_GetProcAddress('glVertexAttrib3sARB');
+ if not Assigned(glVertexAttrib3sARB) then Exit;
+ @glVertexAttrib3dARB := SDL_GL_GetProcAddress('glVertexAttrib3dARB');
+ if not Assigned(glVertexAttrib3dARB) then Exit;
+ @glVertexAttrib4fARB := SDL_GL_GetProcAddress('glVertexAttrib4fARB');
+ if not Assigned(glVertexAttrib4fARB) then Exit;
+ @glVertexAttrib4sARB := SDL_GL_GetProcAddress('glVertexAttrib4sARB');
+ if not Assigned(glVertexAttrib4sARB) then Exit;
+ @glVertexAttrib4dARB := SDL_GL_GetProcAddress('glVertexAttrib4dARB');
+ if not Assigned(glVertexAttrib4dARB) then Exit;
+ @glVertexAttrib4NubARB := SDL_GL_GetProcAddress('glVertexAttrib4NubARB');
+ if not Assigned(glVertexAttrib4NubARB) then Exit;
+ @glVertexAttrib1fvARB := SDL_GL_GetProcAddress('glVertexAttrib1fvARB');
+ if not Assigned(glVertexAttrib1fvARB) then Exit;
+ @glVertexAttrib1svARB := SDL_GL_GetProcAddress('glVertexAttrib1svARB');
+ if not Assigned(glVertexAttrib1svARB) then Exit;
+ @glVertexAttrib1dvARB := SDL_GL_GetProcAddress('glVertexAttrib1dvARB');
+ if not Assigned(glVertexAttrib1dvARB) then Exit;
+ @glVertexAttrib2fvARB := SDL_GL_GetProcAddress('glVertexAttrib2fvARB');
+ if not Assigned(glVertexAttrib2fvARB) then Exit;
+ @glVertexAttrib2svARB := SDL_GL_GetProcAddress('glVertexAttrib2svARB');
+ if not Assigned(glVertexAttrib2svARB) then Exit;
+ @glVertexAttrib2dvARB := SDL_GL_GetProcAddress('glVertexAttrib2dvARB');
+ if not Assigned(glVertexAttrib2dvARB) then Exit;
+ @glVertexAttrib3fvARB := SDL_GL_GetProcAddress('glVertexAttrib3fvARB');
+ if not Assigned(glVertexAttrib3fvARB) then Exit;
+ @glVertexAttrib3svARB := SDL_GL_GetProcAddress('glVertexAttrib3svARB');
+ if not Assigned(glVertexAttrib3svARB) then Exit;
+ @glVertexAttrib3dvARB := SDL_GL_GetProcAddress('glVertexAttrib3dvARB');
+ if not Assigned(glVertexAttrib3dvARB) then Exit;
+ @glVertexAttrib4fvARB := SDL_GL_GetProcAddress('glVertexAttrib4fvARB');
+ if not Assigned(glVertexAttrib4fvARB) then Exit;
+ @glVertexAttrib4svARB := SDL_GL_GetProcAddress('glVertexAttrib4svARB');
+ if not Assigned(glVertexAttrib4svARB) then Exit;
+ @glVertexAttrib4dvARB := SDL_GL_GetProcAddress('glVertexAttrib4dvARB');
+ if not Assigned(glVertexAttrib4dvARB) then Exit;
+ @glVertexAttrib4ivARB := SDL_GL_GetProcAddress('glVertexAttrib4ivARB');
+ if not Assigned(glVertexAttrib4ivARB) then Exit;
+ @glVertexAttrib4bvARB := SDL_GL_GetProcAddress('glVertexAttrib4bvARB');
+ if not Assigned(glVertexAttrib4bvARB) then Exit;
+ @glVertexAttrib4ubvARB := SDL_GL_GetProcAddress('glVertexAttrib4ubvARB');
+ if not Assigned(glVertexAttrib4ubvARB) then Exit;
+ @glVertexAttrib4usvARB := SDL_GL_GetProcAddress('glVertexAttrib4usvARB');
+ if not Assigned(glVertexAttrib4usvARB) then Exit;
+ @glVertexAttrib4uivARB := SDL_GL_GetProcAddress('glVertexAttrib4uivARB');
+ if not Assigned(glVertexAttrib4uivARB) then Exit;
+ @glVertexAttrib4NbvARB := SDL_GL_GetProcAddress('glVertexAttrib4NbvARB');
+ if not Assigned(glVertexAttrib4NbvARB) then Exit;
+ @glVertexAttrib4NsvARB := SDL_GL_GetProcAddress('glVertexAttrib4NsvARB');
+ if not Assigned(glVertexAttrib4NsvARB) then Exit;
+ @glVertexAttrib4NivARB := SDL_GL_GetProcAddress('glVertexAttrib4NivARB');
+ if not Assigned(glVertexAttrib4NivARB) then Exit;
+ @glVertexAttrib4NubvARB := SDL_GL_GetProcAddress('glVertexAttrib4NubvARB');
+ if not Assigned(glVertexAttrib4NubvARB) then Exit;
+ @glVertexAttrib4NusvARB := SDL_GL_GetProcAddress('glVertexAttrib4NusvARB');
+ if not Assigned(glVertexAttrib4NusvARB) then Exit;
+ @glVertexAttrib4NuivARB := SDL_GL_GetProcAddress('glVertexAttrib4NuivARB');
+ if not Assigned(glVertexAttrib4NuivARB) then Exit;
+ @glVertexAttribPointerARB := SDL_GL_GetProcAddress('glVertexAttribPointerARB');
+ if not Assigned(glVertexAttribPointerARB) then Exit;
+ @glEnableVertexAttribArrayARB := SDL_GL_GetProcAddress('glEnableVertexAttribArrayARB');
+ if not Assigned(glEnableVertexAttribArrayARB) then Exit;
+ @glDisableVertexAttribArrayARB := SDL_GL_GetProcAddress('glDisableVertexAttribArrayARB');
+ if not Assigned(glDisableVertexAttribArrayARB) then Exit;
+ @glBindAttribLocationARB := SDL_GL_GetProcAddress('glBindAttribLocationARB');
+ if not Assigned(glBindAttribLocationARB) then Exit;
+ @glGetActiveAttribARB := SDL_GL_GetProcAddress('glGetActiveAttribARB');
+ if not Assigned(glGetActiveAttribARB) then Exit;
+ @glGetAttribLocationARB := SDL_GL_GetProcAddress('glGetAttribLocationARB');
+ if not Assigned(glGetAttribLocationARB) then Exit;
+ @glGetVertexAttribdvARB := SDL_GL_GetProcAddress('glGetVertexAttribdvARB');
+ if not Assigned(glGetVertexAttribdvARB) then Exit;
+ @glGetVertexAttribfvARB := SDL_GL_GetProcAddress('glGetVertexAttribfvARB');
+ if not Assigned(glGetVertexAttribfvARB) then Exit;
+ @glGetVertexAttribivARB := SDL_GL_GetProcAddress('glGetVertexAttribivARB');
+ if not Assigned(glGetVertexAttribivARB) then Exit;
+ @glGetVertexAttribPointervARB := SDL_GL_GetProcAddress('glGetVertexAttribPointervARB');
+ if not Assigned(glGetVertexAttribPointervARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_fragment_shader: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_fragment_shader', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_shading_language_100: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_shading_language_100', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_non_power_of_two: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_texture_non_power_of_two', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_point_sprite: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_point_sprite', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_depth_bounds_test: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_depth_bounds_test', extstring) then
+ begin
+ @glDepthBoundsEXT := SDL_GL_GetProcAddress('glDepthBoundsEXT');
+ if not Assigned(glDepthBoundsEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_secondary_color: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_secondary_color', extstring) then
+ begin
+ @glSecondaryColor3bEXT := SDL_GL_GetProcAddress('glSecondaryColor3bEXT');
+ if not Assigned(glSecondaryColor3bEXT) then Exit;
+ @glSecondaryColor3sEXT := SDL_GL_GetProcAddress('glSecondaryColor3sEXT');
+ if not Assigned(glSecondaryColor3sEXT) then Exit;
+ @glSecondaryColor3iEXT := SDL_GL_GetProcAddress('glSecondaryColor3iEXT');
+ if not Assigned(glSecondaryColor3iEXT) then Exit;
+ @glSecondaryColor3fEXT := SDL_GL_GetProcAddress('glSecondaryColor3fEXT');
+ if not Assigned(glSecondaryColor3fEXT) then Exit;
+ @glSecondaryColor3dEXT := SDL_GL_GetProcAddress('glSecondaryColor3dEXT');
+ if not Assigned(glSecondaryColor3dEXT) then Exit;
+ @glSecondaryColor3ubEXT := SDL_GL_GetProcAddress('glSecondaryColor3ubEXT');
+ if not Assigned(glSecondaryColor3ubEXT) then Exit;
+ @glSecondaryColor3usEXT := SDL_GL_GetProcAddress('glSecondaryColor3usEXT');
+ if not Assigned(glSecondaryColor3usEXT) then Exit;
+ @glSecondaryColor3uiEXT := SDL_GL_GetProcAddress('glSecondaryColor3uiEXT');
+ if not Assigned(glSecondaryColor3uiEXT) then Exit;
+ @glSecondaryColor3bvEXT := SDL_GL_GetProcAddress('glSecondaryColor3bvEXT');
+ if not Assigned(glSecondaryColor3bvEXT) then Exit;
+ @glSecondaryColor3svEXT := SDL_GL_GetProcAddress('glSecondaryColor3svEXT');
+ if not Assigned(glSecondaryColor3svEXT) then Exit;
+ @glSecondaryColor3ivEXT := SDL_GL_GetProcAddress('glSecondaryColor3ivEXT');
+ if not Assigned(glSecondaryColor3ivEXT) then Exit;
+ @glSecondaryColor3fvEXT := SDL_GL_GetProcAddress('glSecondaryColor3fvEXT');
+ if not Assigned(glSecondaryColor3fvEXT) then Exit;
+ @glSecondaryColor3dvEXT := SDL_GL_GetProcAddress('glSecondaryColor3dvEXT');
+ if not Assigned(glSecondaryColor3dvEXT) then Exit;
+ @glSecondaryColor3ubvEXT := SDL_GL_GetProcAddress('glSecondaryColor3ubvEXT');
+ if not Assigned(glSecondaryColor3ubvEXT) then Exit;
+ @glSecondaryColor3usvEXT := SDL_GL_GetProcAddress('glSecondaryColor3usvEXT');
+ if not Assigned(glSecondaryColor3usvEXT) then Exit;
+ @glSecondaryColor3uivEXT := SDL_GL_GetProcAddress('glSecondaryColor3uivEXT');
+ if not Assigned(glSecondaryColor3uivEXT) then Exit;
+ @glSecondaryColorPointerEXT := SDL_GL_GetProcAddress('glSecondaryColorPointerEXT');
+ if not Assigned(glSecondaryColorPointerEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_mirror_clamp: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_texture_mirror_clamp', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_blend_equation_separate: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_blend_equation_separate', extstring) then
+ begin
+ @glBlendEquationSeparateEXT := SDL_GL_GetProcAddress('glBlendEquationSeparateEXT');
+ if not Assigned(glBlendEquationSeparateEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_MESA_pack_invert: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_MESA_pack_invert', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_MESA_ycbcr_texture: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_MESA_ycbcr_texture', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_fragment_program_shadow: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_ARB_fragment_program_shadow', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_fog_coord: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_fog_coord', extstring) then
+ begin
+ @glFogCoordfEXT := SDL_GL_GetProcAddress('glFogCoordfEXT');
+ if not Assigned(glFogCoordfEXT) then Exit;
+ @glFogCoorddEXT := SDL_GL_GetProcAddress('glFogCoorddEXT');
+ if not Assigned(glFogCoorddEXT) then Exit;
+ @glFogCoordfvEXT := SDL_GL_GetProcAddress('glFogCoordfvEXT');
+ if not Assigned(glFogCoordfvEXT) then Exit;
+ @glFogCoorddvEXT := SDL_GL_GetProcAddress('glFogCoorddvEXT');
+ if not Assigned(glFogCoorddvEXT) then Exit;
+ @glFogCoordPointerEXT := SDL_GL_GetProcAddress('glFogCoordPointerEXT');
+ if not Assigned(glFogCoordPointerEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_fragment_program_option: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_fragment_program_option', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_pixel_buffer_object: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_EXT_pixel_buffer_object', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_fragment_program2: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_fragment_program2', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_program2_option: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_program2_option', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_NV_vertex_program3: Boolean;
+var
+ extstring : PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString( GL_EXTENSIONS );
+
+ if glext_ExtensionSupported('GL_NV_vertex_program3', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_draw_buffers: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_draw_buffers', extstring) then
+ begin
+ glDrawBuffersARB := SDL_GL_GetProcAddress('glDrawBuffersARB');
+ if not Assigned(glDrawBuffersARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_rectangle: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_texture_rectangle', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_color_buffer_float: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_color_buffer_float', extstring) then
+ begin
+ glClampColorARB := SDL_GL_GetProcAddress('glClampColorARB');
+ if not Assigned(glClampColorARB) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_half_float_pixel: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_half_float_pixel', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_texture_float: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_texture_float', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_texture_compression_dxt1: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_EXT_texture_compression_dxt1', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_ARB_pixel_buffer_object: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_ARB_pixel_buffer_object', extstring) then
+ begin
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_EXT_framebuffer_object: Boolean;
+var
+ extstring: PChar;
+begin
+
+ Result := FALSE;
+ extstring := glGetString(GL_EXTENSIONS);
+
+ if glext_ExtensionSupported('GL_EXT_framebuffer_object', extstring) then
+ begin
+ glIsRenderbufferEXT := SDL_GL_GetProcAddress('glIsRenderbufferEXT');
+ if not Assigned(glIsRenderbufferEXT) then Exit;
+ glBindRenderbufferEXT := SDL_GL_GetProcAddress('glBindRenderbufferEXT');
+ if not Assigned(glBindRenderbufferEXT) then Exit;
+ glDeleteRenderbuffersEXT := SDL_GL_GetProcAddress('glDeleteRenderbuffersEXT');
+ if not Assigned(glDeleteRenderbuffersEXT) then Exit;
+ glGenRenderbuffersEXT := SDL_GL_GetProcAddress('glGenRenderbuffersEXT');
+ if not Assigned(glGenRenderbuffersEXT) then Exit;
+ glRenderbufferStorageEXT := SDL_GL_GetProcAddress('glRenderbufferStorageEXT');
+ if not Assigned(glRenderbufferStorageEXT) then Exit;
+ glGetRenderbufferParameterivEXT := SDL_GL_GetProcAddress('glGetRenderbufferParameterivEXT');
+ if not Assigned(glGetRenderbufferParameterivEXT) then Exit;
+ glIsFramebufferEXT := SDL_GL_GetProcAddress('glIsFramebufferEXT');
+ if not Assigned(glIsFramebufferEXT) then Exit;
+ glBindFramebufferEXT := SDL_GL_GetProcAddress('glBindFramebufferEXT');
+ if not Assigned(glBindFramebufferEXT) then Exit;
+ glDeleteFramebuffersEXT := SDL_GL_GetProcAddress('glDeleteFramebuffersEXT');
+ if not Assigned(glDeleteFramebuffersEXT) then Exit;
+ glGenFramebuffersEXT := SDL_GL_GetProcAddress('glGenFramebuffersEXT');
+ if not Assigned(glGenFramebuffersEXT) then Exit;
+ glCheckFramebufferStatusEXT := SDL_GL_GetProcAddress('glCheckFramebufferStatusEXT');
+ if not Assigned(glCheckFramebufferStatusEXT) then Exit;
+ glFramebufferTexture1DEXT := SDL_GL_GetProcAddress('glFramebufferTexture1DEXT');
+ if not Assigned(glFramebufferTexture1DEXT) then Exit;
+ glFramebufferTexture2DEXT := SDL_GL_GetProcAddress('glFramebufferTexture2DEXT');
+ if not Assigned(glFramebufferTexture2DEXT) then Exit;
+ glFramebufferTexture3DEXT := SDL_GL_GetProcAddress('glFramebufferTexture3DEXT');
+ if not Assigned(glFramebufferTexture3DEXT) then Exit;
+ glFramebufferRenderbufferEXT := SDL_GL_GetProcAddress('glFramebufferRenderbufferEXT');
+ if not Assigned(glFramebufferRenderbufferEXT) then Exit;
+ glGetFramebufferAttachmentParameterivEXT := SDL_GL_GetProcAddress('glGetFramebufferAttachmentParameterivEXT');
+ if not Assigned(glGetFramebufferAttachmentParameterivEXT) then Exit;
+ glGenerateMipmapEXT := SDL_GL_GetProcAddress('glGenerateMipmapEXT');
+ if not Assigned(glGenerateMipmapEXT) then Exit;
+ Result := TRUE;
+ end;
+
+end;
+
+function Load_GL_version_1_4: Boolean;
+var
+ extstring: String;
+begin
+
+ Result := FALSE;
+ extstring := String(PChar(glGetString(GL_EXTENSIONS)));
+
+ glBlendFuncSeparate := SDL_GL_GetProcAddress('glBlendFuncSeparate');
+ if not Assigned(glBlendFuncSeparate) then Exit;
+ glFogCoordf := SDL_GL_GetProcAddress('glFogCoordf');
+ if not Assigned(glFogCoordf) then Exit;
+ glFogCoordfv := SDL_GL_GetProcAddress('glFogCoordfv');
+ if not Assigned(glFogCoordfv) then Exit;
+ glFogCoordd := SDL_GL_GetProcAddress('glFogCoordd');
+ if not Assigned(glFogCoordd) then Exit;
+ glFogCoorddv := SDL_GL_GetProcAddress('glFogCoorddv');
+ if not Assigned(glFogCoorddv) then Exit;
+ glFogCoordPointer := SDL_GL_GetProcAddress('glFogCoordPointer');
+ if not Assigned(glFogCoordPointer) then Exit;
+ glMultiDrawArrays := SDL_GL_GetProcAddress('glMultiDrawArrays');
+ if not Assigned(glMultiDrawArrays) then Exit;
+ glMultiDrawElements := SDL_GL_GetProcAddress('glMultiDrawElements');
+ if not Assigned(glMultiDrawElements) then Exit;
+ glPointParameterf := SDL_GL_GetProcAddress('glPointParameterf');
+ if not Assigned(glPointParameterf) then Exit;
+ glPointParameterfv := SDL_GL_GetProcAddress('glPointParameterfv');
+ if not Assigned(glPointParameterfv) then Exit;
+ glPointParameteri := SDL_GL_GetProcAddress('glPointParameteri');
+ if not Assigned(glPointParameteri) then Exit;
+ glPointParameteriv := SDL_GL_GetProcAddress('glPointParameteriv');
+ if not Assigned(glPointParameteriv) then Exit;
+ glSecondaryColor3b := SDL_GL_GetProcAddress('glSecondaryColor3b');
+ if not Assigned(glSecondaryColor3b) then Exit;
+ glSecondaryColor3bv := SDL_GL_GetProcAddress('glSecondaryColor3bv');
+ if not Assigned(glSecondaryColor3bv) then Exit;
+ glSecondaryColor3d := SDL_GL_GetProcAddress('glSecondaryColor3d');
+ if not Assigned(glSecondaryColor3d) then Exit;
+ glSecondaryColor3dv := SDL_GL_GetProcAddress('glSecondaryColor3dv');
+ if not Assigned(glSecondaryColor3dv) then Exit;
+ glSecondaryColor3f := SDL_GL_GetProcAddress('glSecondaryColor3f');
+ if not Assigned(glSecondaryColor3f) then Exit;
+ glSecondaryColor3fv := SDL_GL_GetProcAddress('glSecondaryColor3fv');
+ if not Assigned(glSecondaryColor3fv) then Exit;
+ glSecondaryColor3i := SDL_GL_GetProcAddress('glSecondaryColor3i');
+ if not Assigned(glSecondaryColor3i) then Exit;
+ glSecondaryColor3iv := SDL_GL_GetProcAddress('glSecondaryColor3iv');
+ if not Assigned(glSecondaryColor3iv) then Exit;
+ glSecondaryColor3s := SDL_GL_GetProcAddress('glSecondaryColor3s');
+ if not Assigned(glSecondaryColor3s) then Exit;
+ glSecondaryColor3sv := SDL_GL_GetProcAddress('glSecondaryColor3sv');
+ if not Assigned(glSecondaryColor3sv) then Exit;
+ glSecondaryColor3ub := SDL_GL_GetProcAddress('glSecondaryColor3ub');
+ if not Assigned(glSecondaryColor3ub) then Exit;
+ glSecondaryColor3ubv := SDL_GL_GetProcAddress('glSecondaryColor3ubv');
+ if not Assigned(glSecondaryColor3ubv) then Exit;
+ glSecondaryColor3ui := SDL_GL_GetProcAddress('glSecondaryColor3ui');
+ if not Assigned(glSecondaryColor3ui) then Exit;
+ glSecondaryColor3uiv := SDL_GL_GetProcAddress('glSecondaryColor3uiv');
+ if not Assigned(glSecondaryColor3uiv) then Exit;
+ glSecondaryColor3us := SDL_GL_GetProcAddress('glSecondaryColor3us');
+ if not Assigned(glSecondaryColor3us) then Exit;
+ glSecondaryColor3usv := SDL_GL_GetProcAddress('glSecondaryColor3usv');
+ if not Assigned(glSecondaryColor3usv) then Exit;
+ glSecondaryColorPointer := SDL_GL_GetProcAddress('glSecondaryColorPointer');
+ if not Assigned(glSecondaryColorPointer) then Exit;
+ glWindowPos2d := SDL_GL_GetProcAddress('glWindowPos2d');
+ if not Assigned(glWindowPos2d) then Exit;
+ glWindowPos2dv := SDL_GL_GetProcAddress('glWindowPos2dv');
+ if not Assigned(glWindowPos2dv) then Exit;
+ glWindowPos2f := SDL_GL_GetProcAddress('glWindowPos2f');
+ if not Assigned(glWindowPos2f) then Exit;
+ glWindowPos2fv := SDL_GL_GetProcAddress('glWindowPos2fv');
+ if not Assigned(glWindowPos2fv) then Exit;
+ glWindowPos2i := SDL_GL_GetProcAddress('glWindowPos2i');
+ if not Assigned(glWindowPos2i) then Exit;
+ glWindowPos2iv := SDL_GL_GetProcAddress('glWindowPos2iv');
+ if not Assigned(glWindowPos2iv) then Exit;
+ glWindowPos2s := SDL_GL_GetProcAddress('glWindowPos2s');
+ if not Assigned(glWindowPos2s) then Exit;
+ glWindowPos2sv := SDL_GL_GetProcAddress('glWindowPos2sv');
+ if not Assigned(glWindowPos2sv) then Exit;
+ glWindowPos3d := SDL_GL_GetProcAddress('glWindowPos3d');
+ if not Assigned(glWindowPos3d) then Exit;
+ glWindowPos3dv := SDL_GL_GetProcAddress('glWindowPos3dv');
+ if not Assigned(glWindowPos3dv) then Exit;
+ glWindowPos3f := SDL_GL_GetProcAddress('glWindowPos3f');
+ if not Assigned(glWindowPos3f) then Exit;
+ glWindowPos3fv := SDL_GL_GetProcAddress('glWindowPos3fv');
+ if not Assigned(glWindowPos3fv) then Exit;
+ glWindowPos3i := SDL_GL_GetProcAddress('glWindowPos3i');
+ if not Assigned(glWindowPos3i) then Exit;
+ glWindowPos3iv := SDL_GL_GetProcAddress('glWindowPos3iv');
+ if not Assigned(glWindowPos3iv) then Exit;
+ glWindowPos3s := SDL_GL_GetProcAddress('glWindowPos3s');
+ if not Assigned(glWindowPos3s) then Exit;
+ glWindowPos3sv := SDL_GL_GetProcAddress('glWindowPos3sv');
+ if not Assigned(glWindowPos3sv) then Exit;
+ Result := TRUE;
+
+end;
+
+function Load_GL_version_1_5: Boolean;
+var
+ extstring: String;
+begin
+
+ Result := FALSE;
+ extstring := String(PChar(glGetString(GL_EXTENSIONS)));
+
+ glGenQueries := SDL_GL_GetProcAddress('glGenQueries');
+ if not Assigned(glGenQueries) then Exit;
+ glDeleteQueries := SDL_GL_GetProcAddress('glDeleteQueries');
+ if not Assigned(glDeleteQueries) then Exit;
+ glIsQuery := SDL_GL_GetProcAddress('glIsQuery');
+ if not Assigned(glIsQuery) then Exit;
+ glBeginQuery := SDL_GL_GetProcAddress('glBeginQuery');
+ if not Assigned(glBeginQuery) then Exit;
+ glEndQuery := SDL_GL_GetProcAddress('glEndQuery');
+ if not Assigned(glEndQuery) then Exit;
+ glGetQueryiv := SDL_GL_GetProcAddress('glGetQueryiv');
+ if not Assigned(glGetQueryiv) then Exit;
+ glGetQueryObjectiv := SDL_GL_GetProcAddress('glGetQueryObjectiv');
+ if not Assigned(glGetQueryObjectiv) then Exit;
+ glGetQueryObjectuiv := SDL_GL_GetProcAddress('glGetQueryObjectuiv');
+ if not Assigned(glGetQueryObjectuiv) then Exit;
+ glBindBuffer := SDL_GL_GetProcAddress('glBindBuffer');
+ if not Assigned(glBindBuffer) then Exit;
+ glDeleteBuffers := SDL_GL_GetProcAddress('glDeleteBuffers');
+ if not Assigned(glDeleteBuffers) then Exit;
+ glGenBuffers := SDL_GL_GetProcAddress('glGenBuffers');
+ if not Assigned(glGenBuffers) then Exit;
+ glIsBuffer := SDL_GL_GetProcAddress('glIsBuffer');
+ if not Assigned(glIsBuffer) then Exit;
+ glBufferData := SDL_GL_GetProcAddress('glBufferData');
+ if not Assigned(glBufferData) then Exit;
+ glBufferSubData := SDL_GL_GetProcAddress('glBufferSubData');
+ if not Assigned(glBufferSubData) then Exit;
+ glGetBufferSubData := SDL_GL_GetProcAddress('glGetBufferSubData');
+ if not Assigned(glGetBufferSubData) then Exit;
+ glMapBuffer := SDL_GL_GetProcAddress('glMapBuffer');
+ if not Assigned(glMapBuffer) then Exit;
+ glUnmapBuffer := SDL_GL_GetProcAddress('glUnmapBuffer');
+ if not Assigned(glUnmapBuffer) then Exit;
+ glGetBufferParameteriv := SDL_GL_GetProcAddress('glGetBufferParameteriv');
+ if not Assigned(glGetBufferParameteriv) then Exit;
+ glGetBufferPointerv := SDL_GL_GetProcAddress('glGetBufferPointerv');
+ if not Assigned(glGetBufferPointerv) then Exit;
+ Result := TRUE;
+
+end;
+
+function Load_GL_version_2_0: Boolean;
+var
+ extstring: String;
+begin
+
+ Result := FALSE;
+ extstring := String(PChar(glGetString(GL_EXTENSIONS)));
+
+ glBlendEquationSeparate := SDL_GL_GetProcAddress('glBlendEquationSeparate');
+ if not Assigned(glBlendEquationSeparate) then Exit;
+ glDrawBuffers := SDL_GL_GetProcAddress('glDrawBuffers');
+ if not Assigned(glDrawBuffers) then Exit;
+ glStencilOpSeparate := SDL_GL_GetProcAddress('glStencilOpSeparate');
+ if not Assigned(glStencilOpSeparate) then Exit;
+ glStencilFuncSeparate := SDL_GL_GetProcAddress('glStencilFuncSeparate');
+ if not Assigned(glStencilFuncSeparate) then Exit;
+ glStencilMaskSeparate := SDL_GL_GetProcAddress('glStencilMaskSeparate');
+ if not Assigned(glStencilMaskSeparate) then Exit;
+ glAttachShader := SDL_GL_GetProcAddress('glAttachShader');
+ if not Assigned(glAttachShader) then Exit;
+ glBindAttribLocation := SDL_GL_GetProcAddress('glBindAttribLocation');
+ if not Assigned(glBindAttribLocation) then Exit;
+ glCompileShader := SDL_GL_GetProcAddress('glCompileShader');
+ if not Assigned(glCompileShader) then Exit;
+ glCreateProgram := SDL_GL_GetProcAddress('glCreateProgram');
+ if not Assigned(glCreateProgram) then Exit;
+ glCreateShader := SDL_GL_GetProcAddress('glCreateShader');
+ if not Assigned(glCreateShader) then Exit;
+ glDeleteProgram := SDL_GL_GetProcAddress('glDeleteProgram');
+ if not Assigned(glDeleteProgram) then Exit;
+ glDeleteShader := SDL_GL_GetProcAddress('glDeleteShader');
+ if not Assigned(glDeleteShader) then Exit;
+ glDetachShader := SDL_GL_GetProcAddress('glDetachShader');
+ if not Assigned(glDetachShader) then Exit;
+ glDisableVertexAttribArray := SDL_GL_GetProcAddress('glDisableVertexAttribArray');
+ if not Assigned(glDisableVertexAttribArray) then Exit;
+ glEnableVertexAttribArray := SDL_GL_GetProcAddress('glEnableVertexAttribArray');
+ if not Assigned(glEnableVertexAttribArray) then Exit;
+ glGetActiveAttrib := SDL_GL_GetProcAddress('glGetActiveAttrib');
+ if not Assigned(glGetActiveAttrib) then Exit;
+ glGetActiveUniform := SDL_GL_GetProcAddress('glGetActiveUniform');
+ if not Assigned(glGetActiveUniform) then Exit;
+ glGetAttachedShaders := SDL_GL_GetProcAddress('glGetAttachedShaders');
+ if not Assigned(glGetAttachedShaders) then Exit;
+ glGetAttribLocation := SDL_GL_GetProcAddress('glGetAttribLocation');
+ if not Assigned(glGetAttribLocation) then Exit;
+ glGetProgramiv := SDL_GL_GetProcAddress('glGetProgramiv');
+ if not Assigned(glGetProgramiv) then Exit;
+ glGetProgramInfoLog := SDL_GL_GetProcAddress('glGetProgramInfoLog');
+ if not Assigned(glGetProgramInfoLog) then Exit;
+ glGetShaderiv := SDL_GL_GetProcAddress('glGetShaderiv');
+ if not Assigned(glGetShaderiv) then Exit;
+ glGetShaderInfoLog := SDL_GL_GetProcAddress('glGetShaderInfoLog');
+ if not Assigned(glGetShaderInfoLog) then Exit;
+ glGetShaderSource := SDL_GL_GetProcAddress('glGetShaderSource');
+ if not Assigned(glGetShaderSource) then Exit;
+ glGetUniformLocation := SDL_GL_GetProcAddress('glGetUniformLocation');
+ if not Assigned(glGetUniformLocation) then Exit;
+ glGetUniformfv := SDL_GL_GetProcAddress('glGetUniformfv');
+ if not Assigned(glGetUniformfv) then Exit;
+ glGetUniformiv := SDL_GL_GetProcAddress('glGetUniformiv');
+ if not Assigned(glGetUniformiv) then Exit;
+ glGetVertexAttribdv := SDL_GL_GetProcAddress('glGetVertexAttribdv');
+ if not Assigned(glGetVertexAttribdv) then Exit;
+ glGetVertexAttribfv := SDL_GL_GetProcAddress('glGetVertexAttribfv');
+ if not Assigned(glGetVertexAttribfv) then Exit;
+ glGetVertexAttribiv := SDL_GL_GetProcAddress('glGetVertexAttribiv');
+ if not Assigned(glGetVertexAttribiv) then Exit;
+ glGetVertexAttribPointerv := SDL_GL_GetProcAddress('glGetVertexAttribPointerv');
+ if not Assigned(glGetVertexAttribPointerv) then Exit;
+ glIsProgram := SDL_GL_GetProcAddress('glIsProgram');
+ if not Assigned(glIsProgram) then Exit;
+ glIsShader := SDL_GL_GetProcAddress('glIsShader');
+ if not Assigned(glIsShader) then Exit;
+ glLinkProgram := SDL_GL_GetProcAddress('glLinkProgram');
+ if not Assigned(glLinkProgram) then Exit;
+ glShaderSource := SDL_GL_GetProcAddress('glShaderSource');
+ if not Assigned(glShaderSource) then Exit;
+ glUseProgram := SDL_GL_GetProcAddress('glUseProgram');
+ if not Assigned(glUseProgram) then Exit;
+ glUniform1f := SDL_GL_GetProcAddress('glUniform1f');
+ if not Assigned(glUniform1f) then Exit;
+ glUniform2f := SDL_GL_GetProcAddress('glUniform2f');
+ if not Assigned(glUniform2f) then Exit;
+ glUniform3f := SDL_GL_GetProcAddress('glUniform3f');
+ if not Assigned(glUniform3f) then Exit;
+ glUniform4f := SDL_GL_GetProcAddress('glUniform4f');
+ if not Assigned(glUniform4f) then Exit;
+ glUniform1i := SDL_GL_GetProcAddress('glUniform1i');
+ if not Assigned(glUniform1i) then Exit;
+ glUniform2i := SDL_GL_GetProcAddress('glUniform2i');
+ if not Assigned(glUniform2i) then Exit;
+ glUniform3i := SDL_GL_GetProcAddress('glUniform3i');
+ if not Assigned(glUniform3i) then Exit;
+ glUniform4i := SDL_GL_GetProcAddress('glUniform4i');
+ if not Assigned(glUniform4i) then Exit;
+ glUniform1fv := SDL_GL_GetProcAddress('glUniform1fv');
+ if not Assigned(glUniform1fv) then Exit;
+ glUniform2fv := SDL_GL_GetProcAddress('glUniform2fv');
+ if not Assigned(glUniform2fv) then Exit;
+ glUniform3fv := SDL_GL_GetProcAddress('glUniform3fv');
+ if not Assigned(glUniform3fv) then Exit;
+ glUniform4fv := SDL_GL_GetProcAddress('glUniform4fv');
+ if not Assigned(glUniform4fv) then Exit;
+ glUniform1iv := SDL_GL_GetProcAddress('glUniform1iv');
+ if not Assigned(glUniform1iv) then Exit;
+ glUniform2iv := SDL_GL_GetProcAddress('glUniform2iv');
+ if not Assigned(glUniform2iv) then Exit;
+ glUniform3iv := SDL_GL_GetProcAddress('glUniform3iv');
+ if not Assigned(glUniform3iv) then Exit;
+ glUniform4iv := SDL_GL_GetProcAddress('glUniform4iv');
+ if not Assigned(glUniform4iv) then Exit;
+ glUniformMatrix2fv := SDL_GL_GetProcAddress('glUniformMatrix2fv');
+ if not Assigned(glUniformMatrix2fv) then Exit;
+ glUniformMatrix3fv := SDL_GL_GetProcAddress('glUniformMatrix3fv');
+ if not Assigned(glUniformMatrix3fv) then Exit;
+ glUniformMatrix4fv := SDL_GL_GetProcAddress('glUniformMatrix4fv');
+ if not Assigned(glUniformMatrix4fv) then Exit;
+ glValidateProgram := SDL_GL_GetProcAddress('glValidateProgram');
+ if not Assigned(glValidateProgram) then Exit;
+ glVertexAttrib1d := SDL_GL_GetProcAddress('glVertexAttrib1d');
+ if not Assigned(glVertexAttrib1d) then Exit;
+ glVertexAttrib1dv := SDL_GL_GetProcAddress('glVertexAttrib1dv');
+ if not Assigned(glVertexAttrib1dv) then Exit;
+ glVertexAttrib1f := SDL_GL_GetProcAddress('glVertexAttrib1f');
+ if not Assigned(glVertexAttrib1f) then Exit;
+ glVertexAttrib1fv := SDL_GL_GetProcAddress('glVertexAttrib1fv');
+ if not Assigned(glVertexAttrib1fv) then Exit;
+ glVertexAttrib1s := SDL_GL_GetProcAddress('glVertexAttrib1s');
+ if not Assigned(glVertexAttrib1s) then Exit;
+ glVertexAttrib1sv := SDL_GL_GetProcAddress('glVertexAttrib1sv');
+ if not Assigned(glVertexAttrib1sv) then Exit;
+ glVertexAttrib2d := SDL_GL_GetProcAddress('glVertexAttrib2d');
+ if not Assigned(glVertexAttrib2d) then Exit;
+ glVertexAttrib2dv := SDL_GL_GetProcAddress('glVertexAttrib2dv');
+ if not Assigned(glVertexAttrib2dv) then Exit;
+ glVertexAttrib2f := SDL_GL_GetProcAddress('glVertexAttrib2f');
+ if not Assigned(glVertexAttrib2f) then Exit;
+ glVertexAttrib2fv := SDL_GL_GetProcAddress('glVertexAttrib2fv');
+ if not Assigned(glVertexAttrib2fv) then Exit;
+ glVertexAttrib2s := SDL_GL_GetProcAddress('glVertexAttrib2s');
+ if not Assigned(glVertexAttrib2s) then Exit;
+ glVertexAttrib2sv := SDL_GL_GetProcAddress('glVertexAttrib2sv');
+ if not Assigned(glVertexAttrib2sv) then Exit;
+ glVertexAttrib3d := SDL_GL_GetProcAddress('glVertexAttrib3d');
+ if not Assigned(glVertexAttrib3d) then Exit;
+ glVertexAttrib3dv := SDL_GL_GetProcAddress('glVertexAttrib3dv');
+ if not Assigned(glVertexAttrib3dv) then Exit;
+ glVertexAttrib3f := SDL_GL_GetProcAddress('glVertexAttrib3f');
+ if not Assigned(glVertexAttrib3f) then Exit;
+ glVertexAttrib3fv := SDL_GL_GetProcAddress('glVertexAttrib3fv');
+ if not Assigned(glVertexAttrib3fv) then Exit;
+ glVertexAttrib3s := SDL_GL_GetProcAddress('glVertexAttrib3s');
+ if not Assigned(glVertexAttrib3s) then Exit;
+ glVertexAttrib3sv := SDL_GL_GetProcAddress('glVertexAttrib3sv');
+ if not Assigned(glVertexAttrib3sv) then Exit;
+ glVertexAttrib4Nbv := SDL_GL_GetProcAddress('glVertexAttrib4Nbv');
+ if not Assigned(glVertexAttrib4Nbv) then Exit;
+ glVertexAttrib4Niv := SDL_GL_GetProcAddress('glVertexAttrib4Niv');
+ if not Assigned(glVertexAttrib4Niv) then Exit;
+ glVertexAttrib4Nsv := SDL_GL_GetProcAddress('glVertexAttrib4Nsv');
+ if not Assigned(glVertexAttrib4Nsv) then Exit;
+ glVertexAttrib4Nub := SDL_GL_GetProcAddress('glVertexAttrib4Nub');
+ if not Assigned(glVertexAttrib4Nub) then Exit;
+ glVertexAttrib4Nubv := SDL_GL_GetProcAddress('glVertexAttrib4Nubv');
+ if not Assigned(glVertexAttrib4Nubv) then Exit;
+ glVertexAttrib4Nuiv := SDL_GL_GetProcAddress('glVertexAttrib4Nuiv');
+ if not Assigned(glVertexAttrib4Nuiv) then Exit;
+ glVertexAttrib4Nusv := SDL_GL_GetProcAddress('glVertexAttrib4Nusv');
+ if not Assigned(glVertexAttrib4Nusv) then Exit;
+ glVertexAttrib4bv := SDL_GL_GetProcAddress('glVertexAttrib4bv');
+ if not Assigned(glVertexAttrib4bv) then Exit;
+ glVertexAttrib4d := SDL_GL_GetProcAddress('glVertexAttrib4d');
+ if not Assigned(glVertexAttrib4d) then Exit;
+ glVertexAttrib4dv := SDL_GL_GetProcAddress('glVertexAttrib4dv');
+ if not Assigned(glVertexAttrib4dv) then Exit;
+ glVertexAttrib4f := SDL_GL_GetProcAddress('glVertexAttrib4f');
+ if not Assigned(glVertexAttrib4f) then Exit;
+ glVertexAttrib4fv := SDL_GL_GetProcAddress('glVertexAttrib4fv');
+ if not Assigned(glVertexAttrib4fv) then Exit;
+ glVertexAttrib4iv := SDL_GL_GetProcAddress('glVertexAttrib4iv');
+ if not Assigned(glVertexAttrib4iv) then Exit;
+ glVertexAttrib4s := SDL_GL_GetProcAddress('glVertexAttrib4s');
+ if not Assigned(glVertexAttrib4s) then Exit;
+ glVertexAttrib4sv := SDL_GL_GetProcAddress('glVertexAttrib4sv');
+ if not Assigned(glVertexAttrib4sv) then Exit;
+ glVertexAttrib4ubv := SDL_GL_GetProcAddress('glVertexAttrib4ubv');
+ if not Assigned(glVertexAttrib4ubv) then Exit;
+ glVertexAttrib4uiv := SDL_GL_GetProcAddress('glVertexAttrib4uiv');
+ if not Assigned(glVertexAttrib4uiv) then Exit;
+ glVertexAttrib4usv := SDL_GL_GetProcAddress('glVertexAttrib4usv');
+ if not Assigned(glVertexAttrib4usv) then Exit;
+ glVertexAttribPointer := SDL_GL_GetProcAddress('glVertexAttribPointer');
+ if not Assigned(glVertexAttribPointer) then Exit;
+ Result := TRUE;
+
+end;
+
+function glext_LoadExtension(ext: String): Boolean;
+begin
+
+ Result := FALSE;
+
+ if ext = 'GL_version_1_2' then Result := Load_GL_version_1_2
+ else if ext = 'GL_ARB_imaging' then Result := Load_GL_ARB_imaging
+ else if ext = 'GL_version_1_3' then Result := Load_GL_version_1_3
+ else if ext = 'GL_ARB_multitexture' then Result := Load_GL_ARB_multitexture
+ else if ext = 'GL_ARB_transpose_matrix' then Result := Load_GL_ARB_transpose_matrix
+ else if ext = 'GL_ARB_multisample' then Result := Load_GL_ARB_multisample
+ else if ext = 'GL_ARB_texture_env_add' then Result := Load_GL_ARB_texture_env_add
+ {$IFDEF WINDOWS}
+ else if ext = 'WGL_ARB_extensions_string' then Result := Load_WGL_ARB_extensions_string
+ else if ext = 'WGL_ARB_buffer_region' then Result := Load_WGL_ARB_buffer_region
+ {$ENDIF}
+ else if ext = 'GL_ARB_texture_cube_map' then Result := Load_GL_ARB_texture_cube_map
+ else if ext = 'GL_ARB_depth_texture' then Result := Load_GL_ARB_depth_texture
+ else if ext = 'GL_ARB_point_parameters' then Result := Load_GL_ARB_point_parameters
+ else if ext = 'GL_ARB_shadow' then Result := Load_GL_ARB_shadow
+ else if ext = 'GL_ARB_shadow_ambient' then Result := Load_GL_ARB_shadow_ambient
+ else if ext = 'GL_ARB_texture_border_clamp' then Result := Load_GL_ARB_texture_border_clamp
+ else if ext = 'GL_ARB_texture_compression' then Result := Load_GL_ARB_texture_compression
+ else if ext = 'GL_ARB_texture_env_combine' then Result := Load_GL_ARB_texture_env_combine
+ else if ext = 'GL_ARB_texture_env_crossbar' then Result := Load_GL_ARB_texture_env_crossbar
+ else if ext = 'GL_ARB_texture_env_dot3' then Result := Load_GL_ARB_texture_env_dot3
+ else if ext = 'GL_ARB_texture_mirrored_repeat' then Result := Load_GL_ARB_texture_mirrored_repeat
+ else if ext = 'GL_ARB_vertex_blend' then Result := Load_GL_ARB_vertex_blend
+ else if ext = 'GL_ARB_vertex_program' then Result := Load_GL_ARB_vertex_program
+ else if ext = 'GL_ARB_window_pos' then Result := Load_GL_ARB_window_pos
+ else if ext = 'GL_EXT_422_pixels' then Result := Load_GL_EXT_422_pixels
+ else if ext = 'GL_EXT_abgr' then Result := Load_GL_EXT_abgr
+ else if ext = 'GL_EXT_bgra' then Result := Load_GL_EXT_bgra
+ else if ext = 'GL_EXT_blend_color' then Result := Load_GL_EXT_blend_color
+ else if ext = 'GL_EXT_blend_func_separate' then Result := Load_GL_EXT_blend_func_separate
+ else if ext = 'GL_EXT_blend_logic_op' then Result := Load_GL_EXT_blend_logic_op
+ else if ext = 'GL_EXT_blend_minmax' then Result := Load_GL_EXT_blend_minmax
+ else if ext = 'GL_EXT_blend_subtract' then Result := Load_GL_EXT_blend_subtract
+ else if ext = 'GL_EXT_clip_volume_hint' then Result := Load_GL_EXT_clip_volume_hint
+ else if ext = 'GL_EXT_color_subtable' then Result := Load_GL_EXT_color_subtable
+ else if ext = 'GL_EXT_compiled_vertex_array' then Result := Load_GL_EXT_compiled_vertex_array
+ else if ext = 'GL_EXT_convolution' then Result := Load_GL_EXT_convolution
+ else if ext = 'GL_EXT_histogram' then Result := Load_GL_EXT_histogram
+ else if ext = 'GL_EXT_multi_draw_arrays' then Result := Load_GL_EXT_multi_draw_arrays
+ else if ext = 'GL_EXT_packed_pixels' then Result := Load_GL_EXT_packed_pixels
+ else if ext = 'GL_EXT_paletted_texture' then Result := Load_GL_EXT_paletted_texture
+ else if ext = 'GL_EXT_point_parameters' then Result := Load_GL_EXT_point_parameters
+ else if ext = 'GL_EXT_polygon_offset' then Result := Load_GL_EXT_polygon_offset
+ else if ext = 'GL_EXT_separate_specular_color' then Result := Load_GL_EXT_separate_specular_color
+ else if ext = 'GL_EXT_shadow_funcs' then Result := Load_GL_EXT_shadow_funcs
+ else if ext = 'GL_EXT_shared_texture_palette' then Result := Load_GL_EXT_shared_texture_palette
+ else if ext = 'GL_EXT_stencil_two_side' then Result := Load_GL_EXT_stencil_two_side
+ else if ext = 'GL_EXT_stencil_wrap' then Result := Load_GL_EXT_stencil_wrap
+ else if ext = 'GL_EXT_subtexture' then Result := Load_GL_EXT_subtexture
+ else if ext = 'GL_EXT_texture3D' then Result := Load_GL_EXT_texture3D
+ else if ext = 'GL_EXT_texture_compression_s3tc' then Result := Load_GL_EXT_texture_compression_s3tc
+ else if ext = 'GL_EXT_texture_env_add' then Result := Load_GL_EXT_texture_env_add
+ else if ext = 'GL_EXT_texture_env_combine' then Result := Load_GL_EXT_texture_env_combine
+ else if ext = 'GL_EXT_texture_env_dot3' then Result := Load_GL_EXT_texture_env_dot3
+ else if ext = 'GL_EXT_texture_filter_anisotropic' then Result := Load_GL_EXT_texture_filter_anisotropic
+ else if ext = 'GL_EXT_texture_lod_bias' then Result := Load_GL_EXT_texture_lod_bias
+ else if ext = 'GL_EXT_texture_object' then Result := Load_GL_EXT_texture_object
+ else if ext = 'GL_EXT_vertex_array' then Result := Load_GL_EXT_vertex_array
+ else if ext = 'GL_EXT_vertex_shader' then Result := Load_GL_EXT_vertex_shader
+ else if ext = 'GL_EXT_vertex_weighting' then Result := Load_GL_EXT_vertex_weighting
+ else if ext = 'GL_HP_occlusion_test' then Result := Load_GL_HP_occlusion_test
+ else if ext = 'GL_NV_blend_square' then Result := Load_GL_NV_blend_square
+ else if ext = 'GL_NV_copy_depth_to_color' then Result := Load_GL_NV_copy_depth_to_color
+ else if ext = 'GL_NV_depth_clamp' then Result := Load_GL_NV_depth_clamp
+ else if ext = 'GL_NV_evaluators' then Result := Load_GL_NV_evaluators
+ else if ext = 'GL_NV_fence' then Result := Load_GL_NV_fence
+ else if ext = 'GL_NV_fog_distance' then Result := Load_GL_NV_fog_distance
+ else if ext = 'GL_NV_light_max_exponent' then Result := Load_GL_NV_light_max_exponent
+ else if ext = 'GL_NV_multisample_filter_hint' then Result := Load_GL_NV_multisample_filter_hint
+ else if ext = 'GL_NV_occlusion_query' then Result := Load_GL_NV_occlusion_query
+ else if ext = 'GL_NV_packed_depth_stencil' then Result := Load_GL_NV_packed_depth_stencil
+ else if ext = 'GL_NV_point_sprite' then Result := Load_GL_NV_point_sprite
+ else if ext = 'GL_NV_register_combiners' then Result := Load_GL_NV_register_combiners
+ else if ext = 'GL_NV_register_combiners2' then Result := Load_GL_NV_register_combiners2
+ else if ext = 'GL_NV_texgen_emboss' then Result := Load_GL_NV_texgen_emboss
+ else if ext = 'GL_NV_texgen_reflection' then Result := Load_GL_NV_texgen_reflection
+ else if ext = 'GL_NV_texture_compression_vtc' then Result := Load_GL_NV_texture_compression_vtc
+ else if ext = 'GL_NV_texture_env_combine4' then Result := Load_GL_NV_texture_env_combine4
+ else if ext = 'GL_NV_texture_rectangle' then Result := Load_GL_NV_texture_rectangle
+ else if ext = 'GL_NV_texture_shader' then Result := Load_GL_NV_texture_shader
+ else if ext = 'GL_NV_texture_shader2' then Result := Load_GL_NV_texture_shader2
+ else if ext = 'GL_NV_texture_shader3' then Result := Load_GL_NV_texture_shader3
+ else if ext = 'GL_NV_vertex_array_range' then Result := Load_GL_NV_vertex_array_range
+ else if ext = 'GL_NV_vertex_array_range2' then Result := Load_GL_NV_vertex_array_range2
+ else if ext = 'GL_NV_vertex_program' then Result := Load_GL_NV_vertex_program
+ else if ext = 'GL_NV_vertex_program1_1' then Result := Load_GL_NV_vertex_program1_1
+ else if ext = 'GL_ATI_element_array' then Result := Load_GL_ATI_element_array
+ else if ext = 'GL_ATI_envmap_bumpmap' then Result := Load_GL_ATI_envmap_bumpmap
+ else if ext = 'GL_ATI_fragment_shader' then Result := Load_GL_ATI_fragment_shader
+ else if ext = 'GL_ATI_pn_triangles' then Result := Load_GL_ATI_pn_triangles
+ else if ext = 'GL_ATI_texture_mirror_once' then Result := Load_GL_ATI_texture_mirror_once
+ else if ext = 'GL_ATI_vertex_array_object' then Result := Load_GL_ATI_vertex_array_object
+ else if ext = 'GL_ATI_vertex_streams' then Result := Load_GL_ATI_vertex_streams
+ {$IFDEF WINDOWS}
+ else if ext = 'WGL_I3D_image_buffer' then Result := Load_WGL_I3D_image_buffer
+ else if ext = 'WGL_I3D_swap_frame_lock' then Result := Load_WGL_I3D_swap_frame_lock
+ else if ext = 'WGL_I3D_swap_frame_usage' then Result := Load_WGL_I3D_swap_frame_usage
+ {$ENDIF}
+ else if ext = 'GL_3DFX_texture_compression_FXT1' then Result := Load_GL_3DFX_texture_compression_FXT1
+ else if ext = 'GL_IBM_cull_vertex' then Result := Load_GL_IBM_cull_vertex
+ else if ext = 'GL_IBM_multimode_draw_arrays' then Result := Load_GL_IBM_multimode_draw_arrays
+ else if ext = 'GL_IBM_raster_pos_clip' then Result := Load_GL_IBM_raster_pos_clip
+ else if ext = 'GL_IBM_texture_mirrored_repeat' then Result := Load_GL_IBM_texture_mirrored_repeat
+ else if ext = 'GL_IBM_vertex_array_lists' then Result := Load_GL_IBM_vertex_array_lists
+ else if ext = 'GL_MESA_resize_buffers' then Result := Load_GL_MESA_resize_buffers
+ else if ext = 'GL_MESA_window_pos' then Result := Load_GL_MESA_window_pos
+ else if ext = 'GL_OML_interlace' then Result := Load_GL_OML_interlace
+ else if ext = 'GL_OML_resample' then Result := Load_GL_OML_resample
+ else if ext = 'GL_OML_subsample' then Result := Load_GL_OML_subsample
+ else if ext = 'GL_SGIS_generate_mipmap' then Result := Load_GL_SGIS_generate_mipmap
+ else if ext = 'GL_SGIS_multisample' then Result := Load_GL_SGIS_multisample
+ else if ext = 'GL_SGIS_pixel_texture' then Result := Load_GL_SGIS_pixel_texture
+ else if ext = 'GL_SGIS_texture_border_clamp' then Result := Load_GL_SGIS_texture_border_clamp
+ else if ext = 'GL_SGIS_texture_color_mask' then Result := Load_GL_SGIS_texture_color_mask
+ else if ext = 'GL_SGIS_texture_edge_clamp' then Result := Load_GL_SGIS_texture_edge_clamp
+ else if ext = 'GL_SGIS_texture_lod' then Result := Load_GL_SGIS_texture_lod
+ else if ext = 'GL_SGIS_depth_texture' then Result := Load_GL_SGIS_depth_texture
+ else if ext = 'GL_SGIX_fog_offset' then Result := Load_GL_SGIX_fog_offset
+ else if ext = 'GL_SGIX_interlace' then Result := Load_GL_SGIX_interlace
+ else if ext = 'GL_SGIX_shadow_ambient' then Result := Load_GL_SGIX_shadow_ambient
+ else if ext = 'GL_SGI_color_matrix' then Result := Load_GL_SGI_color_matrix
+ else if ext = 'GL_SGI_color_table' then Result := Load_GL_SGI_color_table
+ else if ext = 'GL_SGI_texture_color_table' then Result := Load_GL_SGI_texture_color_table
+ else if ext = 'GL_SUN_vertex' then Result := Load_GL_SUN_vertex
+ else if ext = 'GL_ARB_fragment_program' then Result := Load_GL_ARB_fragment_program
+ else if ext = 'GL_ATI_text_fragment_shader' then Result := Load_GL_ATI_text_fragment_shader
+ else if ext = 'GL_APPLE_client_storage' then Result := Load_GL_APPLE_client_storage
+ else if ext = 'GL_APPLE_element_array' then Result := Load_GL_APPLE_element_array
+ else if ext = 'GL_APPLE_fence' then Result := Load_GL_APPLE_fence
+ else if ext = 'GL_APPLE_vertex_array_object' then Result := Load_GL_APPLE_vertex_array_object
+ else if ext = 'GL_APPLE_vertex_array_range' then Result := Load_GL_APPLE_vertex_array_range
+ {$IFDEF WINDOWS}
+ else if ext = 'WGL_ARB_pixel_format' then Result := Load_WGL_ARB_pixel_format
+ else if ext = 'WGL_ARB_make_current_read' then Result := Load_WGL_ARB_make_current_read
+ else if ext = 'WGL_ARB_pbuffer' then Result := Load_WGL_ARB_pbuffer
+ else if ext = 'WGL_EXT_swap_control' then Result := Load_WGL_EXT_swap_control
+ else if ext = 'WGL_ARB_render_texture' then Result := Load_WGL_ARB_render_texture
+ else if ext = 'WGL_EXT_extensions_string' then Result := Load_WGL_EXT_extensions_string
+ else if ext = 'WGL_EXT_make_current_read' then Result := Load_WGL_EXT_make_current_read
+ else if ext = 'WGL_EXT_pbuffer' then Result := Load_WGL_EXT_pbuffer
+ else if ext = 'WGL_EXT_pixel_format' then Result := Load_WGL_EXT_pixel_format
+ else if ext = 'WGL_I3D_digital_video_control' then Result := Load_WGL_I3D_digital_video_control
+ else if ext = 'WGL_I3D_gamma' then Result := Load_WGL_I3D_gamma
+ else if ext = 'WGL_I3D_genlock' then Result := Load_WGL_I3D_genlock
+ {$ENDIF}
+ else if ext = 'GL_ARB_matrix_palette' then Result := Load_GL_ARB_matrix_palette
+ else if ext = 'GL_NV_element_array' then Result := Load_GL_NV_element_array
+ else if ext = 'GL_NV_float_buffer' then Result := Load_GL_NV_float_buffer
+ else if ext = 'GL_NV_fragment_program' then Result := Load_GL_NV_fragment_program
+ else if ext = 'GL_NV_primitive_restart' then Result := Load_GL_NV_primitive_restart
+ else if ext = 'GL_NV_vertex_program2' then Result := Load_GL_NV_vertex_program2
+ {$IFDEF WINDOWS}
+ else if ext = 'WGL_NV_render_texture_rectangle' then Result := Load_WGL_NV_render_texture_rectangle
+ {$ENDIF}
+ else if ext = 'GL_NV_pixel_data_range' then Result := Load_GL_NV_pixel_data_range
+ else if ext = 'GL_EXT_texture_rectangle' then Result := Load_GL_EXT_texture_rectangle
+ else if ext = 'GL_S3_s3tc' then Result := Load_GL_S3_s3tc
+ else if ext = 'GL_ATI_draw_buffers' then Result := Load_GL_ATI_draw_buffers
+ {$IFDEF WINDOWS}
+ else if ext = 'WGL_ATI_pixel_format_float' then Result := Load_WGL_ATI_pixel_format_float
+ {$ENDIF}
+ else if ext = 'GL_ATI_texture_env_combine3' then Result := Load_GL_ATI_texture_env_combine3
+ else if ext = 'GL_ATI_texture_float' then Result := Load_GL_ATI_texture_float
+ else if ext = 'GL_NV_texture_expand_normal' then Result := Load_GL_NV_texture_expand_normal
+ else if ext = 'GL_NV_half_float' then Result := Load_GL_NV_half_float
+ else if ext = 'GL_ATI_map_object_buffer' then Result := Load_GL_ATI_map_object_buffer
+ else if ext = 'GL_ATI_separate_stencil' then Result := Load_GL_ATI_separate_stencil
+ else if ext = 'GL_ATI_vertex_attrib_array_object' then Result := Load_GL_ATI_vertex_attrib_array_object
+ else if ext = 'GL_ARB_vertex_buffer_object' then Result := Load_GL_ARB_vertex_buffer_object
+ else if ext = 'GL_ARB_occlusion_query' then Result := Load_GL_ARB_occlusion_query
+ else if ext = 'GL_ARB_shader_objects' then Result := Load_GL_ARB_shader_objects
+ else if ext = 'GL_ARB_vertex_shader' then Result := Load_GL_ARB_vertex_shader
+ else if ext = 'GL_ARB_fragment_shader' then Result := Load_GL_ARB_fragment_shader
+ else if ext = 'GL_ARB_shading_language_100' then Result := Load_GL_ARB_shading_language_100
+ else if ext = 'GL_ARB_texture_non_power_of_two' then Result := Load_GL_ARB_texture_non_power_of_two
+ else if ext = 'GL_ARB_point_sprite' then Result := Load_GL_ARB_point_sprite
+ else if ext = 'GL_EXT_depth_bounds_test' then Result := Load_GL_EXT_depth_bounds_test
+ else if ext = 'GL_EXT_secondary_color' then Result := Load_GL_EXT_secondary_color
+ else if ext = 'GL_EXT_texture_mirror_clamp' then Result := Load_GL_EXT_texture_mirror_clamp
+ else if ext = 'GL_EXT_blend_equation_separate' then Result := Load_GL_EXT_blend_equation_separate
+ else if ext = 'GL_MESA_pack_invert' then Result := Load_GL_MESA_pack_invert
+ else if ext = 'GL_MESA_ycbcr_texture' then Result := Load_GL_MESA_ycbcr_texture
+ else if ext = 'GL_ARB_fragment_program_shadow' then Result := Load_GL_ARB_fragment_program_shadow
+ else if ext = 'GL_EXT_fog_coord' then Result := Load_GL_EXT_fog_coord
+ else if ext = 'GL_NV_fragment_program_option' then Result := Load_GL_NV_fragment_program_option
+ else if ext = 'GL_EXT_pixel_buffer_object' then Result := Load_GL_EXT_pixel_buffer_object
+ else if ext = 'GL_NV_fragment_program2' then Result := Load_GL_NV_fragment_program2
+ else if ext = 'GL_NV_vertex_program2_option' then Result := Load_GL_NV_vertex_program2_option
+ else if ext = 'GL_NV_vertex_program3' then Result := Load_GL_NV_vertex_program3
+ else if ext = 'GL_ARB_draw_buffers' then Result := Load_GL_ARB_draw_buffers
+ else if ext = 'GL_ARB_texture_rectangle' then Result := Load_GL_ARB_texture_rectangle
+ else if ext = 'GL_ARB_color_buffer_float' then Result := Load_GL_ARB_color_buffer_float
+ else if ext = 'GL_ARB_half_float_pixel' then Result := Load_GL_ARB_half_float_pixel
+ else if ext = 'GL_ARB_texture_float' then Result := Load_GL_ARB_texture_float
+ else if ext = 'GL_EXT_texture_compression_dxt1' then Result := Load_GL_EXT_texture_compression_dxt1
+ else if ext = 'GL_ARB_pixel_buffer_object' then Result := Load_GL_ARB_pixel_buffer_object
+ else if ext = 'GL_EXT_framebuffer_object' then Result := Load_GL_EXT_framebuffer_object
+ else if ext = 'GL_version_1_4' then Result := Load_GL_version_1_4
+ else if ext = 'GL_version_1_5' then Result := Load_GL_version_1_5
+ else if ext = 'GL_version_2_0' then Result := Load_GL_version_2_0
+
+end;
+
+end.
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/glu.pas b/src/lib/JEDI-SDL/OpenGL/Pas/glu.pas
new file mode 100644
index 00000000..29647d12
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/glu.pas
@@ -0,0 +1,582 @@
+unit glu;
+{
+ $Id: glu.pas,v 1.8 2007/05/20 20:28:31 savage Exp $
+
+ Adaption of the delphi3d.net OpenGL units to FreePascal
+ Sebastian Guenther (sg@freepascal.org) in 2002
+ These units are free to use
+}
+
+(*++ BUILD Version: 0004 // Increment this if a change has global effects
+
+Copyright (c) 1985-95, Microsoft Corporation
+
+Module Name:
+
+ glu.h
+
+Abstract:
+
+ Procedure declarations, constant definitions and macros for the OpenGL
+ Utility Library.
+
+--*)
+
+(*
+** Copyright 1991-1993, Silicon Graphics, Inc.
+** All Rights Reserved.
+**
+** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
+** the contents of this file may not be disclosed to third parties, copied or
+** duplicated in any form, in whole or in part, without the prior written
+** permission of Silicon Graphics, Inc.
+**
+** RESTRICTED RIGHTS LEGEND:
+** Use, duplication or disclosure by the Government is subject to restrictions
+** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
+** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
+** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
+** rights reserved under the Copyright Laws of the United States.
+*)
+
+(*
+** Return the error string associated with a particular error code.
+** This will return 0 for an invalid error code.
+**
+** The generic function prototype that can be compiled for ANSI or Unicode
+** is defined as follows:
+**
+** LPCTSTR APIENTRY gluErrorStringWIN (GLenum errCode);
+*)
+
+{******************************************************************************}
+{ }
+{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
+{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
+{ }
+{ Modified for Delphi/Kylix and FreePascal }
+{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
+{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
+{ }
+{******************************************************************************}
+
+{
+ $Log: glu.pas,v $
+ Revision 1.8 2007/05/20 20:28:31 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.7 2006/11/26 16:35:49 savage
+ Messed up the last change to GLUtessCombineDataProc, had to reapply it. Thanks Michalis.
+
+ Revision 1.6 2006/11/25 23:38:02 savage
+ Changes as proposed by Michalis Kamburelis for better FPC support
+
+ Revision 1.5 2006/11/20 21:20:59 savage
+ Updated to work in MacOS X
+
+ Revision 1.4 2005/05/22 18:52:09 savage
+ Changes as suggested by Michalis Kamburelis. Thanks again.
+
+ Revision 1.3 2004/10/07 21:01:29 savage
+ Fix for FPC
+
+ Revision 1.2 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.1 2004/03/30 21:53:54 savage
+ Moved to it's own folder.
+
+ Revision 1.4 2004/02/20 17:09:55 savage
+ Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
+
+ Revision 1.3 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+ Revision 1.2 2004/02/14 00:09:19 savage
+ Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+ Revision 1.4 2003/06/02 12:32:13 savage
+ Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
+
+ Revision 1.3 2003/05/29 22:55:00 savage
+ Make use of new DLLFunctions
+
+ Revision 1.2 2003/05/27 09:39:53 savage
+ Added better Gnu Pascal support.
+
+ Revision 1.1 2003/05/11 13:18:03 savage
+ Newest OpenGL Headers For Delphi, Kylix and FPC
+
+ Revision 1.2 2002/10/13 14:36:47 sg
+ * Win32 fix: The OS symbol is called "Win32", not "Windows"
+
+ Revision 1.1 2002/10/13 13:57:31 sg
+ * Finally, the new units are available: Match the C headers more closely;
+ support for OpenGL extensions, and much more. Based on the Delphi units
+ by Tom Nuydens of delphi3d.net
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+ moduleloader,
+ gl;
+
+const
+{$IFDEF WINDOWS}
+ GLuLibName = 'glu32.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ GLuLibName = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib';
+{$ELSE}
+ GLuLibName = 'libGLU.so';
+{$ENDIF}
+{$ENDIF}
+
+type
+ TViewPortArray = array[ 0..3 ] of GLint;
+ T16dArray = array[ 0..15 ] of GLdouble;
+ TCallBack = procedure;
+ T3dArray = array[ 0..2 ] of GLdouble;
+ T4pArray = array[ 0..3 ] of Pointer;
+ T4fArray = array[ 0..3 ] of GLfloat;
+{$IFNDEF __GPC__}
+ PPointer = ^Pointer;
+{$ENDIF}
+
+var
+ gluErrorString : function( errCode : GLenum ) : PChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluErrorUnicodeStringEXT : function( errCode : GLenum ) : PWideChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluGetString : function( name : GLenum ) : PChar; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluOrtho2D : procedure( left, right, bottom, top : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluPerspective : procedure( fovy, aspect, zNear, zFar : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluPickMatrix : procedure( x, y, width, height : GLdouble; var viewport : TViewPortArray ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluLookAt : procedure( eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluProject : function( objx, objy, objz : GLdouble; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray; winx, winy, winz : PGLdouble ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluUnProject : function( winx, winy, winz : GLdouble; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray; objx, objy, objz : PGLdouble ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluScaleImage : function( format : GLenum; widthin, heightin : GLint; typein : GLenum; const datain : Pointer; widthout, heightout : GLint; typeout : GLenum; dataout : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluBuild1DMipmaps : function( target : GLenum; components, width : GLint; format, atype : GLenum; const data : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluBuild2DMipmaps : function( target : GLenum; components, width, height : GLint; format, atype : GLenum; const data : Pointer ) : Integer; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+type
+ GLUnurbs = record
+ end; PGLUnurbs = ^GLUnurbs;
+ GLUquadric = record
+ end; PGLUquadric = ^GLUquadric;
+ GLUtesselator = record
+ end; PGLUtesselator = ^GLUtesselator;
+
+ // backwards compatibility:
+ GLUnurbsObj = GLUnurbs; PGLUnurbsObj = PGLUnurbs;
+ GLUquadricObj = GLUquadric; PGLUquadricObj = PGLUquadric;
+ GLUtesselatorObj = GLUtesselator; PGLUtesselatorObj = PGLUtesselator;
+ GLUtriangulatorObj = GLUtesselator; PGLUtriangulatorObj = PGLUtesselator;
+
+var
+ gluNewQuadric : function : PGLUquadric; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluDeleteQuadric : procedure( state : PGLUquadric ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluQuadricNormals : procedure( quadObject : PGLUquadric; normals : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluQuadricTexture : procedure( quadObject : PGLUquadric; textureCoords : GLboolean ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluQuadricOrientation : procedure( quadObject : PGLUquadric; orientation : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluQuadricDrawStyle : procedure( quadObject : PGLUquadric; drawStyle : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluCylinder : procedure( qobj : PGLUquadric; baseRadius, topRadius, height : GLdouble; slices, stacks : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluDisk : procedure( qobj : PGLUquadric; innerRadius, outerRadius : GLdouble; slices, loops : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluPartialDisk : procedure( qobj : PGLUquadric; innerRadius, outerRadius : GLdouble; slices, loops : GLint; startAngle, sweepAngle : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluSphere : procedure( qobj : PGLuquadric; radius : GLdouble; slices, stacks : GLint ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluQuadricCallback : procedure( qobj : PGLUquadric; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNewTess : function : PGLUtesselator; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluDeleteTess : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessBeginPolygon : procedure( tess : PGLUtesselator; polygon_data : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessBeginContour : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessVertex : procedure( tess : PGLUtesselator; var coords : T3dArray; data : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessEndContour : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessEndPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessProperty : procedure( tess : PGLUtesselator; which : GLenum; value : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessNormal : procedure( tess : PGLUtesselator; x, y, z : GLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluTessCallback : procedure( tess : PGLUtesselator; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluGetTessProperty : procedure( tess : PGLUtesselator; which : GLenum; value : PGLdouble ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNewNurbsRenderer : function : PGLUnurbs; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluDeleteNurbsRenderer : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluBeginSurface : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluBeginCurve : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluEndCurve : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluEndSurface : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluBeginTrim : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluEndTrim : procedure( nobj : PGLUnurbs ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluPwlCurve : procedure( nobj : PGLUnurbs; count : GLint; aarray : PGLfloat; stride : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNurbsCurve : procedure( nobj : PGLUnurbs; nknots : GLint; knot : PGLfloat; stride : GLint; ctlarray : PGLfloat; order : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNurbsSurface : procedure( nobj : PGLUnurbs; sknot_count : GLint; sknot : PGLfloat; tknot_count : GLint; tknot : PGLfloat; s_stride, t_stride : GLint; ctlarray : PGLfloat; sorder, torder : GLint; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluLoadSamplingMatrices : procedure( nobj : PGLUnurbs; var modelMatrix, projMatrix : T16dArray; var viewport : TViewPortArray ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNurbsProperty : procedure( nobj : PGLUnurbs; aproperty : GLenum; value : GLfloat ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluGetNurbsProperty : procedure( nobj : PGLUnurbs; aproperty : GLenum; value : PGLfloat ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNurbsCallback : procedure( nobj : PGLUnurbs; which : GLenum; fn : TCallBack ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+(**** Callback function prototypes ****)
+
+type
+ // gluQuadricCallback
+ GLUquadricErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // gluTessCallback
+ GLUtessBeginProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessEdgeFlagProc = procedure( p : GLboolean ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessVertexProc = procedure( p : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessEndProc = procedure; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessCombineProc = procedure( var p1 : T3dArray; p2 : T4pArray; p3 : T4fArray; p4 : PPointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessBeginDataProc = procedure( p1 : GLenum; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessEdgeFlagDataProc = procedure( p1 : GLboolean; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessVertexDataProc = procedure( p1, p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessEndDataProc = procedure( p : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessErrorDataProc = procedure( p1 : GLenum; p2 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ GLUtessCombineDataProc = procedure( var p1 : T3dArray; var p2 : T4pArray; var p3 : T4fArray;
+ p4 : PPointer; p5 : Pointer ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // gluNurbsCallback
+ GLUnurbsErrorProc = procedure( p : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+
+//*** Generic constants ****/
+
+const
+ // Version
+ GLU_VERSION_1_1 = 1;
+ GLU_VERSION_1_2 = 1;
+
+ // Errors: (return value 0 = no error)
+ GLU_INVALID_ENUM = 100900;
+ GLU_INVALID_VALUE = 100901;
+ GLU_OUT_OF_MEMORY = 100902;
+ GLU_INCOMPATIBLE_GL_VERSION = 100903;
+
+ // StringName
+ GLU_VERSION = 100800;
+ GLU_EXTENSIONS = 100801;
+
+ // Boolean
+ GLU_TRUE = GL_TRUE;
+ GLU_FALSE = GL_FALSE;
+
+
+ //*** Quadric constants ****/
+
+ // QuadricNormal
+ GLU_SMOOTH = 100000;
+ GLU_FLAT = 100001;
+ GLU_NONE = 100002;
+
+ // QuadricDrawStyle
+ GLU_POINT = 100010;
+ GLU_LINE = 100011;
+ GLU_FILL = 100012;
+ GLU_SILHOUETTE = 100013;
+
+ // QuadricOrientation
+ GLU_OUTSIDE = 100020;
+ GLU_INSIDE = 100021;
+
+ // Callback types:
+ // GLU_ERROR = 100103;
+
+
+ //*** Tesselation constants ****/
+
+ GLU_TESS_MAX_COORD = 1.0E150;
+
+ // TessProperty
+ GLU_TESS_WINDING_RULE = 100140;
+ GLU_TESS_BOUNDARY_ONLY = 100141;
+ GLU_TESS_TOLERANCE = 100142;
+
+ // TessWinding
+ GLU_TESS_WINDING_ODD = 100130;
+ GLU_TESS_WINDING_NONZERO = 100131;
+ GLU_TESS_WINDING_POSITIVE = 100132;
+ GLU_TESS_WINDING_NEGATIVE = 100133;
+ GLU_TESS_WINDING_ABS_GEQ_TWO = 100134;
+
+ // TessCallback
+ GLU_TESS_BEGIN = 100100; // void (CALLBACK*)(GLenum type)
+ GLU_TESS_VERTEX = 100101; // void (CALLBACK*)(void *data)
+ GLU_TESS_END = 100102; // void (CALLBACK*)(void)
+ GLU_TESS_ERROR = 100103; // void (CALLBACK*)(GLenum errno)
+ GLU_TESS_EDGE_FLAG = 100104; // void (CALLBACK*)(GLboolean boundaryEdge)
+ GLU_TESS_COMBINE = 100105; { void (CALLBACK*)(GLdouble coords[3],
+ void *data[4],
+ GLfloat weight[4],
+ void **dataOut) }
+ GLU_TESS_BEGIN_DATA = 100106; { void (CALLBACK*)(GLenum type,
+ void *polygon_data) }
+ GLU_TESS_VERTEX_DATA = 100107; { void (CALLBACK*)(void *data,
+ void *polygon_data) }
+ GLU_TESS_END_DATA = 100108; // void (CALLBACK*)(void *polygon_data)
+ GLU_TESS_ERROR_DATA = 100109; { void (CALLBACK*)(GLenum errno,
+ void *polygon_data) }
+ GLU_TESS_EDGE_FLAG_DATA = 100110; { void (CALLBACK*)(GLboolean boundaryEdge,
+ void *polygon_data) }
+ GLU_TESS_COMBINE_DATA = 100111; { void (CALLBACK*)(GLdouble coords[3],
+ void *data[4],
+ GLfloat weight[4],
+ void **dataOut,
+ void *polygon_data) }
+
+ // TessError
+ GLU_TESS_ERROR1 = 100151;
+ GLU_TESS_ERROR2 = 100152;
+ GLU_TESS_ERROR3 = 100153;
+ GLU_TESS_ERROR4 = 100154;
+ GLU_TESS_ERROR5 = 100155;
+ GLU_TESS_ERROR6 = 100156;
+ GLU_TESS_ERROR7 = 100157;
+ GLU_TESS_ERROR8 = 100158;
+
+ GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1;
+ GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2;
+ GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3;
+ GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4;
+ GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5;
+ GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6;
+
+ //*** NURBS constants ****/
+
+ // NurbsProperty
+ GLU_AUTO_LOAD_MATRIX = 100200;
+ GLU_CULLING = 100201;
+ GLU_SAMPLING_TOLERANCE = 100203;
+ GLU_DISPLAY_MODE = 100204;
+ GLU_PARAMETRIC_TOLERANCE = 100202;
+ GLU_SAMPLING_METHOD = 100205;
+ GLU_U_STEP = 100206;
+ GLU_V_STEP = 100207;
+
+ // NurbsSampling
+ GLU_PATH_LENGTH = 100215;
+ GLU_PARAMETRIC_ERROR = 100216;
+ GLU_DOMAIN_DISTANCE = 100217;
+
+
+ // NurbsTrim
+ GLU_MAP1_TRIM_2 = 100210;
+ GLU_MAP1_TRIM_3 = 100211;
+
+ // NurbsDisplay
+ // GLU_FILL = 100012;
+ GLU_OUTLINE_POLYGON = 100240;
+ GLU_OUTLINE_PATCH = 100241;
+
+ // NurbsCallback
+ // GLU_ERROR = 100103;
+
+ // NurbsErrors
+ GLU_NURBS_ERROR1 = 100251;
+ GLU_NURBS_ERROR2 = 100252;
+ GLU_NURBS_ERROR3 = 100253;
+ GLU_NURBS_ERROR4 = 100254;
+ GLU_NURBS_ERROR5 = 100255;
+ GLU_NURBS_ERROR6 = 100256;
+ GLU_NURBS_ERROR7 = 100257;
+ GLU_NURBS_ERROR8 = 100258;
+ GLU_NURBS_ERROR9 = 100259;
+ GLU_NURBS_ERROR10 = 100260;
+ GLU_NURBS_ERROR11 = 100261;
+ GLU_NURBS_ERROR12 = 100262;
+ GLU_NURBS_ERROR13 = 100263;
+ GLU_NURBS_ERROR14 = 100264;
+ GLU_NURBS_ERROR15 = 100265;
+ GLU_NURBS_ERROR16 = 100266;
+ GLU_NURBS_ERROR17 = 100267;
+ GLU_NURBS_ERROR18 = 100268;
+ GLU_NURBS_ERROR19 = 100269;
+ GLU_NURBS_ERROR20 = 100270;
+ GLU_NURBS_ERROR21 = 100271;
+ GLU_NURBS_ERROR22 = 100272;
+ GLU_NURBS_ERROR23 = 100273;
+ GLU_NURBS_ERROR24 = 100274;
+ GLU_NURBS_ERROR25 = 100275;
+ GLU_NURBS_ERROR26 = 100276;
+ GLU_NURBS_ERROR27 = 100277;
+ GLU_NURBS_ERROR28 = 100278;
+ GLU_NURBS_ERROR29 = 100279;
+ GLU_NURBS_ERROR30 = 100280;
+ GLU_NURBS_ERROR31 = 100281;
+ GLU_NURBS_ERROR32 = 100282;
+ GLU_NURBS_ERROR33 = 100283;
+ GLU_NURBS_ERROR34 = 100284;
+ GLU_NURBS_ERROR35 = 100285;
+ GLU_NURBS_ERROR36 = 100286;
+ GLU_NURBS_ERROR37 = 100287;
+
+//*** Backwards compatibility for old tesselator ****/
+
+var
+ gluBeginPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluNextContour : procedure( tess : PGLUtesselator; atype : GLenum ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+ gluEndPolygon : procedure( tess : PGLUtesselator ); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+const
+ // Contours types -- obsolete!
+ GLU_CW = 100120;
+ GLU_CCW = 100121;
+ GLU_INTERIOR = 100122;
+ GLU_EXTERIOR = 100123;
+ GLU_UNKNOWN = 100124;
+
+ // Names without "TESS_" prefix
+ GLU_BEGIN = GLU_TESS_BEGIN;
+ GLU_VERTEX = GLU_TESS_VERTEX;
+ GLU_END = GLU_TESS_END;
+ GLU_ERROR = GLU_TESS_ERROR;
+ GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG;
+
+procedure LoadGLu( const dll : PChar );
+procedure FreeGLu;
+
+implementation
+
+var
+ LibGlu : TModuleHandle;
+
+procedure FreeGLu;
+begin
+
+ @gluErrorString := nil;
+ @gluErrorUnicodeStringEXT := nil;
+ @gluGetString := nil;
+ @gluOrtho2D := nil;
+ @gluPerspective := nil;
+ @gluPickMatrix := nil;
+ @gluLookAt := nil;
+ @gluProject := nil;
+ @gluUnProject := nil;
+ @gluScaleImage := nil;
+ @gluBuild1DMipmaps := nil;
+ @gluBuild2DMipmaps := nil;
+ @gluNewQuadric := nil;
+ @gluDeleteQuadric := nil;
+ @gluQuadricNormals := nil;
+ @gluQuadricTexture := nil;
+ @gluQuadricOrientation := nil;
+ @gluQuadricDrawStyle := nil;
+ @gluCylinder := nil;
+ @gluDisk := nil;
+ @gluPartialDisk := nil;
+ @gluSphere := nil;
+ @gluQuadricCallback := nil;
+ @gluNewTess := nil;
+ @gluDeleteTess := nil;
+ @gluTessBeginPolygon := nil;
+ @gluTessBeginContour := nil;
+ @gluTessVertex := nil;
+ @gluTessEndContour := nil;
+ @gluTessEndPolygon := nil;
+ @gluTessProperty := nil;
+ @gluTessNormal := nil;
+ @gluTessCallback := nil;
+ @gluGetTessProperty := nil;
+ @gluNewNurbsRenderer := nil;
+ @gluDeleteNurbsRenderer := nil;
+ @gluBeginSurface := nil;
+ @gluBeginCurve := nil;
+ @gluEndCurve := nil;
+ @gluEndSurface := nil;
+ @gluBeginTrim := nil;
+ @gluEndTrim := nil;
+ @gluPwlCurve := nil;
+ @gluNurbsCurve := nil;
+ @gluNurbsSurface := nil;
+ @gluLoadSamplingMatrices := nil;
+ @gluNurbsProperty := nil;
+ @gluGetNurbsProperty := nil;
+ @gluNurbsCallback := nil;
+ @gluBeginPolygon := nil;
+ @gluNextContour := nil;
+ @gluEndPolygon := nil;
+
+ UnLoadModule( LibGlu );
+
+end;
+
+procedure LoadGLu( const dll : PChar );
+begin
+
+ FreeGLu;
+
+ if LoadModule( LibGlu, dll ) then
+ begin
+ @gluErrorString := GetModuleSymbol( LibGlu, 'gluErrorString' );
+ @gluErrorUnicodeStringEXT := GetModuleSymbol( LibGlu, 'gluErrorUnicodeStringEXT' );
+ @gluGetString := GetModuleSymbol( LibGlu, 'gluGetString' );
+ @gluOrtho2D := GetModuleSymbol( LibGlu, 'gluOrtho2D' );
+ @gluPerspective := GetModuleSymbol( LibGlu, 'gluPerspective' );
+ @gluPickMatrix := GetModuleSymbol( LibGlu, 'gluPickMatrix' );
+ @gluLookAt := GetModuleSymbol( LibGlu, 'gluLookAt' );
+ @gluProject := GetModuleSymbol( LibGlu, 'gluProject' );
+ @gluUnProject := GetModuleSymbol( LibGlu, 'gluUnProject' );
+ @gluScaleImage := GetModuleSymbol( LibGlu, 'gluScaleImage' );
+ @gluBuild1DMipmaps := GetModuleSymbol( LibGlu, 'gluBuild1DMipmaps' );
+ @gluBuild2DMipmaps := GetModuleSymbol( LibGlu, 'gluBuild2DMipmaps' );
+ @gluNewQuadric := GetModuleSymbol( LibGlu, 'gluNewQuadric' );
+ @gluDeleteQuadric := GetModuleSymbol( LibGlu, 'gluDeleteQuadric' );
+ @gluQuadricNormals := GetModuleSymbol( LibGlu, 'gluQuadricNormals' );
+ @gluQuadricTexture := GetModuleSymbol( LibGlu, 'gluQuadricTexture' );
+ @gluQuadricOrientation := GetModuleSymbol( LibGlu, 'gluQuadricOrientation' );
+ @gluQuadricDrawStyle := GetModuleSymbol( LibGlu, 'gluQuadricDrawStyle' );
+ @gluCylinder := GetModuleSymbol( LibGlu, 'gluCylinder' );
+ @gluDisk := GetModuleSymbol( LibGlu, 'gluDisk' );
+ @gluPartialDisk := GetModuleSymbol( LibGlu, 'gluPartialDisk' );
+ @gluSphere := GetModuleSymbol( LibGlu, 'gluSphere' );
+ @gluQuadricCallback := GetModuleSymbol( LibGlu, 'gluQuadricCallback' );
+ @gluNewTess := GetModuleSymbol( LibGlu, 'gluNewTess' );
+ @gluDeleteTess := GetModuleSymbol( LibGlu, 'gluDeleteTess' );
+ @gluTessBeginPolygon := GetModuleSymbol( LibGlu, 'gluTessBeginPolygon' );
+ @gluTessBeginContour := GetModuleSymbol( LibGlu, 'gluTessBeginContour' );
+ @gluTessVertex := GetModuleSymbol( LibGlu, 'gluTessVertex' );
+ @gluTessEndContour := GetModuleSymbol( LibGlu, 'gluTessEndContour' );
+ @gluTessEndPolygon := GetModuleSymbol( LibGlu, 'gluTessEndPolygon' );
+ @gluTessProperty := GetModuleSymbol( LibGlu, 'gluTessProperty' );
+ @gluTessNormal := GetModuleSymbol( LibGlu, 'gluTessNormal' );
+ @gluTessCallback := GetModuleSymbol( LibGlu, 'gluTessCallback' );
+ @gluGetTessProperty := GetModuleSymbol( LibGlu, 'gluGetTessProperty' );
+ @gluNewNurbsRenderer := GetModuleSymbol( LibGlu, 'gluNewNurbsRenderer' );
+ @gluDeleteNurbsRenderer := GetModuleSymbol( LibGlu, 'gluDeleteNurbsRenderer' );
+ @gluBeginSurface := GetModuleSymbol( LibGlu, 'gluBeginSurface' );
+ @gluBeginCurve := GetModuleSymbol( LibGlu, 'gluBeginCurve' );
+ @gluEndCurve := GetModuleSymbol( LibGlu, 'gluEndCurve' );
+ @gluEndSurface := GetModuleSymbol( LibGlu, 'gluEndSurface' );
+ @gluBeginTrim := GetModuleSymbol( LibGlu, 'gluBeginTrim' );
+ @gluEndTrim := GetModuleSymbol( LibGlu, 'gluEndTrim' );
+ @gluPwlCurve := GetModuleSymbol( LibGlu, 'gluPwlCurve' );
+ @gluNurbsCurve := GetModuleSymbol( LibGlu, 'gluNurbsCurve' );
+ @gluNurbsSurface := GetModuleSymbol( LibGlu, 'gluNurbsSurface' );
+ @gluLoadSamplingMatrices := GetModuleSymbol( LibGlu, 'gluLoadSamplingMatrices' );
+ @gluNurbsProperty := GetModuleSymbol( LibGlu, 'gluNurbsProperty' );
+ @gluGetNurbsProperty := GetModuleSymbol( LibGlu, 'gluGetNurbsProperty' );
+ @gluNurbsCallback := GetModuleSymbol( LibGlu, 'gluNurbsCallback' );
+
+ @gluBeginPolygon := GetModuleSymbol( LibGlu, 'gluBeginPolygon' );
+ @gluNextContour := GetModuleSymbol( LibGlu, 'gluNextContour' );
+ @gluEndPolygon := GetModuleSymbol( LibGlu, 'gluEndPolygon' );
+ end;
+end;
+
+initialization
+
+ LoadGLu( GLuLibName );
+
+finalization
+
+ FreeGLu;
+
+end.
+
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/glut.pas b/src/lib/JEDI-SDL/OpenGL/Pas/glut.pas
new file mode 100644
index 00000000..04f69267
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/glut.pas
@@ -0,0 +1,688 @@
+unit glut;
+{
+ $Id: glut.pas,v 1.4 2007/05/20 20:28:31 savage Exp $
+
+ Adaption of the delphi3d.net OpenGL units to FreePascal
+ Sebastian Guenther (sg@freepascal.org) in 2002
+ These units are free to use
+}
+
+// Copyright (c) Mark J. Kilgard, 1994, 1995, 1996. */
+
+(* This program is freely distributable without licensing fees and is
+ provided without guarantee or warrantee expressed or implied. This
+ program is -not- in the public domain. *)
+
+{******************************************************************************}
+{ }
+{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) }
+{ For the latest updates, visit Delphi3D: http://www.delphi3d.net }
+{ }
+{ Modified for Delphi/Kylix and FreePascal }
+{ by Dominique Louis ( Dominique@Savagesoftware.com.au) }
+{ For the latest updates, visit JEDI-SDL : http://www.sf.net/projects/jedi-sdl }
+{ }
+{******************************************************************************}
+
+{
+ $Log: glut.pas,v $
+ Revision 1.4 2007/05/20 20:28:31 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.3 2006/11/20 21:20:59 savage
+ Updated to work in MacOS X
+
+ Revision 1.2 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.1 2004/03/30 21:53:54 savage
+ Moved to it's own folder.
+
+ Revision 1.5 2004/02/20 17:09:55 savage
+ Code tidied up in gl, glu and glut, while extensions in glext.pas are now loaded using SDL_GL_GetProcAddress, thus making it more cross-platform compatible, but now more tied to SDL.
+
+ Revision 1.4 2004/02/14 22:36:29 savage
+ Fixed inconsistencies of using LoadLibrary and LoadModule.
+ Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
+
+ Revision 1.3 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+ Revision 1.2 2004/02/14 00:09:19 savage
+ Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+ Revision 1.4 2003/06/02 12:32:13 savage
+ Modified Sources to avoid warnings with Delphi by moving CVS Logging to the top of the header files. Hopefully CVS Logging still works.
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+uses
+{$IFDEF __GPC__}
+ system,
+ gpc,
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+ Windows,
+{$ENDIF}
+ moduleloader,
+ gl;
+
+type
+ {$IFNDEF __GPC__}
+ PInteger = ^Integer;
+ PPChar = ^PChar;
+ {$ENDIF}
+ TGlutVoidCallback = procedure; {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+ TGlut1IntCallback = procedure(value: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+ TGlut2IntCallback = procedure(v1, v2: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+ TGlut3IntCallback = procedure(v1, v2, v3: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+ TGlut4IntCallback = procedure(v1, v2, v3, v4: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+ TGlut1Char2IntCallback = procedure(c: Byte; v1, v2: Integer); {$IFNDEF __GPC__}{$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}{$ENDIF}
+
+const
+{$IFDEF WINDOWS}
+ GlutLibName = 'glut32.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ GlutLibName = '/System/Library/Frameworks/GLUT.framework/Libraries/libglut.dylib';
+{$ELSE}
+ GlutLibName = 'libglut.so';
+{$ENDIF}
+{$ENDIF}
+
+ GLUT_API_VERSION = 3;
+ GLUT_XLIB_IMPLEMENTATION = 12;
+ // Display mode bit masks.
+ GLUT_RGB = 0;
+ GLUT_RGBA = GLUT_RGB;
+ GLUT_INDEX = 1;
+ GLUT_SINGLE = 0;
+ GLUT_DOUBLE = 2;
+ GLUT_ACCUM = 4;
+ GLUT_ALPHA = 8;
+ GLUT_DEPTH = 16;
+ GLUT_STENCIL = 32;
+ GLUT_MULTISAMPLE = 128;
+ GLUT_STEREO = 256;
+ GLUT_LUMINANCE = 512;
+
+ // Mouse buttons.
+ GLUT_LEFT_BUTTON = 0;
+ GLUT_MIDDLE_BUTTON = 1;
+ GLUT_RIGHT_BUTTON = 2;
+
+ // Mouse button state.
+ GLUT_DOWN = 0;
+ GLUT_UP = 1;
+
+ // function keys
+ GLUT_KEY_F1 = 1;
+ GLUT_KEY_F2 = 2;
+ GLUT_KEY_F3 = 3;
+ GLUT_KEY_F4 = 4;
+ GLUT_KEY_F5 = 5;
+ GLUT_KEY_F6 = 6;
+ GLUT_KEY_F7 = 7;
+ GLUT_KEY_F8 = 8;
+ GLUT_KEY_F9 = 9;
+ GLUT_KEY_F10 = 10;
+ GLUT_KEY_F11 = 11;
+ GLUT_KEY_F12 = 12;
+ // directional keys
+ GLUT_KEY_LEFT = 100;
+ GLUT_KEY_UP = 101;
+ GLUT_KEY_RIGHT = 102;
+ GLUT_KEY_DOWN = 103;
+ GLUT_KEY_PAGE_UP = 104;
+ GLUT_KEY_PAGE_DOWN = 105;
+ GLUT_KEY_HOME = 106;
+ GLUT_KEY_END = 107;
+ GLUT_KEY_INSERT = 108;
+
+ // Entry/exit state.
+ GLUT_LEFT = 0;
+ GLUT_ENTERED = 1;
+
+ // Menu usage state.
+ GLUT_MENU_NOT_IN_USE = 0;
+ GLUT_MENU_IN_USE = 1;
+
+ // Visibility state.
+ GLUT_NOT_VISIBLE = 0;
+ GLUT_VISIBLE = 1;
+
+ // Window status state.
+ GLUT_HIDDEN = 0;
+ GLUT_FULLY_RETAINED = 1;
+ GLUT_PARTIALLY_RETAINED = 2;
+ GLUT_FULLY_COVERED = 3;
+
+ // Color index component selection values.
+ GLUT_RED = 0;
+ GLUT_GREEN = 1;
+ GLUT_BLUE = 2;
+
+ // Layers for use.
+ GLUT_NORMAL = 0;
+ GLUT_OVERLAY = 1;
+
+ // Stroke font constants (use these in GLUT program).
+ GLUT_STROKE_ROMAN = Pointer(0);
+ GLUT_STROKE_MONO_ROMAN = Pointer(1);
+
+ // Bitmap font constants (use these in GLUT program).
+ GLUT_BITMAP_9_BY_15 = Pointer(2);
+ GLUT_BITMAP_8_BY_13 = Pointer(3);
+ GLUT_BITMAP_TIMES_ROMAN_10 = Pointer(4);
+ GLUT_BITMAP_TIMES_ROMAN_24 = Pointer(5);
+ GLUT_BITMAP_HELVETICA_10 = Pointer(6);
+ GLUT_BITMAP_HELVETICA_12 = Pointer(7);
+ GLUT_BITMAP_HELVETICA_18 = Pointer(8);
+
+ // glutGet parameters.
+ GLUT_WINDOW_X = 100;
+ GLUT_WINDOW_Y = 101;
+ GLUT_WINDOW_WIDTH = 102;
+ GLUT_WINDOW_HEIGHT = 103;
+ GLUT_WINDOW_BUFFER_SIZE = 104;
+ GLUT_WINDOW_STENCIL_SIZE = 105;
+ GLUT_WINDOW_DEPTH_SIZE = 106;
+ GLUT_WINDOW_RED_SIZE = 107;
+ GLUT_WINDOW_GREEN_SIZE = 108;
+ GLUT_WINDOW_BLUE_SIZE = 109;
+ GLUT_WINDOW_ALPHA_SIZE = 110;
+ GLUT_WINDOW_ACCUM_RED_SIZE = 111;
+ GLUT_WINDOW_ACCUM_GREEN_SIZE = 112;
+ GLUT_WINDOW_ACCUM_BLUE_SIZE = 113;
+ GLUT_WINDOW_ACCUM_ALPHA_SIZE = 114;
+ GLUT_WINDOW_DOUBLEBUFFER = 115;
+ GLUT_WINDOW_RGBA = 116;
+ GLUT_WINDOW_PARENT = 117;
+ GLUT_WINDOW_NUM_CHILDREN = 118;
+ GLUT_WINDOW_COLORMAP_SIZE = 119;
+ GLUT_WINDOW_NUM_SAMPLES = 120;
+ GLUT_WINDOW_STEREO = 121;
+ GLUT_WINDOW_CURSOR = 122;
+ GLUT_SCREEN_WIDTH = 200;
+ GLUT_SCREEN_HEIGHT = 201;
+ GLUT_SCREEN_WIDTH_MM = 202;
+ GLUT_SCREEN_HEIGHT_MM = 203;
+ GLUT_MENU_NUM_ITEMS = 300;
+ GLUT_DISPLAY_MODE_POSSIBLE = 400;
+ GLUT_INIT_WINDOW_X = 500;
+ GLUT_INIT_WINDOW_Y = 501;
+ GLUT_INIT_WINDOW_WIDTH = 502;
+ GLUT_INIT_WINDOW_HEIGHT = 503;
+ GLUT_INIT_DISPLAY_MODE = 504;
+ GLUT_ELAPSED_TIME = 700;
+
+ // glutDeviceGet parameters.
+ GLUT_HAS_KEYBOARD = 600;
+ GLUT_HAS_MOUSE = 601;
+ GLUT_HAS_SPACEBALL = 602;
+ GLUT_HAS_DIAL_AND_BUTTON_BOX = 603;
+ GLUT_HAS_TABLET = 604;
+ GLUT_NUM_MOUSE_BUTTONS = 605;
+ GLUT_NUM_SPACEBALL_BUTTONS = 606;
+ GLUT_NUM_BUTTON_BOX_BUTTONS = 607;
+ GLUT_NUM_DIALS = 608;
+ GLUT_NUM_TABLET_BUTTONS = 609;
+
+ // glutLayerGet parameters.
+ GLUT_OVERLAY_POSSIBLE = 800;
+ GLUT_LAYER_IN_USE = 801;
+ GLUT_HAS_OVERLAY = 802;
+ GLUT_TRANSPARENT_INDEX = 803;
+ GLUT_NORMAL_DAMAGED = 804;
+ GLUT_OVERLAY_DAMAGED = 805;
+
+ // glutVideoResizeGet parameters.
+ GLUT_VIDEO_RESIZE_POSSIBLE = 900;
+ GLUT_VIDEO_RESIZE_IN_USE = 901;
+ GLUT_VIDEO_RESIZE_X_DELTA = 902;
+ GLUT_VIDEO_RESIZE_Y_DELTA = 903;
+ GLUT_VIDEO_RESIZE_WIDTH_DELTA = 904;
+ GLUT_VIDEO_RESIZE_HEIGHT_DELTA = 905;
+ GLUT_VIDEO_RESIZE_X = 906;
+ GLUT_VIDEO_RESIZE_Y = 907;
+ GLUT_VIDEO_RESIZE_WIDTH = 908;
+ GLUT_VIDEO_RESIZE_HEIGHT = 909;
+
+ // glutGetModifiers return mask.
+ GLUT_ACTIVE_SHIFT = 1;
+ GLUT_ACTIVE_CTRL = 2;
+ GLUT_ACTIVE_ALT = 4;
+
+ // glutSetCursor parameters.
+ // Basic arrows.
+ GLUT_CURSOR_RIGHT_ARROW = 0;
+ GLUT_CURSOR_LEFT_ARROW = 1;
+ // Symbolic cursor shapes.
+ GLUT_CURSOR_INFO = 2;
+ GLUT_CURSOR_DESTROY = 3;
+ GLUT_CURSOR_HELP = 4;
+ GLUT_CURSOR_CYCLE = 5;
+ GLUT_CURSOR_SPRAY = 6;
+ GLUT_CURSOR_WAIT = 7;
+ GLUT_CURSOR_TEXT = 8;
+ GLUT_CURSOR_CROSSHAIR = 9;
+ // Directional cursors.
+ GLUT_CURSOR_UP_DOWN = 10;
+ GLUT_CURSOR_LEFT_RIGHT = 11;
+ // Sizing cursors.
+ GLUT_CURSOR_TOP_SIDE = 12;
+ GLUT_CURSOR_BOTTOM_SIDE = 13;
+ GLUT_CURSOR_LEFT_SIDE = 14;
+ GLUT_CURSOR_RIGHT_SIDE = 15;
+ GLUT_CURSOR_TOP_LEFT_CORNER = 16;
+ GLUT_CURSOR_TOP_RIGHT_CORNER = 17;
+ GLUT_CURSOR_BOTTOM_RIGHT_CORNER = 18;
+ GLUT_CURSOR_BOTTOM_LEFT_CORNER = 19;
+ // Inherit from parent window.
+ GLUT_CURSOR_INHERIT = 100;
+ // Blank cursor.
+ GLUT_CURSOR_NONE = 101;
+ // Fullscreen crosshair (if available).
+ GLUT_CURSOR_FULL_CROSSHAIR = 102;
+
+ // GLUT game mode sub-API.
+ // glutGameModeGet.
+ GLUT_GAME_MODE_ACTIVE = 0;
+ GLUT_GAME_MODE_POSSIBLE = 1;
+ GLUT_GAME_MODE_WIDTH = 2;
+ GLUT_GAME_MODE_HEIGHT = 3;
+ GLUT_GAME_MODE_PIXEL_DEPTH = 4;
+ GLUT_GAME_MODE_REFRESH_RATE = 5;
+ GLUT_GAME_MODE_DISPLAY_CHANGED = 6;
+
+var
+// GLUT initialization sub-API.
+ glutInit: procedure(argcp: PInteger; argv: PPChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutInitDisplayMode: procedure(mode: Word); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutInitDisplayString: procedure(const str: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutInitWindowPosition: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutInitWindowSize: procedure(width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutMainLoop: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT window sub-API.
+ glutCreateWindow: function(const title: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutCreateSubWindow: function(win, x, y, width, height: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutDestroyWindow: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPostRedisplay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPostWindowRedisplay: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSwapBuffers: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutGetWindow: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetWindow: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetWindowTitle: procedure(const title: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetIconTitle: procedure(const title: PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPositionWindow: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutReshapeWindow: procedure(width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPopWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPushWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutIconifyWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutShowWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutHideWindow: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutFullScreen: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetCursor: procedure(cursor: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWarpPointer: procedure(x, y: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT overlay sub-API.
+ glutEstablishOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutRemoveOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutUseLayer: procedure(layer: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPostOverlayRedisplay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPostWindowOverlayRedisplay: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutShowOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutHideOverlay: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT menu sub-API.
+ glutCreateMenu: function(callback: TGlut1IntCallback): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutDestroyMenu: procedure(menu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutGetMenu: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetMenu: procedure(menu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutAddMenuEntry: procedure(const caption: PChar; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutAddSubMenu: procedure(const caption: PChar; submenu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutChangeToMenuEntry: procedure(item: Integer; const caption: PChar; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutChangeToSubMenu: procedure(item: Integer; const caption: PChar; submenu: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutRemoveMenuItem: procedure(item: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutAttachMenu: procedure(button: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutDetachMenu: procedure(button: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUTsub-API.
+ glutDisplayFunc: procedure(f: TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutReshapeFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutKeyboardFunc: procedure(f: TGlut1Char2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutMouseFunc: procedure(f: TGlut4IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutPassiveMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutEntryFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutVisibilityFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutIdleFunc: procedure(f: TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutTimerFunc: procedure(millis: Word; f: TGlut1IntCallback; value: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutMenuStateFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSpecialFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSpaceballMotionFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSpaceballRotateFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSpaceballButtonFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutButtonBoxFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutDialsFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutTabletMotionFunc: procedure(f: TGlut2IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutTabletButtonFunc: procedure(f: TGlut4IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutMenuStatusFunc: procedure(f: TGlut3IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutOverlayDisplayFunc: procedure(f:TGlutVoidCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWindowStatusFunc: procedure(f: TGlut1IntCallback); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT color index sub-API.
+ glutSetColor: procedure(cell: Integer; red, green, blue: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutGetColor: function(ndx, component: Integer): GLfloat; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutCopyColormap: procedure(win: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT state retrieval sub-API.
+ glutGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutDeviceGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT extension support sub-API
+ glutExtensionSupported: function(const name: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutGetModifiers: function: Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutLayerGet: function(t: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT font sub-API
+ glutBitmapCharacter: procedure(font : pointer; character: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutBitmapWidth: function(font : pointer; character: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutStrokeCharacter: procedure(font : pointer; character: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutStrokeWidth: function(font : pointer; character: Integer): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutBitmapLength: function(font: pointer; const str: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutStrokeLength: function(font: pointer; const str: PChar): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT pre-built models sub-API
+ glutWireSphere: procedure(radius: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidSphere: procedure(radius: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireCone: procedure(base, height: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidCone: procedure(base, height: GLdouble; slices, stacks: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireCube: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidCube: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireTorus: procedure(innerRadius, outerRadius: GLdouble; sides, rings: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidTorus: procedure(innerRadius, outerRadius: GLdouble; sides, rings: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireDodecahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidDodecahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireTeapot: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidTeapot: procedure(size: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireOctahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidOctahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireTetrahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidTetrahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutWireIcosahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSolidIcosahedron: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT video resize sub-API.
+ glutVideoResizeGet: function(param: GLenum): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutSetupVideoResizing: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutStopVideoResizing: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutVideoResize: procedure(x, y, width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutVideoPan: procedure(x, y, width, height: Integer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+// GLUT debugging sub-API.
+ glutReportErrors: procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+var
+ //example glutGameModeString('1280x1024:32@75');
+ glutGameModeString : procedure (const AString : PChar); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutEnterGameMode : function : integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutLeaveGameMode : procedure; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glutGameModeGet : function (mode : GLenum) : integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+procedure LoadGlut(const dll: PChar);
+procedure FreeGlut;
+
+implementation
+
+var
+ LibGLUT : TModuleHandle;
+
+procedure FreeGlut;
+begin
+
+ UnLoadModule( LibGLUT );
+
+ @glutInit := nil;
+ @glutInitDisplayMode := nil;
+ @glutInitDisplayString := nil;
+ @glutInitWindowPosition := nil;
+ @glutInitWindowSize := nil;
+ @glutMainLoop := nil;
+ @glutCreateWindow := nil;
+ @glutCreateSubWindow := nil;
+ @glutDestroyWindow := nil;
+ @glutPostRedisplay := nil;
+ @glutPostWindowRedisplay := nil;
+ @glutSwapBuffers := nil;
+ @glutGetWindow := nil;
+ @glutSetWindow := nil;
+ @glutSetWindowTitle := nil;
+ @glutSetIconTitle := nil;
+ @glutPositionWindow := nil;
+ @glutReshapeWindow := nil;
+ @glutPopWindow := nil;
+ @glutPushWindow := nil;
+ @glutIconifyWindow := nil;
+ @glutShowWindow := nil;
+ @glutHideWindow := nil;
+ @glutFullScreen := nil;
+ @glutSetCursor := nil;
+ @glutWarpPointer := nil;
+ @glutEstablishOverlay := nil;
+ @glutRemoveOverlay := nil;
+ @glutUseLayer := nil;
+ @glutPostOverlayRedisplay := nil;
+ @glutPostWindowOverlayRedisplay := nil;
+ @glutShowOverlay := nil;
+ @glutHideOverlay := nil;
+ @glutCreateMenu := nil;
+ @glutDestroyMenu := nil;
+ @glutGetMenu := nil;
+ @glutSetMenu := nil;
+ @glutAddMenuEntry := nil;
+ @glutAddSubMenu := nil;
+ @glutChangeToMenuEntry := nil;
+ @glutChangeToSubMenu := nil;
+ @glutRemoveMenuItem := nil;
+ @glutAttachMenu := nil;
+ @glutDetachMenu := nil;
+ @glutDisplayFunc := nil;
+ @glutReshapeFunc := nil;
+ @glutKeyboardFunc := nil;
+ @glutMouseFunc := nil;
+ @glutMotionFunc := nil;
+ @glutPassiveMotionFunc := nil;
+ @glutEntryFunc := nil;
+ @glutVisibilityFunc := nil;
+ @glutIdleFunc := nil;
+ @glutTimerFunc := nil;
+ @glutMenuStateFunc := nil;
+ @glutSpecialFunc := nil;
+ @glutSpaceballMotionFunc := nil;
+ @glutSpaceballRotateFunc := nil;
+ @glutSpaceballButtonFunc := nil;
+ @glutButtonBoxFunc := nil;
+ @glutDialsFunc := nil;
+ @glutTabletMotionFunc := nil;
+ @glutTabletButtonFunc := nil;
+ @glutMenuStatusFunc := nil;
+ @glutOverlayDisplayFunc := nil;
+ @glutWindowStatusFunc := nil;
+ @glutSetColor := nil;
+ @glutGetColor := nil;
+ @glutCopyColormap := nil;
+ @glutGet := nil;
+ @glutDeviceGet := nil;
+ @glutExtensionSupported := nil;
+ @glutGetModifiers := nil;
+ @glutLayerGet := nil;
+ @glutBitmapCharacter := nil;
+ @glutBitmapWidth := nil;
+ @glutStrokeCharacter := nil;
+ @glutStrokeWidth := nil;
+ @glutBitmapLength := nil;
+ @glutStrokeLength := nil;
+ @glutWireSphere := nil;
+ @glutSolidSphere := nil;
+ @glutWireCone := nil;
+ @glutSolidCone := nil;
+ @glutWireCube := nil;
+ @glutSolidCube := nil;
+ @glutWireTorus := nil;
+ @glutSolidTorus := nil;
+ @glutWireDodecahedron := nil;
+ @glutSolidDodecahedron := nil;
+ @glutWireTeapot := nil;
+ @glutSolidTeapot := nil;
+ @glutWireOctahedron := nil;
+ @glutSolidOctahedron := nil;
+ @glutWireTetrahedron := nil;
+ @glutSolidTetrahedron := nil;
+ @glutWireIcosahedron := nil;
+ @glutSolidIcosahedron := nil;
+ @glutVideoResizeGet := nil;
+ @glutSetupVideoResizing := nil;
+ @glutStopVideoResizing := nil;
+ @glutVideoResize := nil;
+ @glutVideoPan := nil;
+ @glutReportErrors := nil;
+
+end;
+
+procedure LoadGlut(const dll: PChar);
+begin
+
+ FreeGlut;
+
+ if LoadModule( LibGLUT, dll ) then
+ begin
+ @glutInit := GetModuleSymbol(LibGLUT, 'glutInit');
+ @glutInitDisplayMode := GetModuleSymbol(LibGLUT, 'glutInitDisplayMode');
+ @glutInitDisplayString := GetModuleSymbol(LibGLUT, 'glutInitDisplayString');
+ @glutInitWindowPosition := GetModuleSymbol(LibGLUT, 'glutInitWindowPosition');
+ @glutInitWindowSize := GetModuleSymbol(LibGLUT, 'glutInitWindowSize');
+ @glutMainLoop := GetModuleSymbol(LibGLUT, 'glutMainLoop');
+ @glutCreateWindow := GetModuleSymbol(LibGLUT, 'glutCreateWindow');
+ @glutCreateSubWindow := GetModuleSymbol(LibGLUT, 'glutCreateSubWindow');
+ @glutDestroyWindow := GetModuleSymbol(LibGLUT, 'glutDestroyWindow');
+ @glutPostRedisplay := GetModuleSymbol(LibGLUT, 'glutPostRedisplay');
+ @glutPostWindowRedisplay := GetModuleSymbol(LibGLUT, 'glutPostWindowRedisplay');
+ @glutSwapBuffers := GetModuleSymbol(LibGLUT, 'glutSwapBuffers');
+ @glutGetWindow := GetModuleSymbol(LibGLUT, 'glutGetWindow');
+ @glutSetWindow := GetModuleSymbol(LibGLUT, 'glutSetWindow');
+ @glutSetWindowTitle := GetModuleSymbol(LibGLUT, 'glutSetWindowTitle');
+ @glutSetIconTitle := GetModuleSymbol(LibGLUT, 'glutSetIconTitle');
+ @glutPositionWindow := GetModuleSymbol(LibGLUT, 'glutPositionWindow');
+ @glutReshapeWindow := GetModuleSymbol(LibGLUT, 'glutReshapeWindow');
+ @glutPopWindow := GetModuleSymbol(LibGLUT, 'glutPopWindow');
+ @glutPushWindow := GetModuleSymbol(LibGLUT, 'glutPushWindow');
+ @glutIconifyWindow := GetModuleSymbol(LibGLUT, 'glutIconifyWindow');
+ @glutShowWindow := GetModuleSymbol(LibGLUT, 'glutShowWindow');
+ @glutHideWindow := GetModuleSymbol(LibGLUT, 'glutHideWindow');
+ @glutFullScreen := GetModuleSymbol(LibGLUT, 'glutFullScreen');
+ @glutSetCursor := GetModuleSymbol(LibGLUT, 'glutSetCursor');
+ @glutWarpPointer := GetModuleSymbol(LibGLUT, 'glutWarpPointer');
+ @glutEstablishOverlay := GetModuleSymbol(LibGLUT, 'glutEstablishOverlay');
+ @glutRemoveOverlay := GetModuleSymbol(LibGLUT, 'glutRemoveOverlay');
+ @glutUseLayer := GetModuleSymbol(LibGLUT, 'glutUseLayer');
+ @glutPostOverlayRedisplay := GetModuleSymbol(LibGLUT, 'glutPostOverlayRedisplay');
+ @glutPostWindowOverlayRedisplay := GetModuleSymbol(LibGLUT, 'glutPostWindowOverlayRedisplay');
+ @glutShowOverlay := GetModuleSymbol(LibGLUT, 'glutShowOverlay');
+ @glutHideOverlay := GetModuleSymbol(LibGLUT, 'glutHideOverlay');
+ @glutCreateMenu := GetModuleSymbol(LibGLUT, 'glutCreateMenu');
+ @glutDestroyMenu := GetModuleSymbol(LibGLUT, 'glutDestroyMenu');
+ @glutGetMenu := GetModuleSymbol(LibGLUT, 'glutGetMenu');
+ @glutSetMenu := GetModuleSymbol(LibGLUT, 'glutSetMenu');
+ @glutAddMenuEntry := GetModuleSymbol(LibGLUT, 'glutAddMenuEntry');
+ @glutAddSubMenu := GetModuleSymbol(LibGLUT, 'glutAddSubMenu');
+ @glutChangeToMenuEntry := GetModuleSymbol(LibGLUT, 'glutChangeToMenuEntry');
+ @glutChangeToSubMenu := GetModuleSymbol(LibGLUT, 'glutChangeToSubMenu');
+ @glutRemoveMenuItem := GetModuleSymbol(LibGLUT, 'glutRemoveMenuItem');
+ @glutAttachMenu := GetModuleSymbol(LibGLUT, 'glutAttachMenu');
+ @glutDetachMenu := GetModuleSymbol(LibGLUT, 'glutDetachMenu');
+ @glutDisplayFunc := GetModuleSymbol(LibGLUT, 'glutDisplayFunc');
+ @glutReshapeFunc := GetModuleSymbol(LibGLUT, 'glutReshapeFunc');
+ @glutKeyboardFunc := GetModuleSymbol(LibGLUT, 'glutKeyboardFunc');
+ @glutMouseFunc := GetModuleSymbol(LibGLUT, 'glutMouseFunc');
+ @glutMotionFunc := GetModuleSymbol(LibGLUT, 'glutMotionFunc');
+ @glutPassiveMotionFunc := GetModuleSymbol(LibGLUT, 'glutPassiveMotionFunc');
+ @glutEntryFunc := GetModuleSymbol(LibGLUT, 'glutEntryFunc');
+ @glutVisibilityFunc := GetModuleSymbol(LibGLUT, 'glutVisibilityFunc');
+ @glutIdleFunc := GetModuleSymbol(LibGLUT, 'glutIdleFunc');
+ @glutTimerFunc := GetModuleSymbol(LibGLUT, 'glutTimerFunc');
+ @glutMenuStateFunc := GetModuleSymbol(LibGLUT, 'glutMenuStateFunc');
+ @glutSpecialFunc := GetModuleSymbol(LibGLUT, 'glutSpecialFunc');
+ @glutSpaceballMotionFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballMotionFunc');
+ @glutSpaceballRotateFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballRotateFunc');
+ @glutSpaceballButtonFunc := GetModuleSymbol(LibGLUT, 'glutSpaceballButtonFunc');
+ @glutButtonBoxFunc := GetModuleSymbol(LibGLUT, 'glutButtonBoxFunc');
+ @glutDialsFunc := GetModuleSymbol(LibGLUT, 'glutDialsFunc');
+ @glutTabletMotionFunc := GetModuleSymbol(LibGLUT, 'glutTabletMotionFunc');
+ @glutTabletButtonFunc := GetModuleSymbol(LibGLUT, 'glutTabletButtonFunc');
+ @glutMenuStatusFunc := GetModuleSymbol(LibGLUT, 'glutMenuStatusFunc');
+ @glutOverlayDisplayFunc := GetModuleSymbol(LibGLUT, 'glutOverlayDisplayFunc');
+ @glutWindowStatusFunc := GetModuleSymbol(LibGLUT, 'glutWindowStatusFunc');
+ @glutSetColor := GetModuleSymbol(LibGLUT, 'glutSetColor');
+ @glutGetColor := GetModuleSymbol(LibGLUT, 'glutGetColor');
+ @glutCopyColormap := GetModuleSymbol(LibGLUT, 'glutCopyColormap');
+ @glutGet := GetModuleSymbol(LibGLUT, 'glutGet');
+ @glutDeviceGet := GetModuleSymbol(LibGLUT, 'glutDeviceGet');
+ @glutExtensionSupported := GetModuleSymbol(LibGLUT, 'glutExtensionSupported');
+ @glutGetModifiers := GetModuleSymbol(LibGLUT, 'glutGetModifiers');
+ @glutLayerGet := GetModuleSymbol(LibGLUT, 'glutLayerGet');
+ @glutBitmapCharacter := GetModuleSymbol(LibGLUT, 'glutBitmapCharacter');
+ @glutBitmapWidth := GetModuleSymbol(LibGLUT, 'glutBitmapWidth');
+ @glutStrokeCharacter := GetModuleSymbol(LibGLUT, 'glutStrokeCharacter');
+ @glutStrokeWidth := GetModuleSymbol(LibGLUT, 'glutStrokeWidth');
+ @glutBitmapLength := GetModuleSymbol(LibGLUT, 'glutBitmapLength');
+ @glutStrokeLength := GetModuleSymbol(LibGLUT, 'glutStrokeLength');
+ @glutWireSphere := GetModuleSymbol(LibGLUT, 'glutWireSphere');
+ @glutSolidSphere := GetModuleSymbol(LibGLUT, 'glutSolidSphere');
+ @glutWireCone := GetModuleSymbol(LibGLUT, 'glutWireCone');
+ @glutSolidCone := GetModuleSymbol(LibGLUT, 'glutSolidCone');
+ @glutWireCube := GetModuleSymbol(LibGLUT, 'glutWireCube');
+ @glutSolidCube := GetModuleSymbol(LibGLUT, 'glutSolidCube');
+ @glutWireTorus := GetModuleSymbol(LibGLUT, 'glutWireTorus');
+ @glutSolidTorus := GetModuleSymbol(LibGLUT, 'glutSolidTorus');
+ @glutWireDodecahedron := GetModuleSymbol(LibGLUT, 'glutWireDodecahedron');
+ @glutSolidDodecahedron := GetModuleSymbol(LibGLUT, 'glutSolidDodecahedron');
+ @glutWireTeapot := GetModuleSymbol(LibGLUT, 'glutWireTeapot');
+ @glutSolidTeapot := GetModuleSymbol(LibGLUT, 'glutSolidTeapot');
+ @glutWireOctahedron := GetModuleSymbol(LibGLUT, 'glutWireOctahedron');
+ @glutSolidOctahedron := GetModuleSymbol(LibGLUT, 'glutSolidOctahedron');
+ @glutWireTetrahedron := GetModuleSymbol(LibGLUT, 'glutWireTetrahedron');
+ @glutSolidTetrahedron := GetModuleSymbol(LibGLUT, 'glutSolidTetrahedron');
+ @glutWireIcosahedron := GetModuleSymbol(LibGLUT, 'glutWireIcosahedron');
+ @glutSolidIcosahedron := GetModuleSymbol(LibGLUT, 'glutSolidIcosahedron');
+ @glutVideoResizeGet := GetModuleSymbol(LibGLUT, 'glutVideoResizeGet');
+ @glutSetupVideoResizing := GetModuleSymbol(LibGLUT, 'glutSetupVideoResizing');
+ @glutStopVideoResizing := GetModuleSymbol(LibGLUT, 'glutStopVideoResizing');
+ @glutVideoResize := GetModuleSymbol(LibGLUT, 'glutVideoResize');
+ @glutVideoPan := GetModuleSymbol(LibGLUT, 'glutVideoPan');
+ @glutReportErrors := GetModuleSymbol(LibGLUT, 'glutReportErrors');
+ @glutGameModeString := GetModuleSymbol(LibGLUT, 'glutGameModeString');
+ @glutEnterGameMode := GetModuleSymbol(LibGLUT, 'glutEnterGameMode');
+ @glutLeaveGameMode := GetModuleSymbol(LibGLUT, 'glutLeaveGameMode');
+ @glutGameModeGet := GetModuleSymbol(LibGLUT, 'glutGameModeGet');
+ end;
+end;
+
+initialization
+ LoadGlut( GlutLibName );
+
+finalization
+ FreeGlut;
+
+end.
diff --git a/src/lib/JEDI-SDL/OpenGL/Pas/glx.pas b/src/lib/JEDI-SDL/OpenGL/Pas/glx.pas
new file mode 100644
index 00000000..f43a4e4c
--- /dev/null
+++ b/src/lib/JEDI-SDL/OpenGL/Pas/glx.pas
@@ -0,0 +1,280 @@
+unit glx;
+{
+ $Id: glx.pas,v 1.3 2006/11/20 21:20:59 savage Exp $
+
+ Translation of the Mesa GLX headers for FreePascal
+ Copyright (C) 1999 Sebastian Guenther
+
+
+ Mesa 3-D graphics library
+ Version: 3.0
+ Copyright (C) 1995-1998 Brian Paul
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+// {$MODE delphi} // objfpc would not work because of direct proc var assignments
+
+{You have to enable Macros (compiler switch "-Sm") for compiling this unit!
+ This is necessary for supporting different platforms with different calling
+ conventions via a single unit.}
+
+{
+ $Log: glx.pas,v $
+ Revision 1.3 2006/11/20 21:20:59 savage
+ Updated to work in MacOS X
+
+ Revision 1.2 2006/04/18 18:38:33 savage
+ fixed boolean test - thanks grudzio
+
+ Revision 1.1 2004/03/30 21:53:55 savage
+ Moved to it's own folder.
+
+ Revision 1.5 2004/02/15 22:48:35 savage
+ More FPC and FreeBSD support changes.
+
+ Revision 1.4 2004/02/14 22:36:29 savage
+ Fixed inconsistencies of using LoadLibrary and LoadModule.
+ Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
+
+ Revision 1.3 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+ Revision 1.2 2004/02/14 00:09:19 savage
+ Changed uses to now make use of moduleloader.pas rather than dllfuncs.pas
+
+ Revision 1.1 2004/02/05 00:08:19 savage
+ Module 1.0 release
+
+ Revision 1.1 2003/05/11 13:18:03 savage
+ Newest OpenGL Headers For Delphi, Kylix and FPC
+
+ Revision 1.1 2002/10/13 13:57:31 sg
+ * Finally, the new units are available: Match the C headers more closely;
+ support for OpenGL extensions, and much more. Based on the Delphi units
+ by Tom Nuydens of delphi3d.net
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+{$IFDEF UNIX}
+ uses
+ {$IFDEF FPC}
+ x,
+ xlib,
+ xutil;
+ {$ELSE}
+ xlib;
+ {$ENDIF}
+ {$DEFINE HasGLX} // Activate GLX stuff
+{$ELSE}
+ {$MESSAGE Unsupported platform.}
+{$ENDIF}
+
+{$IFNDEF HasGLX}
+ {$MESSAGE GLX not present on this platform.}
+{$ENDIF}
+
+
+// =======================================================
+// Unit specific extensions
+// =======================================================
+
+// Note: Requires that the GL library has already been initialized
+function InitGLX: Boolean;
+
+var
+ GLXDumpUnresolvedFunctions,
+ GLXInitialized: Boolean;
+
+
+// =======================================================
+// GLX consts, types and functions
+// =======================================================
+
+// Tokens for glXChooseVisual and glXGetConfig:
+const
+ GLX_USE_GL = 1;
+ GLX_BUFFER_SIZE = 2;
+ GLX_LEVEL = 3;
+ GLX_RGBA = 4;
+ GLX_DOUBLEBUFFER = 5;
+ GLX_STEREO = 6;
+ GLX_AUX_BUFFERS = 7;
+ GLX_RED_SIZE = 8;
+ GLX_GREEN_SIZE = 9;
+ GLX_BLUE_SIZE = 10;
+ GLX_ALPHA_SIZE = 11;
+ GLX_DEPTH_SIZE = 12;
+ GLX_STENCIL_SIZE = 13;
+ GLX_ACCUM_RED_SIZE = 14;
+ GLX_ACCUM_GREEN_SIZE = 15;
+ GLX_ACCUM_BLUE_SIZE = 16;
+ GLX_ACCUM_ALPHA_SIZE = 17;
+
+ // GLX_EXT_visual_info extension
+ GLX_X_VISUAL_TYPE_EXT = $22;
+ GLX_TRANSPARENT_TYPE_EXT = $23;
+ GLX_TRANSPARENT_INDEX_VALUE_EXT = $24;
+ GLX_TRANSPARENT_RED_VALUE_EXT = $25;
+ GLX_TRANSPARENT_GREEN_VALUE_EXT = $26;
+ GLX_TRANSPARENT_BLUE_VALUE_EXT = $27;
+ GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28;
+
+
+ // Error codes returned by glXGetConfig:
+ GLX_BAD_SCREEN = 1;
+ GLX_BAD_ATTRIBUTE = 2;
+ GLX_NO_EXTENSION = 3;
+ GLX_BAD_VISUAL = 4;
+ GLX_BAD_CONTEXT = 5;
+ GLX_BAD_VALUE = 6;
+ GLX_BAD_ENUM = 7;
+
+ // GLX 1.1 and later:
+ GLX_VENDOR = 1;
+ GLX_VERSION = 2;
+ GLX_EXTENSIONS = 3;
+
+ // GLX_visual_info extension
+ GLX_TRUE_COLOR_EXT = $8002;
+ GLX_DIRECT_COLOR_EXT = $8003;
+ GLX_PSEUDO_COLOR_EXT = $8004;
+ GLX_STATIC_COLOR_EXT = $8005;
+ GLX_GRAY_SCALE_EXT = $8006;
+ GLX_STATIC_GRAY_EXT = $8007;
+ GLX_NONE_EXT = $8000;
+ GLX_TRANSPARENT_RGB_EXT = $8008;
+ GLX_TRANSPARENT_INDEX_EXT = $8009;
+
+type
+ // From XLib:
+ {$IFNDEF FPC}
+ TXID = XID;
+ {$ENDIF}
+ XPixmap = TXID;
+ XFont = TXID;
+ XColormap = TXID;
+
+ GLXContext = Pointer;
+ GLXPixmap = TXID;
+ GLXDrawable = TXID;
+ GLXContextID = TXID;
+
+var
+ glXChooseVisual: function(dpy: PDisplay; screen: Integer; var attribList: Integer): PXVisualInfo; cdecl;
+ glXCreateContext: function(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: Boolean): GLXContext; cdecl;
+ glXDestroyContext: procedure(dpy: PDisplay; ctx: GLXContext); cdecl;
+ glXMakeCurrent: function(dpy: PDisplay; drawable: GLXDrawable; ctx: GLXContext): Boolean; cdecl;
+ glXCopyContext: procedure(dpy: PDisplay; src, dst: GLXContext; mask: LongWord); cdecl;
+ glXSwapBuffers: procedure(dpy: PDisplay; drawable: GLXDrawable); cdecl;
+ glXCreateGLXPixmap: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap): GLXPixmap; cdecl;
+ glXDestroyGLXPixmap: procedure(dpy: PDisplay; pixmap: GLXPixmap); cdecl;
+ glXQueryExtension: function(dpy: PDisplay; var errorb, event: Integer): Boolean; cdecl;
+ glXQueryVersion: function(dpy: PDisplay; var maj, min: Integer): Boolean; cdecl;
+ glXIsDirect: function(dpy: PDisplay; ctx: GLXContext): Boolean; cdecl;
+ glXGetConfig: function(dpy: PDisplay; visual: PXVisualInfo; attrib: Integer; var value: Integer): Integer; cdecl;
+ glXGetCurrentContext: function: GLXContext; cdecl;
+ glXGetCurrentDrawable: function: GLXDrawable; cdecl;
+ glXWaitGL: procedure; cdecl;
+ glXWaitX: procedure; cdecl;
+ glXUseXFont: procedure(font: XFont; first, count, list: Integer); cdecl;
+
+ // GLX 1.1 and later
+ glXQueryExtensionsString: function(dpy: PDisplay; screen: Integer): PChar; cdecl;
+ glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl;
+ glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl;
+
+ // Mesa GLX Extensions
+ glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl;
+ glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl;
+ glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl;
+ glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl;
+ glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl;
+
+
+// =======================================================
+//
+// =======================================================
+
+implementation
+
+uses
+ {$IFNDEF __GPC__}
+ SysUtils,
+ {$ENDIF}
+ moduleloader;
+
+(* {$LINKLIB m} *)
+
+var
+ libGLX: TModuleHandle;
+
+function InitGLXFromLibrary( dll : PChar ): Boolean;
+begin
+ Result := False;
+
+ if not LoadModule( libGLX, dll ) then
+ exit;
+
+ glXChooseVisual := GetModuleSymbol(libglx, 'glXChooseVisual');
+ glXCreateContext := GetModuleSymbol(libglx, 'glXCreateContext');
+ glXDestroyContext := GetModuleSymbol(libglx, 'glXDestroyContext');
+ glXMakeCurrent := GetModuleSymbol(libglx, 'glXMakeCurrent');
+ glXCopyContext := GetModuleSymbol(libglx, 'glXCopyContext');
+ glXSwapBuffers := GetModuleSymbol(libglx, 'glXSwapBuffers');
+ glXCreateGLXPixmap := GetModuleSymbol(libglx, 'glXCreateGLXPixmap');
+ glXDestroyGLXPixmap := GetModuleSymbol(libglx, 'glXDestroyGLXPixmap');
+ glXQueryExtension := GetModuleSymbol(libglx, 'glXQueryExtension');
+ glXQueryVersion := GetModuleSymbol(libglx, 'glXQueryVersion');
+ glXIsDirect := GetModuleSymbol(libglx, 'glXIsDirect');
+ glXGetConfig := GetModuleSymbol(libglx, 'glXGetConfig');
+ glXGetCurrentContext := GetModuleSymbol(libglx, 'glXGetCurrentContext');
+ glXGetCurrentDrawable := GetModuleSymbol(libglx, 'glXGetCurrentDrawable');
+ glXWaitGL := GetModuleSymbol(libglx, 'glXWaitGL');
+ glXWaitX := GetModuleSymbol(libglx, 'glXWaitX');
+ glXUseXFont := GetModuleSymbol(libglx, 'glXUseXFont');
+ // GLX 1.1 and later
+ glXQueryExtensionsString := GetModuleSymbol(libglx, 'glXQueryExtensionsString');
+ glXQueryServerString := GetModuleSymbol(libglx, 'glXQueryServerString');
+ glXGetClientString := GetModuleSymbol(libglx, 'glXGetClientString');
+ // Mesa GLX Extensions
+ glXCreateGLXPixmapMESA := GetModuleSymbol(libglx, 'glXCreateGLXPixmapMESA');
+ glXReleaseBufferMESA := GetModuleSymbol(libglx, 'glXReleaseBufferMESA');
+ glXCopySubBufferMESA := GetModuleSymbol(libglx, 'glXCopySubBufferMESA');
+ glXGetVideoSyncSGI := GetModuleSymbol(libglx, 'glXGetVideoSyncSGI');
+ glXWaitVideoSyncSGI := GetModuleSymbol(libglx, 'glXWaitVideoSyncSGI');
+
+ GLXInitialized := True;
+ Result := True;
+end;
+
+function InitGLX: Boolean;
+begin
+ Result := InitGLXFromLibrary('libGL.so') or
+ InitGLXFromLibrary('libGL.so.1') or
+ InitGLXFromLibrary('libMesaGL.so') or
+ InitGLXFromLibrary('libMesaGL.so.3');
+end;
+
+
+initialization
+ InitGLX;
+finalization
+ UnloadModule(libGLX);
+end.
diff --git a/src/lib/JEDI-SDL/SDL/Pas/Readme.txt b/src/lib/JEDI-SDL/SDL/Pas/Readme.txt
new file mode 100644
index 00000000..f176d0c9
--- /dev/null
+++ b/src/lib/JEDI-SDL/SDL/Pas/Readme.txt
@@ -0,0 +1,27 @@
+Delphi interface unit for OpenGL version 1.2 compilable with Delphi 3-6 and Kylix.
+
+This unit is open source under the Mozilla Public License and
+the original author is Dipl. Ing. Mike Lischke (public@lischke-online.de).
+
+You can obtain this unit also from the JEDI (Joint Endeavor of Delphi Innovators)
+API page at www.delphi-jedi.org.
+
+Note for GLScene users: Eric Grange has provided a general vector types unit which
+resolves conflicts for types which are defined in OpenGL12.pas as well as Geometry.pas.
+This unit is located in the sub folder "GLScene AddOn".
+Please add this unit to the uses clause of OpenGL12.pas and remove the few types which
+are already declared in VectorTypes.pas.
+
+For tests and as starting point three demos are included into the package. Two of them (GLDiag and GLTest)
+need the (also provided) simple OpenGL control GLControl (see "GLControl\Package").
+
+- Basic is a very simple test program which only uses an empty form.
+- GLTest (in GLControl) uses GLControl to show four rendering contexts simultanously.
+- GLDiag is a diagnosis tool similar to DXDiag which shows some properties of the current
+ OpenGL driver implementation.
+
+Have fun and
+
+Ciao, Mike
+www.lischke-online.de
+www.delphi-unicode.net
\ No newline at end of file
diff --git a/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc b/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
new file mode 100644
index 00000000..0130ad32
--- /dev/null
+++ b/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc
@@ -0,0 +1,438 @@
+{
+ $Id: jedi-sdl.inc,v 1.15 2007/05/29 21:30:48 savage Exp $
+}
+{******************************************************************************}
+{ }
+{ Borland Delphi SDL - Simple DirectMedia Layer }
+{ Global Conditional Definitions for JEDI-SDL cross-compilation }
+{ }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Prof. Abimbola Olowofoyeku }
+{ }
+{ Portions created by Prof. Abimbola Olowofoyeku are }
+{ Copyright (C) 2000 - 2100 Prof. Abimbola Olowofoyeku. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Prof. Abimbola Olowofoyeku }
+{ Dominqiue Louis }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ This code has been copied from... }
+{ Global Conditional Definitions for Chief's UNZIP package }
+{ By Prof. Abimbola Olowofoyeku (The African Chief) }
+{ http://www.bigfoot.com/~African_Chief/ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
+{ They are available from... }
+{ http://www.libsdl.org . }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ 2003-04-03 DL - Initial addition }
+{ }
+{ 2003-04-07 DL - Added Macro ON derective for FPC and OpenGL and removed }
+{ WEAKPACKAGE derective. WEAKPACKAGE should be set when }
+{ appropriate. }
+{ }
+{ 2003-04-23 - DL : under instruction from Alexey Barkovoy I have added }
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief) }
+{ I have added better Gnu Pascal support }
+{ }
+{ 2004-01-19 - DL : Under instruction from Marco van de Voort, I have added }
+{ Better FPC support for FreeBSD. }
+{ }
+(*
+ $Log: jedi-sdl.inc,v $
+ Revision 1.15 2007/05/29 21:30:48 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.14 2007/05/20 20:29:11 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.13 2007/01/21 15:51:45 savage
+ Added Delphi 2006 support
+
+ Revision 1.12 2006/11/19 18:41:01 savage
+ removed THREADING ON flag as it is no longer needed in latest versions of FPC.
+
+ Revision 1.11 2006/01/04 00:52:41 drellis
+ Updated to include defined for ENDIAN values, SDL_BYTEORDER should now be correctly defined depending onthe platform. Code taken from sdl_mixer
+
+ Revision 1.10 2005/05/22 18:42:31 savage
+ Changes as suggested by Michalis Kamburelis. Thanks again.
+
+ Revision 1.9 2004/12/23 23:42:17 savage
+ Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability.
+
+ Revision 1.8 2004/10/20 22:43:04 savage
+ Ensure that UNSAFE type warning are off in D9 as well
+
+ Revision 1.7 2004/04/05 09:59:51 savage
+ Changes for FreePacal as suggested by Marco
+
+ Revision 1.6 2004/03/31 22:18:15 savage
+ Small comment for turning off warning under GnuPascal
+
+ Revision 1.5 2004/03/30 22:41:02 savage
+ Added extra commenting due to previous compiler directive
+
+ Revision 1.4 2004/03/30 22:08:33 savage
+ Added Kylix Define
+
+ Revision 1.3 2004/03/30 21:34:40 savage
+ {$H+} needed for FPC compatiblity
+
+ Revision 1.2 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+*)
+{******************************************************************************}
+
+{.$define Debug} { uncomment for debugging }
+
+{$IFNDEF FPC}
+ {$IFDEF __GPC__}
+ {$I-}
+ {$W-} // turn off GPC warnings
+ {$X+}
+ {$ELSE} {__GPC__}
+ {$IFDEF Debug}
+ {$F+,D+,Q-,L+,R+,I-,S+,Y+,A+}
+ {$ELSE}
+ {$F+,Q-,R-,S-,I-,A+}
+ {$ENDIF}
+ {$ENDIF} {__GPC__}
+{$ELSE} {FPC}
+ //{$M+}
+{$ENDIF} {FPC}
+
+{$IFDEF LINUX}
+{$DEFINE UNIX}
+{$ENDIF}
+
+{$IFDEF ver70}
+ {$IFDEF Windows}
+ {$DEFINE Win16}
+ {$ENDIF Windows}
+ {$IFDEF MSDOS}
+ {$DEFINE NO_EXPORTS}
+ {$ENDIF MSDOS}
+ {$IFDEF DPMI}
+ {$DEFINE BP_DPMI}
+ {$ENDIF}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver70}
+
+{$IFDEF ver80}
+ {$DEFINE Delphi} {Delphi 1.x}
+ {$DEFINE Delphi16}
+ {$DEFINE Win16}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver80}
+
+{$IFDEF ver90}
+ {$DEFINE Delphi} {Delphi 2.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver90}
+
+{$IFDEF ver100}
+ {$DEFINE Delphi} {Delphi 3.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver100}
+
+{$IFDEF ver93}
+ {$DEFINE Delphi} {C++ Builder 1.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver93}
+
+{$IFDEF ver110}
+ {$DEFINE Delphi} {C++ Builder 3.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver110}
+
+{$IFDEF ver120}
+ {$DEFINE Delphi} {Delphi 4.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver120}
+
+{$IFDEF ver130}
+ {$DEFINE Delphi} {Delphi 5.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver130}
+
+{$IFDEF ver140}
+ {$DEFINE Delphi} {Delphi 6.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver140}
+
+{$IFDEF ver150}
+ {$DEFINE Delphi} {Delphi 7.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver150}
+
+{$IFDEF ver160}
+ {$DEFINE Delphi} {Delphi 8}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver160}
+
+{$IFDEF ver170}
+ {$DEFINE Delphi} {Delphi 2005}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver170}
+
+{$IFDEF ver180}
+ {$DEFINE Delphi} {Delphi 2006}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver180}
+
+{$IFDEF ver185}
+ {$DEFINE Delphi} {Delphi 2007}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver180}
+
+{$IFDEF UNIX}
+ {$ifdef VER140} // Kylix 1 & 2
+ {$DEFINE KYLIX}
+ {$DEFINE KYLIX1UP}
+ {$DEFINE KYLIX2UP}
+ {$DEFINE HAS_TYPES}
+ {$endif}
+
+ {$ifdef VER150} // Kylix 3
+ {$DEFINE KYLIX}
+ {$DEFINE KYLIX1UP}
+ {$DEFINE KYLIX2UP}
+ {$DEFINE KYLIX3UP}
+ {$DEFINE HAS_TYPES}
+ {$endif}
+{$ENDIF UNIX}
+
+{$IFDEF VirtualPascal} { Virtual Pascal 2.x }
+ {$DEFINE Delphi} { Use Delphi Syntax }
+ {$DEFINE VP2}
+ {&Delphi+}
+{$ENDIF VirtualPascal}
+
+{$IFDEF Delphi}
+ {$DEFINE Windows}
+ {$DEFINE USE_STDCALL}
+ //{$ALIGN ON}
+{$ENDIF Delphi}
+
+{$IFDEF FPC}
+ {$MODE Delphi} { use Delphi compatibility mode }
+ {$H+}
+ {$PACKRECORDS C} // Added for record
+ {$MACRO ON} // Added For OpenGL
+ {$DEFINE Delphi}
+ {$DEFINE UseAT}
+ {$UNDEF USE_STDCALL}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE Has_Int64}
+ {$DEFINE NOCRT}
+ {$IFDEF UNIX}
+ {$DEFINE fpc_unix}
+ {$ELSE}
+ {$DEFINE __OS_DOS__}
+ {$ENDIF}
+ {$IFDEF WIN32}
+ {$DEFINE UseWin}
+ {$ENDIF}
+ {$DEFINE HAS_TYPES}
+{$ENDIF FPC}
+
+{$IFDEF Win16}
+ {$K+} {smart callbacks}
+{$ENDIF Win16}
+
+ {$IFDEF OS2}
+ {$UNDEF Windows}
+ {$DEFINE UseWin}
+ {$DEFINE OS_BigMem}
+ {$ENDIF OS2}
+
+{$IFDEF __GPC__}
+ {$UNDEF UseWin}
+ {$UNDEF USE_STDCALL}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE NOCRT}
+ {$DEFINE cdecl attribute(cdecl)}
+{$ENDIF}
+
+{$IFDEF __TMT__}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE UseAT}
+ {$IFNDEF MSDOS}
+ {$DEFINE USE_STDCALL}
+ {$ENDIF}
+
+ {$IFDEF __WIN32__}
+ {$DEFINE Win32}
+ {$DEFINE UseWin}
+ {$DEFINE NOCRT}
+ {$DEFINE Win32}
+ {$IFNDEF __CON__}
+ {$DEFINE Windows}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$A+} // Word alignment data
+ {$OA+} // Objects and structures align
+{$ENDIF}
+
+{$IFDEF Win32}
+ {$DEFINE OS_BigMem}
+{$ELSE Win32}
+ {$IFDEF ver70}
+ {$DEFINE assembler}
+ {$ENDIF} { use 16-bit assembler! }
+{$ENDIF Win32}
+
+{ ************************** dos/dos-like platforms **************}
+{$IFDEF Windows}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE UseWin}
+ {$DEFINE MSWINDOWS}
+{$ENDIF Delphi}
+
+{$IFDEF OS2}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF Delphi}
+
+{$IFDEF UseWin}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF Win16}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF BP_DPMI}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF USE_STDCALL}
+ {$IFNDEF __TMT__}
+ {$DEFINE BY_NAME}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFNDEF ver70}
+ {$UNDEF assembler}
+{$ENDIF}
+
+{*************** define LITTLE ENDIAN platforms ********************}
+
+
+{$IFDEF Delphi}
+{$DEFINE IA32}
+{$ENDIF}
+
+{$IFDEF KYLIX}
+{$DEFINE IA32}
+{$ENDIF}
+
+{$IFDEF FPC}
+{$IFDEF FPC_LITTLE_ENDIAN}
+{$DEFINE IA32}
+{$ENDIF}
+{$ENDIF}
diff --git a/src/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas b/src/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
new file mode 100644
index 00000000..63e7b7fb
--- /dev/null
+++ b/src/lib/JEDI-SDL/SDL/Pas/libxmlparser.pas
@@ -0,0 +1,2688 @@
+(**
+===============================================================================================
+Name : LibXmlParser
+===============================================================================================
+Project : All Projects
+===============================================================================================
+Subject : Progressive XML Parser for all types of XML Files
+===============================================================================================
+Author : Stefan Heymann
+ Eschenweg 3
+ 72076 Tübingen
+ GERMANY
+
+E-Mail: stefan@destructor.de
+URL: www.destructor.de
+===============================================================================================
+Source, Legals ("Licence")
+--------------------------
+The official site to get this parser is http://www.destructor.de/
+
+Usage and Distribution of this Source Code is ruled by the
+"Destructor.de Source code Licence" (DSL) which comes with this file or
+can be downloaded at http://www.destructor.de/
+
+IN SHORT: Usage and distribution of this source code is free.
+ You use it completely on your own risk.
+
+Postcardware
+------------
+If you like this code, please send a postcard of your city to my above address.
+===============================================================================================
+!!! All parts of this code which are not finished or not conforming exactly to
+ the XmlSpec are marked with three exclamation marks
+
+-!- Parts where the parser may be able to detect errors in the document's syntax are
+ marked with the dash-exlamation mark-dash sequence.
+===============================================================================================
+Terminology:
+------------
+- Start: Start of a buffer part
+- Final: End (last character) of a buffer part
+- DTD: Document Type Definition
+- DTDc: Document Type Declaration
+- XMLSpec: The current W3C XML Recommendation (version 1.0 as of 1998-02-10), Chapter No.
+- Cur*: Fields concerning the "Current" part passed back by the "Scan" method
+===============================================================================================
+Scanning the XML document
+-------------------------
+- Create TXmlParser Instance MyXml := TXmlParser.Create;
+- Load XML Document MyXml.LoadFromFile (Filename);
+- Start Scanning MyXml.StartScan;
+- Scan Loop WHILE MyXml.Scan DO
+- Test for Part Type CASE MyXml.CurPartType OF
+- Handle Parts ... : ;;;
+- Handle Parts ... : ;;;
+- Handle Parts ... : ;;;
+ END;
+- Destroy MyXml.Free;
+===============================================================================================
+Loading the XML document
+------------------------
+You can load the XML document from a file with the "LoadFromFile" method.
+It is beyond the scope of this parser to perform HTTP or FTP accesses. If you want your
+application to handle such requests (URLs), you can load the XML via HTTP or FTP or whatever
+protocol and hand over the data buffer using the "LoadFromBuffer" or "SetBuffer" method.
+"LoadFromBuffer" loads the internal buffer of TXmlParser with the given null-terminated
+string, thereby creating a copy of that buffer.
+"SetBuffer" just takes the pointer to another buffer, which means that the given
+buffer pointer must be valid while the document is accessed via TXmlParser.
+===============================================================================================
+Encodings:
+----------
+This XML parser kind of "understands" the following encodings:
+- UTF-8
+- ISO-8859-1
+- Windows-1252
+
+Any flavor of multi-byte characters (and this includes UTF-16) is not supported. Sorry.
+
+Every string which has to be passed to the application passes the virtual method
+"TranslateEncoding" which translates the string from the current encoding (stored in
+"CurEncoding") into the encoding the application wishes to receive.
+The "TranslateEncoding" method that is built into TXmlParser assumes that the application
+wants to receive Windows ANSI (Windows-1252, about the same as ISO-8859-1) and is able
+to convert UTF-8 and ISO-8859-1 encodings.
+For other source and target encodings, you will have to override "TranslateEncoding".
+===============================================================================================
+Buffer Handling
+---------------
+- The document must be loaded completely into a piece of RAM
+- All character positions are referenced by PChar pointers
+- The TXmlParser instance can either "own" the buffer itself (then, FBufferSize is > 0)
+ or reference the buffer of another instance or object (then, FBuffersize is 0 and
+ FBuffer is not NIL)
+- The Property DocBuffer passes back a pointer to the first byte of the document. If there
+ is no document stored (FBuffer is NIL), the DocBuffer returns a pointer to a NULL character.
+===============================================================================================
+Whitespace Handling
+-------------------
+The TXmlParser property "PackSpaces" determines how Whitespace is returned in Text Content:
+While PackSpaces is true, all leading and trailing whitespace characters are trimmed of, all
+Whitespace is converted to Space #x20 characters and contiguous Whitespace characters are
+compressed to one.
+If the "Scan" method reports a ptContent part, the application can get the original text
+with all whitespace characters by extracting the characters from "CurStart" to "CurFinal".
+If the application detects an xml:space attribute, it can set "PackSpaces" accordingly or
+use CurStart/CurFinal.
+Please note that TXmlParser does _not_ normalize Line Breaks to single LineFeed characters
+as the XmlSpec requires (XmlSpec 2.11).
+The xml:space attribute is not handled by TXmlParser. This is on behalf of the application.
+===============================================================================================
+Non-XML-Conforming
+------------------
+TXmlParser does not conform 100 % exactly to the XmlSpec:
+- UTF-16 is not supported (XmlSpec 2.2)
+ (Workaround: Convert UTF-16 to UTF-8 and hand the buffer over to TXmlParser)
+- As the parser only works with single byte strings, all Unicode characters > 255
+ can currently not be handled correctly.
+- Line breaks are not normalized to single Linefeed #x0A characters (XmlSpec 2.11)
+ (Workaround: The Application can access the text contents on its own [CurStart, CurFinal],
+ thereby applying every normalization it wishes to)
+- The attribute value normalization does not work exactly as defined in the
+ Second Edition of the XML 1.0 specification.
+- See also the code parts marked with three consecutive exclamation marks. These are
+ parts which are not finished in the current code release.
+
+This list may be incomplete, so it may grow if I get to know any other points.
+As work on the parser proceeds, this list may also shrink.
+===============================================================================================
+Things Todo
+-----------
+- Introduce a new event/callback which is called when there is an unresolvable
+ entity or character reference
+- Support Unicode
+- Use Streams instead of reading the whole XML into memory
+===============================================================================================
+Change History, Version numbers
+-------------------------------
+The Date is given in ISO Year-Month-Day (YYYY-MM-DD) order.
+Versions are counted from 1.0.0 beginning with the version from 2000-03-16.
+Unreleased versions don't get a version number.
+
+Date Author Version Changes
+-----------------------------------------------------------------------------------------------
+2000-03-16 HeySt 1.0.0 Start
+2000-03-28 HeySt 1.0.1 Initial Publishing of TXmlParser on the destructor.de Web Site
+2000-03-30 HeySt 1.0.2 TXmlParser.AnalyzeCData: Call "TranslateEncoding" for CurContent
+2000-03-31 HeySt 1.0.3 Deleted the StrPosE function (was not needed anyway)
+2000-04-04 HeySt 1.0.4 TDtdElementRec modified: Start/Final for all Elements;
+ Should be backwards compatible.
+ AnalyzeDtdc: Set CurPartType to ptDtdc
+2000-04-23 HeySt 1.0.5 New class TObjectList. Eliminated reference to the Delphi 5
+ "Contnrs" unit so LibXmlParser is Delphi 4 compatible.
+2000-07-03 HeySt 1.0.6 TNvpNode: Added Constructor
+2000-07-11 HeySt 1.0.7 Removed "Windows" from USES clause
+ Added three-exclamation-mark comments for Utf8ToAnsi/AnsiToUtf8
+ Added three-exclamation-mark comments for CHR function calls
+2000-07-23 HeySt 1.0.8 TXmlParser.Clear: CurAttr.Clear; EntityStack.Clear;
+ (This was not a bug; just defensive programming)
+2000-07-29 HeySt 1.0.9 TNvpList: Added methods: Node(Index), Value(Index), Name(Index);
+2000-10-07 HeySt Introduced Conditional Defines
+ Uses Contnrs unit and its TObjectList class again for
+ Delphi 5 and newer versions
+2001-01-30 HeySt Introduced Version Numbering
+ Made LoadFromFile and LoadFromBuffer BOOLEAN functions
+ Introduced FileMode parameter for LoadFromFile
+ BugFix: TAttrList.Analyze: Must add CWhitespace to ExtractName call
+ Comments worked over
+2001-02-28 HeySt 1.0.10 Completely worked over and tested the UTF-8 functions
+ Fixed a bug in TXmlParser.Scan which caused it to start over when it
+ was called after the end of scanning, resulting in an endless loop
+ TEntityStack is now a TObjectList instead of TList
+2001-07-03 HeySt 1.0.11 Updated Compiler Version IFDEFs for Kylix
+2001-07-11 HeySt 1.0.12 New TCustomXmlScanner component (taken over from LibXmlComps.pas)
+2001-07-14 HeySt 1.0.13 Bugfix TCustomXmlScanner.FOnTranslateEncoding
+2001-10-22 HeySt Don't clear CurName anymore when the parser finds a CDATA section.
+2001-12-03 HeySt 1.0.14 TObjectList.Clear: Make call to INHERITED method (fixes a memory leak)
+2001-12-05 HeySt 1.0.15 TObjectList.Clear: removed call to INHERITED method
+ TObjectList.Destroy: Inserted SetCapacity call.
+ Reduces need for frequent re-allocation of pointer buffer
+ Dedicated to my father, Theodor Heymann
+2002-06-26 HeySt 1.0.16 TXmlParser.Scan: Fixed a bug with PIs whose name is beginning
+ with 'xml'. Thanks to Uwe Kamm for submitting this bug.
+ The CurEncoding property is now always in uppercase letters (the XML
+ spec wants it to be treated case independently so when it's uppercase
+ comparisons are faster)
+2002-03-04 HeySt 1.0.17 Included an IFDEF for Delphi 7 (VER150) and Kylix
+ There is a new symbol HAS_CONTNRS_UNIT which is used now to
+ distinguish between IDEs which come with the Contnrs unit and
+ those that don't.
+*)
+
+UNIT libxmlparser;
+
+{$I jedi-sdl.inc}
+
+INTERFACE
+
+USES
+ SysUtils, Classes,
+ (*$IFDEF HAS_CONTNRS_UNIT *) // The Contnrs Unit was introduced in Delphi 5
+ Contnrs,
+ (*$ENDIF*)
+ Math;
+
+CONST
+ CVersion = '1.0.17'; // This variable will be updated for every release
+ // (I hope, I won't forget to do it everytime ...)
+
+TYPE
+ TPartType = // --- Document Part Types
+ (ptNone, // Nothing
+ ptXmlProlog, // XML Prolog XmlSpec 2.8 / 4.3.1
+ ptComment, // Comment XmlSpec 2.5
+ ptPI, // Processing Instruction XmlSpec 2.6
+ ptDtdc, // Document Type Declaration XmlSpec 2.8
+ ptStartTag, // Start Tag XmlSpec 3.1
+ ptEmptyTag, // Empty-Element Tag XmlSpec 3.1
+ ptEndTag, // End Tag XmlSpec 3.1
+ ptContent, // Text Content between Tags
+ ptCData); // CDATA Section XmlSpec 2.7
+
+ TDtdElemType = // --- DTD Elements
+ (deElement, // !ELEMENT declaration
+ deAttList, // !ATTLIST declaration
+ deEntity, // !ENTITY declaration
+ deNotation, // !NOTATION declaration
+ dePI, // PI in DTD
+ deComment, // Comment in DTD
+ deError); // Error found in the DTD
+
+TYPE
+ TAttrList = CLASS;
+ TEntityStack = CLASS;
+ TNvpList = CLASS;
+ TElemDef = CLASS;
+ TElemList = CLASS;
+ TEntityDef = CLASS;
+ TNotationDef = CLASS;
+
+ TDtdElementRec = RECORD // --- This Record is returned by the DTD parser callback function
+ Start, Final : PChar; // Start/End of the Element's Declaration
+ CASE ElementType : TDtdElemType OF // Type of the Element
+ deElement, //
+ deAttList : (ElemDef : TElemDef); //
+ deEntity : (EntityDef : TEntityDef); //
+ deNotation : (NotationDef : TNotationDef); //
+ dePI : (Target : PChar; //
+ Content : PChar;
+ AttrList : TAttrList);
+ deError : (Pos : PChar); // Error
+ // deComment : ((No additional fields here)); //
+ END;
+
+ TXmlParser = CLASS // --- Internal Properties and Methods
+ PROTECTED
+ FBuffer : PChar; // NIL if there is no buffer available
+ FBufferSize : INTEGER; // 0 if the buffer is not owned by the Document instance
+ FSource : STRING; // Name of Source of document. Filename for Documents loaded with LoadFromFile
+
+ FXmlVersion : STRING; // XML version from Document header. Default is '1.0'
+ FEncoding : STRING; // Encoding from Document header. Default is 'UTF-8'
+ FStandalone : BOOLEAN; // Standalone declaration from Document header. Default is 'yes'
+ FRootName : STRING; // Name of the Root Element (= DTD name)
+ FDtdcFinal : PChar; // Pointer to the '>' character terminating the DTD declaration
+
+ FNormalize : BOOLEAN; // If true: Pack Whitespace and don't return empty contents
+ EntityStack : TEntityStack; // Entity Stack for Parameter and General Entities
+ FCurEncoding : STRING; // Current Encoding during parsing (always uppercase)
+
+ PROCEDURE AnalyzeProlog; // Analyze XML Prolog or Text Declaration
+ PROCEDURE AnalyzeComment (Start : PChar; VAR Final : PChar); // Analyze Comments
+ PROCEDURE AnalyzePI (Start : PChar; VAR Final : PChar); // Analyze Processing Instructions (PI)
+ PROCEDURE AnalyzeDtdc; // Analyze Document Type Declaration
+ PROCEDURE AnalyzeDtdElements (Start : PChar; VAR Final : PChar); // Analyze DTD declarations
+ PROCEDURE AnalyzeTag; // Analyze Start/End/Empty-Element Tags
+ PROCEDURE AnalyzeCData; // Analyze CDATA Sections
+ PROCEDURE AnalyzeText (VAR IsDone : BOOLEAN); // Analyze Text Content between Tags
+ PROCEDURE AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
+
+ PROCEDURE PushPE (VAR Start : PChar);
+ PROCEDURE ReplaceCharacterEntities (VAR Str : STRING);
+ PROCEDURE ReplaceParameterEntities (VAR Str : STRING);
+ PROCEDURE ReplaceGeneralEntities (VAR Str : STRING);
+
+ FUNCTION GetDocBuffer : PChar; // Returns FBuffer or a pointer to a NUL char if Buffer is empty
+
+ PUBLIC // --- Document Properties
+ PROPERTY XmlVersion : STRING READ FXmlVersion; // XML version from the Document Prolog
+ PROPERTY Encoding : STRING READ FEncoding; // Document Encoding from Prolog
+ PROPERTY Standalone : BOOLEAN READ FStandalone; // Standalone Declaration from Prolog
+ PROPERTY RootName : STRING READ FRootName; // Name of the Root Element
+ PROPERTY Normalize : BOOLEAN READ FNormalize WRITE FNormalize; // True if Content is to be normalized
+ PROPERTY Source : STRING READ FSource; // Name of Document Source (Filename)
+ PROPERTY DocBuffer : PChar READ GetDocBuffer; // Returns document buffer
+ PUBLIC // --- DTD Objects
+ Elements : TElemList; // Elements: List of TElemDef (contains Attribute Definitions)
+ Entities : TNvpList; // General Entities: List of TEntityDef
+ ParEntities : TNvpList; // Parameter Entities: List of TEntityDef
+ Notations : TNvpList; // Notations: List of TNotationDef
+ PUBLIC
+ CONSTRUCTOR Create;
+ DESTRUCTOR Destroy; OVERRIDE;
+
+ // --- Document Handling
+ FUNCTION LoadFromFile (Filename : STRING;
+ FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
+ // Loads Document from given file
+ FUNCTION LoadFromBuffer (Buffer : PChar) : BOOLEAN; // Loads Document from another buffer
+ PROCEDURE SetBuffer (Buffer : PChar); // References another buffer
+ PROCEDURE Clear; // Clear Document
+
+ PUBLIC
+ // --- Scanning through the document
+ CurPartType : TPartType; // Current Type
+ CurName : STRING; // Current Name
+ CurContent : STRING; // Current Normalized Content
+ CurStart : PChar; // Current First character
+ CurFinal : PChar; // Current Last character
+ CurAttr : TAttrList; // Current Attribute List
+ PROPERTY CurEncoding : STRING READ FCurEncoding; // Current Encoding
+ PROCEDURE StartScan;
+ FUNCTION Scan : BOOLEAN;
+
+ // --- Events / Callbacks
+ FUNCTION LoadExternalEntity (SystemId, PublicId,
+ Notation : STRING) : TXmlParser; VIRTUAL;
+ FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; VIRTUAL;
+ PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); VIRTUAL;
+ END;
+
+ TValueType = // --- Attribute Value Type
+ (vtNormal, // Normal specified Attribute
+ vtImplied, // #IMPLIED attribute value
+ vtFixed, // #FIXED attribute value
+ vtDefault); // Attribute value from default value in !ATTLIST declaration
+
+ TAttrDefault = // --- Attribute Default Type
+ (adDefault, // Normal default value
+ adRequired, // #REQUIRED attribute
+ adImplied, // #IMPLIED attribute
+ adFixed); // #FIXED attribute
+
+ TAttrType = // --- Type of attribute
+ (atUnknown, // Unknown type
+ atCData, // Character data only
+ atID, // ID
+ atIdRef, // ID Reference
+ atIdRefs, // Several ID References, separated by Whitespace
+ atEntity, // Name of an unparsed Entity
+ atEntities, // Several unparsed Entity names, separated by Whitespace
+ atNmToken, // Name Token
+ atNmTokens, // Several Name Tokens, separated by Whitespace
+ atNotation, // A selection of Notation names (Unparsed Entity)
+ atEnumeration); // Enumeration
+
+ TElemType = // --- Element content type
+ (etEmpty, // Element is always empty
+ etAny, // Element can have any mixture of PCDATA and any elements
+ etChildren, // Element must contain only elements
+ etMixed); // Mixed PCDATA and elements
+
+ (*$IFDEF HAS_CONTNRS_UNIT *)
+ TObjectList = Contnrs.TObjectList; // Re-Export this identifier
+ (*$ELSE *)
+ TObjectList = CLASS (TList)
+ DESTRUCTOR Destroy; OVERRIDE;
+ PROCEDURE Delete (Index : INTEGER);
+ PROCEDURE Clear; OVERRIDE;
+ END;
+ (*$ENDIF *)
+
+ TNvpNode = CLASS // Name-Value Pair Node
+ Name : STRING;
+ Value : STRING;
+ CONSTRUCTOR Create (TheName : STRING = ''; TheValue : STRING = '');
+ END;
+
+ TNvpList = CLASS (TObjectList) // Name-Value Pair List
+ PROCEDURE Add (Node : TNvpNode);
+ FUNCTION Node (Name : STRING) : TNvpNode; OVERLOAD;
+ FUNCTION Node (Index : INTEGER) : TNvpNode; OVERLOAD;
+ FUNCTION Value (Name : STRING) : STRING; OVERLOAD;
+ FUNCTION Value (Index : INTEGER) : STRING; OVERLOAD;
+ FUNCTION Name (Index : INTEGER) : STRING;
+ END;
+
+ TAttr = CLASS (TNvpNode) // Attribute of a Start-Tag or Empty-Element-Tag
+ ValueType : TValueType;
+ AttrType : TAttrType;
+ END;
+
+ TAttrList = CLASS (TNvpList) // List of Attributes
+ PROCEDURE Analyze (Start : PChar; VAR Final : PChar);
+ END;
+
+ TEntityStack = CLASS (TObjectList) // Stack where current position is stored before parsing entities
+ PROTECTED
+ Owner : TXmlParser;
+ PUBLIC
+ CONSTRUCTOR Create (TheOwner : TXmlParser);
+ PROCEDURE Push (LastPos : PChar); OVERLOAD;
+ PROCEDURE Push (Instance : TObject; LastPos : PChar); OVERLOAD;
+ FUNCTION Pop : PChar; // Returns next char or NIL if EOF is reached. Frees Instance.
+ END;
+
+ TAttrDef = CLASS (TNvpNode) // Represents a ';
+
+ // --- Name Constants for the above enumeration types
+ CPartType_Name : ARRAY [TPartType] OF STRING =
+ ('', 'XML Prolog', 'Comment', 'PI',
+ 'DTD Declaration', 'Start Tag', 'Empty Tag', 'End Tag',
+ 'Text', 'CDATA');
+ CValueType_Name : ARRAY [TValueType] OF STRING = ('Normal', 'Implied', 'Fixed', 'Default');
+ CAttrDefault_Name : ARRAY [TAttrDefault] OF STRING = ('Default', 'Required', 'Implied', 'Fixed');
+ CElemType_Name : ARRAY [TElemType] OF STRING = ('Empty', 'Any', 'Childs only', 'Mixed');
+ CAttrType_Name : ARRAY [TAttrType] OF STRING = ('Unknown', 'CDATA',
+ 'ID', 'IDREF', 'IDREFS',
+ 'ENTITY', 'ENTITIES',
+ 'NMTOKEN', 'NMTOKENS',
+ 'Notation', 'Enumeration');
+
+FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING; // Convert WS to spaces #x20
+PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar); // SetString by Start/Final of buffer
+FUNCTION StrSFPas (Start, Finish : PChar) : STRING; // Convert buffer part to Pascal string
+FUNCTION TrimWs (Source : STRING) : STRING; // Trim Whitespace
+
+FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING; // Convert Win-1252 to UTF-8
+FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING; // Convert UTF-8 to Win-1252
+
+
+(*
+===============================================================================================
+TCustomXmlScanner event based component wrapper for TXmlParser
+===============================================================================================
+*)
+
+TYPE
+ TCustomXmlScanner = CLASS;
+ TXmlPrologEvent = PROCEDURE (Sender : TObject; XmlVersion, Encoding: STRING; Standalone : BOOLEAN) OF OBJECT;
+ TCommentEvent = PROCEDURE (Sender : TObject; Comment : STRING) OF OBJECT;
+ TPIEvent = PROCEDURE (Sender : TObject; Target, Content: STRING; Attributes : TAttrList) OF OBJECT;
+ TDtdEvent = PROCEDURE (Sender : TObject; RootElementName : STRING) OF OBJECT;
+ TStartTagEvent = PROCEDURE (Sender : TObject; TagName : STRING; Attributes : TAttrList) OF OBJECT;
+ TEndTagEvent = PROCEDURE (Sender : TObject; TagName : STRING) OF OBJECT;
+ TContentEvent = PROCEDURE (Sender : TObject; Content : STRING) OF OBJECT;
+ TElementEvent = PROCEDURE (Sender : TObject; ElemDef : TElemDef) OF OBJECT;
+ TEntityEvent = PROCEDURE (Sender : TObject; EntityDef : TEntityDef) OF OBJECT;
+ TNotationEvent = PROCEDURE (Sender : TObject; NotationDef : TNotationDef) OF OBJECT;
+ TErrorEvent = PROCEDURE (Sender : TObject; ErrorPos : PChar) OF OBJECT;
+ TExternalEvent = PROCEDURE (Sender : TObject; SystemId, PublicId, NotationId : STRING;
+ VAR Result : TXmlParser) OF OBJECT;
+ TEncodingEvent = FUNCTION (Sender : TObject; CurrentEncoding, Source : STRING) : STRING OF OBJECT;
+
+
+ TCustomXmlScanner = CLASS (TComponent)
+ PROTECTED
+ FXmlParser : TXmlParser;
+ FOnXmlProlog : TXmlPrologEvent;
+ FOnComment : TCommentEvent;
+ FOnPI : TPIEvent;
+ FOnDtdRead : TDtdEvent;
+ FOnStartTag : TStartTagEvent;
+ FOnEmptyTag : TStartTagEvent;
+ FOnEndTag : TEndTagEvent;
+ FOnContent : TContentEvent;
+ FOnCData : TContentEvent;
+ FOnElement : TElementEvent;
+ FOnAttList : TElementEvent;
+ FOnEntity : TEntityEvent;
+ FOnNotation : TNotationEvent;
+ FOnDtdError : TErrorEvent;
+ FOnLoadExternal : TExternalEvent;
+ FOnTranslateEncoding : TEncodingEvent;
+ FStopParser : BOOLEAN;
+ FUNCTION GetNormalize : BOOLEAN;
+ PROCEDURE SetNormalize (Value : BOOLEAN);
+
+ PROCEDURE WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN); VIRTUAL;
+ PROCEDURE WhenComment (Comment : STRING); VIRTUAL;
+ PROCEDURE WhenPI (Target, Content: STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenDtdRead (RootElementName : STRING); VIRTUAL;
+ PROCEDURE WhenStartTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenEmptyTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenEndTag (TagName : STRING); VIRTUAL;
+ PROCEDURE WhenContent (Content : STRING); VIRTUAL;
+ PROCEDURE WhenCData (Content : STRING); VIRTUAL;
+ PROCEDURE WhenElement (ElemDef : TElemDef); VIRTUAL;
+ PROCEDURE WhenAttList (ElemDef : TElemDef); VIRTUAL;
+ PROCEDURE WhenEntity (EntityDef : TEntityDef); VIRTUAL;
+ PROCEDURE WhenNotation (NotationDef : TNotationDef); VIRTUAL;
+ PROCEDURE WhenDtdError (ErrorPos : PChar); VIRTUAL;
+
+ PUBLIC
+ CONSTRUCTOR Create (AOwner: TComponent); OVERRIDE;
+ DESTRUCTOR Destroy; OVERRIDE;
+
+ PROCEDURE LoadFromFile (Filename : TFilename); // Load XML Document from file
+ PROCEDURE LoadFromBuffer (Buffer : PChar); // Load XML Document from buffer
+ PROCEDURE SetBuffer (Buffer : PChar); // Refer to Buffer
+ FUNCTION GetFilename : TFilename;
+
+ PROCEDURE Execute; // Perform scanning
+
+ PROTECTED
+ PROPERTY XmlParser : TXmlParser READ FXmlParser;
+ PROPERTY StopParser : BOOLEAN READ FStopParser WRITE FStopParser;
+ PROPERTY Filename : TFilename READ GetFilename WRITE LoadFromFile;
+ PROPERTY Normalize : BOOLEAN READ GetNormalize WRITE SetNormalize;
+ PROPERTY OnXmlProlog : TXmlPrologEvent READ FOnXmlProlog WRITE FOnXmlProlog;
+ PROPERTY OnComment : TCommentEvent READ FOnComment WRITE FOnComment;
+ PROPERTY OnPI : TPIEvent READ FOnPI WRITE FOnPI;
+ PROPERTY OnDtdRead : TDtdEvent READ FOnDtdRead WRITE FOnDtdRead;
+ PROPERTY OnStartTag : TStartTagEvent READ FOnStartTag WRITE FOnStartTag;
+ PROPERTY OnEmptyTag : TStartTagEvent READ FOnEmptyTag WRITE FOnEmptyTag;
+ PROPERTY OnEndTag : TEndTagEvent READ FOnEndTag WRITE FOnEndTag;
+ PROPERTY OnContent : TContentEvent READ FOnContent WRITE FOnContent;
+ PROPERTY OnCData : TContentEvent READ FOnCData WRITE FOnCData;
+ PROPERTY OnElement : TElementEvent READ FOnElement WRITE FOnElement;
+ PROPERTY OnAttList : TElementEvent READ FOnAttList WRITE FOnAttList;
+ PROPERTY OnEntity : TEntityEvent READ FOnEntity WRITE FOnEntity;
+ PROPERTY OnNotation : TNotationEvent READ FOnNotation WRITE FOnNotation;
+ PROPERTY OnDtdError : TErrorEvent READ FOnDtdError WRITE FOnDtdError;
+ PROPERTY OnLoadExternal : TExternalEvent READ FOnLoadExternal WRITE FOnLoadExternal;
+ PROPERTY OnTranslateEncoding : TEncodingEvent READ FOnTranslateEncoding WRITE FOnTranslateEncoding;
+ END;
+
+(*
+===============================================================================================
+IMPLEMENTATION
+===============================================================================================
+*)
+
+IMPLEMENTATION
+
+
+(*
+===============================================================================================
+Unicode and UTF-8 stuff
+===============================================================================================
+*)
+
+CONST
+ // --- Character Translation Table for Unicode <-> Win-1252
+ WIN1252_UNICODE : ARRAY [$00..$FF] OF WORD = (
+ $0000, $0001, $0002, $0003, $0004, $0005, $0006, $0007, $0008, $0009,
+ $000A, $000B, $000C, $000D, $000E, $000F, $0010, $0011, $0012, $0013,
+ $0014, $0015, $0016, $0017, $0018, $0019, $001A, $001B, $001C, $001D,
+ $001E, $001F, $0020, $0021, $0022, $0023, $0024, $0025, $0026, $0027,
+ $0028, $0029, $002A, $002B, $002C, $002D, $002E, $002F, $0030, $0031,
+ $0032, $0033, $0034, $0035, $0036, $0037, $0038, $0039, $003A, $003B,
+ $003C, $003D, $003E, $003F, $0040, $0041, $0042, $0043, $0044, $0045,
+ $0046, $0047, $0048, $0049, $004A, $004B, $004C, $004D, $004E, $004F,
+ $0050, $0051, $0052, $0053, $0054, $0055, $0056, $0057, $0058, $0059,
+ $005A, $005B, $005C, $005D, $005E, $005F, $0060, $0061, $0062, $0063,
+ $0064, $0065, $0066, $0067, $0068, $0069, $006A, $006B, $006C, $006D,
+ $006E, $006F, $0070, $0071, $0072, $0073, $0074, $0075, $0076, $0077,
+ $0078, $0079, $007A, $007B, $007C, $007D, $007E, $007F,
+
+ $20AC, $0081, $201A, $0192, $201E, $2026, $2020, $2021, $02C6, $2030,
+ $0160, $2039, $0152, $008D, $017D, $008F, $0090, $2018, $2019, $201C,
+ $201D, $2022, $2013, $2014, $02DC, $2122, $0161, $203A, $0153, $009D,
+ $017E, $0178, $00A0, $00A1, $00A2, $00A3, $00A4, $00A5, $00A6, $00A7,
+ $00A8, $00A9, $00AA, $00AB, $00AC, $00AD, $00AE, $00AF, $00B0, $00B1,
+ $00B2, $00B3, $00B4, $00B5, $00B6, $00B7, $00B8, $00B9, $00BA, $00BB,
+ $00BC, $00BD, $00BE, $00BF, $00C0, $00C1, $00C2, $00C3, $00C4, $00C5,
+ $00C6, $00C7, $00C8, $00C9, $00CA, $00CB, $00CC, $00CD, $00CE, $00CF,
+ $00D0, $00D1, $00D2, $00D3, $00D4, $00D5, $00D6, $00D7, $00D8, $00D9,
+ $00DA, $00DB, $00DC, $00DD, $00DE, $00DF, $00E0, $00E1, $00E2, $00E3,
+ $00E4, $00E5, $00E6, $00E7, $00E8, $00E9, $00EA, $00EB, $00EC, $00ED,
+ $00EE, $00EF, $00F0, $00F1, $00F2, $00F3, $00F4, $00F5, $00F6, $00F7,
+ $00F8, $00F9, $00FA, $00FB, $00FC, $00FD, $00FE, $00FF);
+
+(* UTF-8 (somewhat simplified)
+ -----
+ Character Range Byte sequence
+ --------------- -------------------------- (x=Bits from original character)
+ $0000..$007F 0xxxxxxx
+ $0080..$07FF 110xxxxx 10xxxxxx
+ $8000..$FFFF 1110xxxx 10xxxxxx 10xxxxxx
+
+ Example
+ --------
+ Transforming the Unicode character U+00E4 LATIN SMALL LETTER A WITH DIAERESIS ("ä"):
+
+ ISO-8859-1, Decimal 228
+ Win1252, Hex $E4
+ ANSI Bin 1110 0100
+ abcd efgh
+
+ UTF-8 Binary 1100xxab 10cdefgh
+ Binary 11000011 10100100
+ Hex $C3 $A4
+ Decimal 195 164
+ ANSI Ã ¤ *)
+
+
+FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING;
+ (* Converts the given Windows ANSI (Win1252) String to UTF-8. *)
+VAR
+ I : INTEGER; // Loop counter
+ U : WORD; // Current Unicode value
+ Len : INTEGER; // Current real length of "Result" string
+BEGIN
+ SetLength (Result, Length (Source) * 3); // Worst case
+ Len := 0;
+ FOR I := 1 TO Length (Source) DO BEGIN
+ U := WIN1252_UNICODE [ORD (Source [I])];
+ CASE U OF
+ $0000..$007F : BEGIN
+ INC (Len);
+ Result [Len] := CHR (U);
+ END;
+ $0080..$07FF : BEGIN
+ INC (Len);
+ Result [Len] := CHR ($C0 OR (U SHR 6));
+ INC (Len);
+ Result [Len] := CHR ($80 OR (U AND $3F));
+ END;
+ $0800..$FFFF : BEGIN
+ INC (Len);
+ Result [Len] := CHR ($E0 OR (U SHR 12));
+ INC (Len);
+ Result [Len] := CHR ($80 OR ((U SHR 6) AND $3F));
+ INC (Len);
+ Result [Len] := CHR ($80 OR (U AND $3F));
+ END;
+ END;
+ END;
+ SetLength (Result, Len);
+END;
+
+
+FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING;
+ (* Converts the given UTF-8 String to Windows ANSI (Win-1252).
+ If a character can not be converted, the "UnknownChar" is inserted. *)
+VAR
+ SourceLen : INTEGER; // Length of Source string
+ I, K : INTEGER;
+ A : BYTE; // Current ANSI character value
+ U : WORD;
+ Ch : CHAR; // Dest char
+ Len : INTEGER; // Current real length of "Result" string
+BEGIN
+ SourceLen := Length (Source);
+ SetLength (Result, SourceLen); // Enough room to live
+ Len := 0;
+ I := 1;
+ WHILE I <= SourceLen DO BEGIN
+ A := ORD (Source [I]);
+ IF A < $80 THEN BEGIN // Range $0000..$007F
+ INC (Len);
+ Result [Len] := Source [I];
+ INC (I);
+ END
+ ELSE BEGIN // Determine U, Inc I
+ IF (A AND $E0 = $C0) AND (I < SourceLen) THEN BEGIN // Range $0080..$07FF
+ U := (WORD (A AND $1F) SHL 6) OR (ORD (Source [I+1]) AND $3F);
+ INC (I, 2);
+ END
+ ELSE IF (A AND $F0 = $E0) AND (I < SourceLen-1) THEN BEGIN // Range $0800..$FFFF
+ U := (WORD (A AND $0F) SHL 12) OR
+ (WORD (ORD (Source [I+1]) AND $3F) SHL 6) OR
+ ( ORD (Source [I+2]) AND $3F);
+ INC (I, 3);
+ END
+ ELSE BEGIN // Unknown/unsupported
+ INC (I);
+ FOR K := 7 DOWNTO 0 DO
+ IF A AND (1 SHL K) = 0 THEN BEGIN
+ INC (I, (A SHR (K+1))-1);
+ BREAK;
+ END;
+ U := WIN1252_UNICODE [ORD (UnknownChar)];
+ END;
+ Ch := UnknownChar; // Retrieve ANSI char
+ FOR A := $00 TO $FF DO
+ IF WIN1252_UNICODE [A] = U THEN BEGIN
+ Ch := CHR (A);
+ BREAK;
+ END;
+ INC (Len);
+ Result [Len] := Ch;
+ END;
+ END;
+ SetLength (Result, Len);
+END;
+
+
+(*
+===============================================================================================
+"Special" Helper Functions
+
+Don't ask me why. But including these functions makes the parser *DRAMATICALLY* faster
+on my K6-233 machine. You can test it yourself just by commenting them out.
+They do exactly the same as the Assembler routines defined in SysUtils.
+(This is where you can see how great the Delphi compiler really is. The compiled code is
+faster than hand-coded assembler!)
+===============================================================================================
+--> Just move this line below the StrScan function --> *)
+
+
+FUNCTION StrPos (CONST Str, SearchStr : PChar) : PChar;
+ // Same functionality as SysUtils.StrPos
+VAR
+ First : CHAR;
+ Len : INTEGER;
+BEGIN
+ First := SearchStr^;
+ Len := StrLen (SearchStr);
+ Result := Str;
+ REPEAT
+ IF Result^ = First THEN
+ IF StrLComp (Result, SearchStr, Len) = 0 THEN BREAK;
+ IF Result^ = #0 THEN BEGIN
+ Result := NIL;
+ BREAK;
+ END;
+ INC (Result);
+ UNTIL FALSE;
+END;
+
+
+FUNCTION StrScan (CONST Start : PChar; CONST Ch : CHAR) : PChar;
+ // Same functionality as SysUtils.StrScan
+BEGIN
+ Result := Start;
+ WHILE Result^ <> Ch DO BEGIN
+ IF Result^ = #0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+ INC (Result);
+ END;
+END;
+
+
+(*
+===============================================================================================
+Helper Functions
+===============================================================================================
+*)
+
+FUNCTION DelChars (Source : STRING; CharsToDelete : TCharset) : STRING;
+ // Delete all "CharsToDelete" from the string
+VAR
+ I : INTEGER;
+BEGIN
+ Result := Source;
+ FOR I := Length (Result) DOWNTO 1 DO
+ IF Result [I] IN CharsToDelete THEN
+ Delete (Result, I, 1);
+END;
+
+
+FUNCTION TrimWs (Source : STRING) : STRING;
+ // Trimms off Whitespace characters from both ends of the string
+VAR
+ I : INTEGER;
+BEGIN
+ // --- Trim Left
+ I := 1;
+ WHILE (I <= Length (Source)) AND (Source [I] IN CWhitespace) DO
+ INC (I);
+ Result := Copy (Source, I, MaxInt);
+
+ // --- Trim Right
+ I := Length (Result);
+ WHILE (I > 1) AND (Result [I] IN CWhitespace) DO
+ DEC (I);
+ Delete (Result, I+1, Length (Result)-I);
+END;
+
+
+FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING;
+ // Converts all Whitespace characters to the Space #x20 character
+ // If "PackWs" is true, contiguous Whitespace characters are packed to one
+VAR
+ I : INTEGER;
+BEGIN
+ Result := Source;
+ FOR I := Length (Result) DOWNTO 1 DO
+ IF (Result [I] IN CWhitespace) THEN
+ IF PackWs AND (I > 1) AND (Result [I-1] IN CWhitespace)
+ THEN Delete (Result, I, 1)
+ ELSE Result [I] := #32;
+END;
+
+
+PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar);
+BEGIN
+ SetString (S, BufferStart, BufferFinal-BufferStart+1);
+END;
+
+
+FUNCTION StrLPas (Start : PChar; Len : INTEGER) : STRING;
+BEGIN
+ SetString (Result, Start, Len);
+END;
+
+
+FUNCTION StrSFPas (Start, Finish : PChar) : STRING;
+BEGIN
+ SetString (Result, Start, Finish-Start+1);
+END;
+
+
+FUNCTION StrScanE (CONST Source : PChar; CONST CharToScanFor : CHAR) : PChar;
+ // If "CharToScanFor" is not found, StrScanE returns the last char of the
+ // buffer instead of NIL
+BEGIN
+ Result := StrScan (Source, CharToScanFor);
+ IF Result = NIL THEN
+ Result := StrEnd (Source)-1;
+END;
+
+
+PROCEDURE ExtractName (Start : PChar; Terminators : TCharset; VAR Final : PChar);
+ (* Extracts the complete Name beginning at "Start".
+ It is assumed that the name is contained in Markup, so the '>' character is
+ always a Termination.
+ Start: IN Pointer to first char of name. Is always considered to be valid
+ Terminators: IN Characters which terminate the name
+ Final: OUT Pointer to last char of name *)
+BEGIN
+ Final := Start+1;
+ Include (Terminators, #0);
+ Include (Terminators, '>');
+ WHILE NOT (Final^ IN Terminators) DO
+ INC (Final);
+ DEC (Final);
+END;
+
+
+PROCEDURE ExtractQuote (Start : PChar; VAR Content : STRING; VAR Final : PChar);
+ (* Extract a string which is contained in single or double Quotes.
+ Start: IN Pointer to opening quote
+ Content: OUT The quoted string
+ Final: OUT Pointer to closing quote *)
+BEGIN
+ Final := StrScan (Start+1, Start^);
+ IF Final = NIL THEN BEGIN
+ Final := StrEnd (Start+1)-1;
+ SetString (Content, Start+1, Final-Start);
+ END
+ ELSE
+ SetString (Content, Start+1, Final-1-Start);
+END;
+
+
+(*
+===============================================================================================
+TEntityStackNode
+This Node is pushed to the "Entity Stack" whenever the parser parses entity replacement text.
+The "Instance" field holds the Instance pointer of an External Entity buffer. When it is
+popped, the Instance is freed.
+The "Encoding" field holds the name of the Encoding. External Parsed Entities may have
+another encoding as the document entity (XmlSpec 4.3.3). So when there is an " 0 THEN BEGIN
+ ESN := TEntityStackNode (Items [Count-1]);
+ Result := ESN.LastPos;
+ IF ESN.Instance <> NIL THEN
+ ESN.Instance.Free;
+ IF ESN.Encoding <> '' THEN
+ Owner.FCurEncoding := ESN.Encoding; // Restore current Encoding
+ Delete (Count-1);
+ END
+ ELSE
+ Result := NIL;
+END;
+
+
+(*
+===============================================================================================
+TExternalID
+-----------
+XmlSpec 4.2.2: ExternalID ::= 'SYSTEM' S SystemLiteral |
+ 'PUBLIC' S PubidLiteral S SystemLiteral
+XmlSpec 4.7: PublicID ::= 'PUBLIC' S PubidLiteral
+SystemLiteral and PubidLiteral are quoted
+===============================================================================================
+*)
+
+TYPE
+ TExternalID = CLASS
+ PublicId : STRING;
+ SystemId : STRING;
+ Final : PChar;
+ CONSTRUCTOR Create (Start : PChar);
+ END;
+
+CONSTRUCTOR TExternalID.Create (Start : PChar);
+BEGIN
+ INHERITED Create;
+ Final := Start;
+ IF StrLComp (Start, 'SYSTEM', 6) = 0 THEN BEGIN
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, SystemID, Final);
+ END
+ ELSE IF StrLComp (Start, 'PUBLIC', 6) = 0 THEN BEGIN
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, PublicID, Final);
+ INC (Final);
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, SystemID, Final);
+ END;
+END;
+
+
+(*
+===============================================================================================
+TXmlParser
+===============================================================================================
+*)
+
+CONSTRUCTOR TXmlParser.Create;
+BEGIN
+ INHERITED Create;
+ FBuffer := NIL;
+ FBufferSize := 0;
+ Elements := TElemList.Create;
+ Entities := TNvpList.Create;
+ ParEntities := TNvpList.Create;
+ Notations := TNvpList.Create;
+ CurAttr := TAttrList.Create;
+ EntityStack := TEntityStack.Create (Self);
+ Clear;
+END;
+
+
+DESTRUCTOR TXmlParser.Destroy;
+BEGIN
+ Clear;
+ Elements.Free;
+ Entities.Free;
+ ParEntities.Free;
+ Notations.Free;
+ CurAttr.Free;
+ EntityStack.Free;
+ INHERITED Destroy;
+END;
+
+
+PROCEDURE TXmlParser.Clear;
+ // Free Buffer and clear all object attributes
+BEGIN
+ IF (FBufferSize > 0) AND (FBuffer <> NIL) THEN
+ FreeMem (FBuffer);
+ FBuffer := NIL;
+ FBufferSize := 0;
+ FSource := '';
+ FXmlVersion := '';
+ FEncoding := '';
+ FStandalone := FALSE;
+ FRootName := '';
+ FDtdcFinal := NIL;
+ FNormalize := TRUE;
+ Elements.Clear;
+ Entities.Clear;
+ ParEntities.Clear;
+ Notations.Clear;
+ CurAttr.Clear;
+ EntityStack.Clear;
+END;
+
+
+FUNCTION TXmlParser.LoadFromFile (Filename : STRING; FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
+ // Loads Document from given file
+ // Returns TRUE if successful
+VAR
+ f : FILE;
+ ReadIn : INTEGER;
+ OldFileMode : INTEGER;
+BEGIN
+ Result := FALSE;
+ Clear;
+
+ // --- Open File
+ OldFileMode := SYSTEM.FileMode;
+ TRY
+ SYSTEM.FileMode := FileMode;
+ TRY
+ AssignFile (f, Filename);
+ Reset (f, 1);
+ EXCEPT
+ EXIT;
+ END;
+
+ TRY
+ // --- Allocate Memory
+ TRY
+ FBufferSize := Filesize (f) + 1;
+ GetMem (FBuffer, FBufferSize);
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+
+ // --- Read File
+ TRY
+ BlockRead (f, FBuffer^, FBufferSize, ReadIn);
+ (FBuffer+ReadIn)^ := #0; // NULL termination
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+ FINALLY
+ CloseFile (f);
+ END;
+
+ FSource := Filename;
+ Result := TRUE;
+
+ FINALLY
+ SYSTEM.FileMode := OldFileMode;
+ END;
+END;
+
+
+FUNCTION TXmlParser.LoadFromBuffer (Buffer : PChar) : BOOLEAN;
+ // Loads Document from another buffer
+ // Returns TRUE if successful
+ // The "Source" property becomes '' if successful
+BEGIN
+ Result := FALSE;
+ Clear;
+ FBufferSize := StrLen (Buffer) + 1;
+ TRY
+ GetMem (FBuffer, FBufferSize);
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+ StrCopy (FBuffer, Buffer);
+ FSource := '';
+ Result := TRUE;
+END;
+
+
+PROCEDURE TXmlParser.SetBuffer (Buffer : PChar); // References another buffer
+BEGIN
+ Clear;
+ FBuffer := Buffer;
+ FBufferSize := 0;
+ FSource := '';
+END;
+
+
+//-----------------------------------------------------------------------------------------------
+// Scanning through the document
+//-----------------------------------------------------------------------------------------------
+
+PROCEDURE TXmlParser.StartScan;
+BEGIN
+ CurPartType := ptNone;
+ CurName := '';
+ CurContent := '';
+ CurStart := NIL;
+ CurFinal := NIL;
+ CurAttr.Clear;
+ EntityStack.Clear;
+END;
+
+
+FUNCTION TXmlParser.Scan : BOOLEAN;
+ // Scans the next Part
+ // Returns TRUE if a part could be found, FALSE if there is no part any more
+ //
+ // "IsDone" can be set to FALSE by AnalyzeText in order to go to the next part
+ // if there is no Content due to normalization
+VAR
+ IsDone : BOOLEAN;
+BEGIN
+ REPEAT
+ IsDone := TRUE;
+
+ // --- Start of next Part
+ IF CurStart = NIL
+ THEN CurStart := DocBuffer
+ ELSE CurStart := CurFinal+1;
+ CurFinal := CurStart;
+
+ // --- End of Document of Pop off a new part from the Entity stack?
+ IF CurStart^ = #0 THEN
+ CurStart := EntityStack.Pop;
+
+ // --- No Document or End Of Document: Terminate Scan
+ IF (CurStart = NIL) OR (CurStart^ = #0) THEN BEGIN
+ CurStart := StrEnd (DocBuffer);
+ CurFinal := CurStart-1;
+ EntityStack.Clear;
+ Result := FALSE;
+ EXIT;
+ END;
+
+ IF (StrLComp (CurStart, '');
+ IF CurFinal <> NIL
+ THEN INC (CurFinal)
+ ELSE CurFinal := StrEnd (CurStart)-1;
+ FCurEncoding := AnsiUpperCase (CurAttr.Value ('encoding'));
+ IF FCurEncoding = '' THEN
+ FCurEncoding := 'UTF-8'; // Default XML Encoding is UTF-8
+ CurPartType := ptXmlProlog;
+ CurName := '';
+ CurContent := '';
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeComment (Start : PChar; VAR Final : PChar);
+ // Analyze Comments
+BEGIN
+ Final := StrPos (Start+4, '-->');
+ IF Final = NIL
+ THEN Final := StrEnd (Start)-1
+ ELSE INC (Final, 2);
+ CurPartType := ptComment;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzePI (Start : PChar; VAR Final : PChar);
+ // Analyze Processing Instructions (PI)
+ // This is also called for Character
+VAR
+ F : PChar;
+BEGIN
+ CurPartType := ptPI;
+ Final := StrPos (Start+2, '?>');
+ IF Final = NIL
+ THEN Final := StrEnd (Start)-1
+ ELSE INC (Final);
+ ExtractName (Start+2, CWhitespace + ['?', '>'], F);
+ SetStringSF (CurName, Start+2, F);
+ SetStringSF (CurContent, F+1, Final-2);
+ CurAttr.Analyze (F+1, F);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeDtdc;
+ (* Analyze Document Type Declaration
+ doctypedecl ::= ''
+ markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
+ PEReference ::= '%' Name ';'
+
+ elementdecl ::= ''
+ AttlistDecl ::= ''
+ EntityDecl ::= '' |
+ ''
+ NotationDecl ::= ''
+ PI ::= '' PITarget (S (Char* - (Char* '?>' Char* )))? '?>'
+ Comment ::= '' *)
+TYPE
+ TPhase = (phName, phDtd, phInternal, phFinishing);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ ExternalID : TExternalID;
+ ExternalDTD : TXmlParser;
+ DER : TDtdElementRec;
+BEGIN
+ DER.Start := CurStart;
+ EntityStack.Clear; // Clear stack for Parameter Entities
+ CurPartType := ptDtdc;
+
+ // --- Don't read DTDc twice
+ IF FDtdcFinal <> NIL THEN BEGIN
+ CurFinal := FDtdcFinal;
+ EXIT;
+ END;
+
+ // --- Scan DTDc
+ CurFinal := CurStart + 9; // First char after '' : BREAK;
+ ELSE IF NOT (CurFinal^ IN CWhitespace) THEN BEGIN
+ CASE Phase OF
+ phName : IF (CurFinal^ IN CNameStart) THEN BEGIN
+ ExtractName (CurFinal, CWhitespace + ['[', '>'], F);
+ SetStringSF (FRootName, CurFinal, F);
+ CurFinal := F;
+ Phase := phDtd;
+ END;
+ phDtd : IF (StrLComp (CurFinal, 'SYSTEM', 6) = 0) OR
+ (StrLComp (CurFinal, 'PUBLIC', 6) = 0) THEN BEGIN
+ ExternalID := TExternalID.Create (CurFinal);
+ ExternalDTD := LoadExternalEntity (ExternalId.SystemId, ExternalID.PublicId, '');
+ F := StrPos (ExternalDtd.DocBuffer, ' NIL THEN
+ AnalyzeDtdElements (F, F);
+ ExternalDTD.Free;
+ CurFinal := ExternalID.Final;
+ ExternalID.Free;
+ END;
+ ELSE BEGIN
+ DER.ElementType := deError;
+ DER.Pos := CurFinal;
+ DER.Final := CurFinal;
+ DtdElementFound (DER);
+ END;
+ END;
+
+ END;
+ END;
+ INC (CurFinal);
+ UNTIL FALSE;
+
+ CurPartType := ptDtdc;
+ CurName := '';
+ CurContent := '';
+
+ // It is an error in the document if "EntityStack" is not empty now
+ IF EntityStack.Count > 0 THEN BEGIN
+ DER.ElementType := deError;
+ DER.Final := CurFinal;
+ DER.Pos := CurFinal;
+ DtdElementFound (DER);
+ END;
+
+ EntityStack.Clear; // Clear stack for General Entities
+ FDtdcFinal := CurFinal;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeDtdElements (Start : PChar; VAR Final : PChar);
+ // Analyze the "Elements" of a DTD contained in the external or
+ // internal DTD subset.
+VAR
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start;
+ REPEAT
+ CASE Final^ OF
+ '%' : BEGIN
+ PushPE (Final);
+ CONTINUE;
+ END;
+ #0 : IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ CurFinal := EntityStack.Pop;
+ CONTINUE;
+ END;
+ ']',
+ '>' : BREAK;
+ '<' : IF StrLComp (Final, '');
+
+ // --- Set Default Attribute values for nonexistent attributes
+ IF (CurPartType = ptStartTag) OR (CurPartType = ptEmptyTag) THEN BEGIN
+ ElemDef := Elements.Node (CurName);
+ IF ElemDef <> NIL THEN BEGIN
+ FOR I := 0 TO ElemDef.Count-1 DO BEGIN
+ AttrDef := TAttrDef (ElemDef [I]);
+ Attr := TAttr (CurAttr.Node (AttrDef.Name));
+ IF (Attr = NIL) AND (AttrDef.Value <> '') THEN BEGIN
+ Attr := TAttr.Create (AttrDef.Name, AttrDef.Value);
+ Attr.ValueType := vtDefault;
+ CurAttr.Add (Attr);
+ END;
+ IF Attr <> NIL THEN BEGIN
+ CASE AttrDef.DefaultType OF
+ adDefault : ;
+ adRequired : ; // -!- It is an error in the document if "Attr.Value" is an empty string
+ adImplied : Attr.ValueType := vtImplied;
+ adFixed : BEGIN
+ Attr.ValueType := vtFixed;
+ Attr.Value := AttrDef.Value;
+ END;
+ END;
+ Attr.AttrType := AttrDef.AttrType;
+ END;
+ END;
+ END;
+
+ // --- Normalize Attribute Values. XmlSpec:
+ // - a character reference is processed by appending the referenced character to the attribute value
+ // - an entity reference is processed by recursively processing the replacement text of the entity
+ // - a whitespace character (#x20, #xD, #xA, #x9) is processed by appending #x20 to the normalized value,
+ // except that only a single #x20 is appended for a "#xD#xA" sequence that is part of an external
+ // parsed entity or the literal entity value of an internal parsed entity
+ // - other characters are processed by appending them to the normalized value
+ // If the declared value is not CDATA, then the XML processor must further process the
+ // normalized attribute value by discarding any leading and trailing space (#x20) characters,
+ // and by replacing sequences of space (#x20) characters by a single space (#x20) character.
+ // All attributes for which no declaration has been read should be treated by a
+ // non-validating parser as if declared CDATA.
+ // !!! The XML 1.0 SE specification is somewhat different here
+ // This code does not conform exactly to this specification
+ FOR I := 0 TO CurAttr.Count-1 DO
+ WITH TAttr (CurAttr [I]) DO BEGIN
+ ReplaceGeneralEntities (Value);
+ ReplaceCharacterEntities (Value);
+ IF (AttrType <> atCData) AND (AttrType <> atUnknown)
+ THEN Value := TranslateEncoding (TrimWs (ConvertWs (Value, TRUE)))
+ ELSE Value := TranslateEncoding (ConvertWs (Value, FALSE));
+ END;
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeCData;
+ // Analyze CDATA Sections
+BEGIN
+ CurPartType := ptCData;
+ CurFinal := StrPos (CurStart, CDEnd);
+ IF CurFinal = NIL THEN BEGIN
+ CurFinal := StrEnd (CurStart)-1;
+ CurContent := TranslateEncoding (StrPas (CurStart+Length (CDStart)));
+ END
+ ELSE BEGIN
+ SetStringSF (CurContent, CurStart+Length (CDStart), CurFinal-1);
+ INC (CurFinal, Length (CDEnd)-1);
+ CurContent := TranslateEncoding (CurContent);
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeText (VAR IsDone : BOOLEAN);
+ (* Analyzes Text Content between Tags. CurFinal will point to the last content character.
+ Content ends at a '<' character or at the end of the document.
+ Entity References and Character Entity references are resolved.
+ If PackSpaces is TRUE, contiguous Whitespace Characters will be compressed to
+ one Space #x20 character, Whitespace at the beginning and end of content will
+ be trimmed off and content which is or becomes empty is not returned to
+ the application (in this case, "IsDone" is set to FALSE which causes the
+ Scan method to proceed directly to the next part. *)
+
+ PROCEDURE ProcessEntity;
+ (* Is called if there is an ampsersand '&' character found in the document.
+ IN "CurFinal" points to the ampersand
+ OUT "CurFinal" points to the first character after the semi-colon ';' *)
+ VAR
+ P : PChar;
+ Name : STRING;
+ EntityDef : TEntityDef;
+ ExternalEntity : TXmlParser;
+ BEGIN
+ P := StrScan (CurFinal , ';');
+ IF P <> NIL THEN BEGIN
+ SetStringSF (Name, CurFinal+1, P-1);
+
+ // Is it a Character Entity?
+ IF (CurFinal+1)^ = '#' THEN BEGIN
+ IF UpCase ((CurFinal+2)^) = 'X' // !!! Can't use "CHR" for Unicode characters > 255:
+ THEN CurContent := CurContent + CHR (StrToIntDef ('$'+Copy (Name, 3, MaxInt), 32))
+ ELSE CurContent := CurContent + CHR (StrToIntDef (Copy (Name, 2, MaxInt), 32));
+ CurFinal := P+1;
+ EXIT;
+ END
+
+ // Is it a Predefined Entity?
+ ELSE IF Name = 'lt' THEN BEGIN CurContent := CurContent + '<'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'gt' THEN BEGIN CurContent := CurContent + '>'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'amp' THEN BEGIN CurContent := CurContent + '&'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'apos' THEN BEGIN CurContent := CurContent + ''''; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'quot' THEN BEGIN CurContent := CurContent + '"'; CurFinal := P+1; EXIT; END;
+
+ // Replace with Entity from DTD
+ EntityDef := TEntityDef (Entities.Node (Name));
+ IF EntityDef <> NIL THEN BEGIN
+ IF EntityDef.Value <> '' THEN BEGIN
+ EntityStack.Push (P+1);
+ CurFinal := PChar (EntityDef.Value);
+ END
+ ELSE BEGIN
+ ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
+ EntityStack.Push (ExternalEntity, P+1);
+ CurFinal := ExternalEntity.DocBuffer;
+ END;
+ END
+ ELSE BEGIN
+ CurContent := CurContent + Name;
+ CurFinal := P+1;
+ END;
+ END
+ ELSE BEGIN
+ INC (CurFinal);
+ END;
+ END;
+
+VAR
+ C : INTEGER;
+BEGIN
+ CurFinal := CurStart;
+ CurPartType := ptContent;
+ CurContent := '';
+ C := 0;
+ REPEAT
+ CASE CurFinal^ OF
+ '&' : BEGIN
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ C := 0;
+ ProcessEntity;
+ CONTINUE;
+ END;
+ #0 : BEGIN
+ IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ C := 0;
+ CurFinal := EntityStack.Pop;
+ CONTINUE;
+ END;
+ END;
+ '<' : BREAK;
+ ELSE INC (C);
+ END;
+ INC (CurFinal);
+ UNTIL FALSE;
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ DEC (CurFinal);
+
+ IF FNormalize THEN BEGIN
+ CurContent := ConvertWs (TrimWs (CurContent), TRUE);
+ IsDone := CurContent <> ''; // IsDone will only get FALSE if PackSpaces is TRUE
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
+ (* Parse ' character
+ XmlSpec 3.2:
+ elementdecl ::= ''
+ contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
+ Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
+ '(' S? '#PCDATA' S? ')'
+ children ::= (choice | seq) ('?' | '*' | '+')?
+ choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+
+ More simply:
+ contentspec ::= EMPTY
+ ANY
+ '(#PCDATA)'
+ '(#PCDATA | A | B)*'
+ '(A, B, C)'
+ '(A | B | C)'
+ '(A?, B*, C+),
+ '(A, (B | C | D)* )' *)
+VAR
+ Element : TElemDef;
+ Elem2 : TElemDef;
+ F : PChar;
+ DER : TDtdElementRec;
+BEGIN
+ Element := TElemDef.Create;
+ Final := Start + 9;
+ DER.Start := Start;
+ REPEAT
+ IF Final^ = '>' THEN BREAK;
+ IF (Final^ IN CNameStart) AND (Element.Name = '') THEN BEGIN
+ ExtractName (Final, CWhitespace, F);
+ SetStringSF (Element.Name, Final, F);
+ Final := F;
+ F := StrScan (Final+1, '>');
+ IF F = NIL THEN BEGIN
+ Element.Definition := STRING (Final);
+ Final := StrEnd (Final);
+ BREAK;
+ END
+ ELSE BEGIN
+ SetStringSF (Element.Definition, Final+1, F-1);
+ Final := F;
+ BREAK;
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ Element.Definition := DelChars (Element.Definition, CWhitespace);
+ ReplaceParameterEntities (Element.Definition);
+ IF Element.Definition = 'EMPTY' THEN Element.ElemType := etEmpty
+ ELSE IF Element.Definition = 'ANY' THEN Element.ElemType := etAny
+ ELSE IF Copy (Element.Definition, 1, 8) = '(#PCDATA' THEN Element.ElemType := etMixed
+ ELSE IF Copy (Element.Definition, 1, 1) = '(' THEN Element.ElemType := etChildren
+ ELSE Element.ElemType := etAny;
+
+ Elem2 := Elements.Node (Element.Name);
+ IF Elem2 <> NIL THEN
+ Elements.Delete (Elements.IndexOf (Elem2));
+ Elements.Add (Element);
+ Final := StrScanE (Final, '>');
+ DER.ElementType := deElement;
+ DER.ElemDef := Element;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
+ (* Parse ' character
+ XmlSpec 3.3:
+ AttlistDecl ::= ''
+ AttDef ::= S Name S AttType S DefaultDecl
+ AttType ::= StringType | TokenizedType | EnumeratedType
+ StringType ::= 'CDATA'
+ TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
+ EnumeratedType ::= NotationType | Enumeration
+ NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
+ DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
+ AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
+ Examples:
+ *)
+TYPE
+ TPhase = (phElementName, phName, phType, phNotationContent, phDefault);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ ElementName : STRING;
+ ElemDef : TElemDef;
+ AttrDef : TAttrDef;
+ AttrDef2 : TAttrDef;
+ Strg : STRING;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 9; // The character after ' : BREAK;
+ ELSE CASE Phase OF
+ phElementName : BEGIN
+ ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
+ SetStringSF (ElementName, Final, F);
+ Final := F;
+ ElemDef := Elements.Node (ElementName);
+ IF ElemDef = NIL THEN BEGIN
+ ElemDef := TElemDef.Create;
+ ElemDef.Name := ElementName;
+ ElemDef.Definition := 'ANY';
+ ElemDef.ElemType := etAny;
+ Elements.Add (ElemDef);
+ END;
+ Phase := phName;
+ END;
+ phName : BEGIN
+ AttrDef := TAttrDef.Create;
+ ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
+ SetStringSF (AttrDef.Name, Final, F);
+ Final := F;
+ AttrDef2 := TAttrDef (ElemDef.Node (AttrDef.Name));
+ IF AttrDef2 <> NIL THEN
+ ElemDef.Delete (ElemDef.IndexOf (AttrDef2));
+ ElemDef.Add (AttrDef);
+ Phase := phType;
+ END;
+ phType : BEGIN
+ IF Final^ = '(' THEN BEGIN
+ F := StrScan (Final+1, ')');
+ IF F <> NIL
+ THEN SetStringSF (AttrDef.TypeDef, Final+1, F-1)
+ ELSE AttrDef.TypeDef := STRING (Final+1);
+ AttrDef.TypeDef := DelChars (AttrDef.TypeDef, CWhitespace);
+ AttrDef.AttrType := atEnumeration;
+ ReplaceParameterEntities (AttrDef.TypeDef);
+ ReplaceCharacterEntities (AttrDef.TypeDef);
+ Phase := phDefault;
+ END
+ ELSE IF StrLComp (Final, 'NOTATION', 8) = 0 THEN BEGIN
+ INC (Final, 8);
+ AttrDef.AttrType := atNotation;
+ Phase := phNotationContent;
+ END
+ ELSE BEGIN
+ ExtractName (Final, CWhitespace+CQuoteChar+['#'], F);
+ SetStringSF (AttrDef.TypeDef, Final, F);
+ IF AttrDef.TypeDef = 'CDATA' THEN AttrDef.AttrType := atCData
+ ELSE IF AttrDef.TypeDef = 'ID' THEN AttrDef.AttrType := atId
+ ELSE IF AttrDef.TypeDef = 'IDREF' THEN AttrDef.AttrType := atIdRef
+ ELSE IF AttrDef.TypeDef = 'IDREFS' THEN AttrDef.AttrType := atIdRefs
+ ELSE IF AttrDef.TypeDef = 'ENTITY' THEN AttrDef.AttrType := atEntity
+ ELSE IF AttrDef.TypeDef = 'ENTITIES' THEN AttrDef.AttrType := atEntities
+ ELSE IF AttrDef.TypeDef = 'NMTOKEN' THEN AttrDef.AttrType := atNmToken
+ ELSE IF AttrDef.TypeDef = 'NMTOKENS' THEN AttrDef.AttrType := atNmTokens;
+ Phase := phDefault;
+ END
+ END;
+ phNotationContent : BEGIN
+ F := StrScan (Final, ')');
+ IF F <> NIL THEN
+ SetStringSF (AttrDef.Notations, Final+1, F-1)
+ ELSE BEGIN
+ AttrDef.Notations := STRING (Final+1);
+ Final := StrEnd (Final);
+ END;
+ ReplaceParameterEntities (AttrDef.Notations);
+ AttrDef.Notations := DelChars (AttrDef.Notations, CWhitespace);
+ Phase := phDefault;
+ END;
+ phDefault : BEGIN
+ IF Final^ = '#' THEN BEGIN
+ ExtractName (Final, CWhiteSpace + CQuoteChar, F);
+ SetStringSF (Strg, Final, F);
+ Final := F;
+ ReplaceParameterEntities (Strg);
+ IF Strg = '#REQUIRED' THEN BEGIN AttrDef.DefaultType := adRequired; Phase := phName; END
+ ELSE IF Strg = '#IMPLIED' THEN BEGIN AttrDef.DefaultType := adImplied; Phase := phName; END
+ ELSE IF Strg = '#FIXED' THEN AttrDef.DefaultType := adFixed;
+ END
+ ELSE IF (Final^ IN CQuoteChar) THEN BEGIN
+ ExtractQuote (Final, AttrDef.Value, Final);
+ ReplaceParameterEntities (AttrDef.Value);
+ ReplaceCharacterEntities (AttrDef.Value);
+ Phase := phName;
+ END;
+ IF Phase = phName THEN BEGIN
+ AttrDef := NIL;
+ END;
+ END;
+
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+
+ Final := StrScan (Final, '>');
+
+ DER.ElementType := deAttList;
+ DER.ElemDef := ElemDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
+ (* Parse ' character
+ XmlSpec 4.2:
+ EntityDecl ::= '' |
+ ''
+ EntityDef ::= EntityValue | (ExternalID NDataDecl?)
+ PEDef ::= EntityValue | ExternalID
+ NDataDecl ::= S 'NDATA' S Name
+ EntityValue ::= '"' ([^%&"] | PEReference | EntityRef | CharRef)* '"' |
+ "'" ([^%&'] | PEReference | EntityRef | CharRef)* "'"
+ PEReference ::= '%' Name ';'
+
+ Examples
+
+
+
+ ">
+
+
+ Dies ist ein Test-Absatz">
+ *)
+TYPE
+ TPhase = (phName, phContent, phNData, phNotationName, phFinalGT);
+VAR
+ Phase : TPhase;
+ IsParamEntity : BOOLEAN;
+ F : PChar;
+ ExternalID : TExternalID;
+ EntityDef : TEntityDef;
+ EntityDef2 : TEntityDef;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 8; // First char after ' : BREAK;
+ ELSE CASE Phase OF
+ phName : IF Final^ IN CNameStart THEN BEGIN
+ ExtractName (Final, CWhitespace + CQuoteChar, F);
+ SetStringSF (EntityDef.Name, Final, F);
+ Final := F;
+ Phase := phContent;
+ END;
+ phContent : IF Final^ IN CQuoteChar THEN BEGIN
+ ExtractQuote (Final, EntityDef.Value, Final);
+ Phase := phFinalGT;
+ END
+ ELSE IF (StrLComp (Final, 'SYSTEM', 6) = 0) OR
+ (StrLComp (Final, 'PUBLIC', 6) = 0) THEN BEGIN
+ ExternalID := TExternalID.Create (Final);
+ EntityDef.SystemId := ExternalID.SystemId;
+ EntityDef.PublicId := ExternalID.PublicId;
+ Final := ExternalID.Final;
+ Phase := phNData;
+ ExternalID.Free;
+ END;
+ phNData : IF StrLComp (Final, 'NDATA', 5) = 0 THEN BEGIN
+ INC (Final, 4);
+ Phase := phNotationName;
+ END;
+ phNotationName : IF Final^ IN CNameStart THEN BEGIN
+ ExtractName (Final, CWhitespace + ['>'], F);
+ SetStringSF (EntityDef.NotationName, Final, F);
+ Final := F;
+ Phase := phFinalGT;
+ END;
+ phFinalGT : ; // -!- There is an error in the document if this branch is called
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ IF IsParamEntity THEN BEGIN
+ EntityDef2 := TEntityDef (ParEntities.Node (EntityDef.Name));
+ IF EntityDef2 <> NIL THEN
+ ParEntities.Delete (ParEntities.IndexOf (EntityDef2));
+ ParEntities.Add (EntityDef);
+ ReplaceCharacterEntities (EntityDef.Value);
+ END
+ ELSE BEGIN
+ EntityDef2 := TEntityDef (Entities.Node (EntityDef.Name));
+ IF EntityDef2 <> NIL THEN
+ Entities.Delete (Entities.IndexOf (EntityDef2));
+ Entities.Add (EntityDef);
+ ReplaceParameterEntities (EntityDef.Value); // Create replacement texts (see XmlSpec 4.5)
+ ReplaceCharacterEntities (EntityDef.Value);
+ END;
+ Final := StrScanE (Final, '>');
+
+ DER.ElementType := deEntity;
+ DER.EntityDef := EntityDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
+ // Parse ' character
+ // XmlSpec 4.7: NotationDecl ::= ''
+TYPE
+ TPhase = (phName, phExtId, phEnd);
+VAR
+ ExternalID : TExternalID;
+ Phase : TPhase;
+ F : PChar;
+ NotationDef : TNotationDef;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 10; // Character after ',
+ #0 : BREAK;
+ ELSE CASE Phase OF
+ phName : BEGIN
+ ExtractName (Final, CWhitespace + ['>'], F);
+ SetStringSF (NotationDef.Name, Final, F);
+ Final := F;
+ Phase := phExtId;
+ END;
+ phExtId : BEGIN
+ ExternalID := TExternalID.Create (Final);
+ NotationDef.Value := ExternalID.SystemId;
+ NotationDef.PublicId := ExternalID.PublicId;
+ Final := ExternalId.Final;
+ ExternalId.Free;
+ Phase := phEnd;
+ END;
+ phEnd : ; // -!- There is an error in the document if this branch is called
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ Notations.Add (NotationDef);
+ Final := StrScanE (Final, '>');
+
+ DER.ElementType := deNotation;
+ DER.NotationDef := NotationDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.PushPE (VAR Start : PChar);
+ (* If there is a parameter entity reference found in the data stream,
+ the current position will be pushed to the entity stack.
+ Start: IN Pointer to the '%' character starting the PE reference
+ OUT Pointer to first character of PE replacement text *)
+VAR
+ P : PChar;
+ EntityDef : TEntityDef;
+BEGIN
+ P := StrScan (Start, ';');
+ IF P <> NIL THEN BEGIN
+ EntityDef := TEntityDef (ParEntities.Node (StrSFPas (Start+1, P-1)));
+ IF EntityDef <> NIL THEN BEGIN
+ EntityStack.Push (P+1);
+ Start := PChar (EntityDef.Value);
+ END
+ ELSE
+ Start := P+1;
+ END;
+END;
+
+
+PROCEDURE TXmlParser.ReplaceCharacterEntities (VAR Str : STRING);
+ // Replaces all Character Entity References in the String
+VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER; // Length of Entity Reference
+BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str) + Start-1, '');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ IF CompareText (Str [PosAmp+2], 'x') = 0 // !!! Can't use "CHR" for Unicode characters > 255
+ THEN Str [PosAmp] := CHR (StrToIntDef ('$'+Copy (Str, PosAmp+3, Len-4), 0))
+ ELSE Str [PosAmp] := CHR (StrToIntDef (Copy (Str, PosAmp+2, Len-3), 32));
+ Delete (Str, PosAmp+1, Len-1);
+ Start := PosAmp + 1;
+ UNTIL FALSE;
+END;
+
+
+PROCEDURE TXmlParser.ReplaceParameterEntities (VAR Str : STRING);
+ // Recursively replaces all Parameter Entity References in the String
+ PROCEDURE ReplaceEntities (VAR Str : STRING);
+ VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER;
+ Entity : TEntityDef;
+ Repl : STRING; // Replacement
+ BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str)+Start-1, '%');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ Entity := TEntityDef (ParEntities.Node (Copy (Str, PosAmp+1, Len-2)));
+ IF Entity <> NIL THEN BEGIN
+ Repl := Entity.Value;
+ ReplaceEntities (Repl); // Recursion
+ END
+ ELSE
+ Repl := Copy (Str, PosAmp, Len);
+ Delete (Str, PosAmp, Len);
+ Insert (Repl, Str, PosAmp);
+ Start := PosAmp + Length (Repl);
+ UNTIL FALSE;
+ END;
+BEGIN
+ ReplaceEntities (Str);
+END;
+
+
+PROCEDURE TXmlParser.ReplaceGeneralEntities (VAR Str : STRING);
+ // Recursively replaces General Entity References in the String
+ PROCEDURE ReplaceEntities (VAR Str : STRING);
+ VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER;
+ EntityDef : TEntityDef;
+ EntName : STRING;
+ Repl : STRING; // Replacement
+ ExternalEntity : TXmlParser;
+ BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str)+Start-1, '&');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ EntName := Copy (Str, PosAmp+1, Len-2);
+ IF EntName = 'lt' THEN Repl := '<'
+ ELSE IF EntName = 'gt' THEN Repl := '>'
+ ELSE IF EntName = 'amp' THEN Repl := '&'
+ ELSE IF EntName = 'apos' THEN Repl := ''''
+ ELSE IF EntName = 'quot' THEN Repl := '"'
+ ELSE BEGIN
+ EntityDef := TEntityDef (Entities.Node (EntName));
+ IF EntityDef <> NIL THEN BEGIN
+ IF EntityDef.Value <> '' THEN // Internal Entity
+ Repl := EntityDef.Value
+ ELSE BEGIN // External Entity
+ ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
+ Repl := StrPas (ExternalEntity.DocBuffer); // !!! What if it contains a Text Declaration?
+ ExternalEntity.Free;
+ END;
+ ReplaceEntities (Repl); // Recursion
+ END
+ ELSE
+ Repl := Copy (Str, PosAmp, Len);
+ END;
+ Delete (Str, PosAmp, Len);
+ Insert (Repl, Str, PosAmp);
+ Start := PosAmp + Length (Repl);
+ UNTIL FALSE;
+ END;
+BEGIN
+ ReplaceEntities (Str);
+END;
+
+
+FUNCTION TXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
+ // This will be called whenever there is a Parsed External Entity or
+ // the DTD External Subset to be parsed.
+ // It has to create a TXmlParser instance and load the desired Entity.
+ // This instance of LoadExternalEntity assumes that "SystemId" is a valid
+ // file name (relative to the Document source) and loads this file using
+ // the LoadFromFile method.
+VAR
+ Filename : STRING;
+BEGIN
+ // --- Convert System ID to complete filename
+ Filename := StringReplace (SystemId, '/', '\', [rfReplaceAll]);
+ IF Copy (FSource, 1, 1) <> '<' THEN
+ IF (Copy (Filename, 1, 2) = '\\') OR (Copy (Filename, 2, 1) = ':') THEN
+ // Already has an absolute Path
+ ELSE BEGIN
+ Filename := ExtractFilePath (FSource) + Filename;
+ END;
+
+ // --- Load the File
+ Result := TXmlParser.Create;
+ Result.LoadFromFile (Filename);
+END;
+
+
+FUNCTION TXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
+ // The member variable "CurEncoding" always holds the name of the current
+ // encoding, e.g. 'UTF-8' or 'ISO-8859-1'.
+ // This virtual method "TranslateEncoding" is responsible for translating
+ // the content passed in the "Source" parameter to the Encoding which
+ // is expected by the application.
+ // This instance of "TranlateEncoding" assumes that the Application expects
+ // Windows ANSI (Win1252) strings. It is able to transform UTF-8 or ISO-8859-1
+ // encodings.
+ // If you want your application to understand or create other encodings, you
+ // override this function.
+BEGIN
+ IF CurEncoding = 'UTF-8'
+ THEN Result := Utf8ToAnsi (Source)
+ ELSE Result := Source;
+END;
+
+
+PROCEDURE TXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
+ // This method is called for every element which is found in the DTD
+ // declaration. The variant record TDtdElementRec is passed which
+ // holds informations about the element.
+ // You can override this function to handle DTD declarations.
+ // Note that when you parse the same Document instance a second time,
+ // the DTD will not get parsed again.
+BEGIN
+END;
+
+
+FUNCTION TXmlParser.GetDocBuffer: PChar;
+ // Returns FBuffer or a pointer to a NUL char if Buffer is empty
+BEGIN
+ IF FBuffer = NIL
+ THEN Result := #0
+ ELSE Result := FBuffer;
+END;
+
+
+(*$IFNDEF HAS_CONTNRS_UNIT
+===============================================================================================
+TObjectList
+===============================================================================================
+*)
+
+DESTRUCTOR TObjectList.Destroy;
+BEGIN
+ Clear;
+ SetCapacity(0);
+ INHERITED Destroy;
+END;
+
+
+PROCEDURE TObjectList.Delete (Index : INTEGER);
+BEGIN
+ IF (Index < 0) OR (Index >= Count) THEN EXIT;
+ TObject (Items [Index]).Free;
+ INHERITED Delete (Index);
+END;
+
+
+PROCEDURE TObjectList.Clear;
+BEGIN
+ WHILE Count > 0 DO
+ Delete (Count-1);
+END;
+
+(*$ENDIF *)
+
+(*
+===============================================================================================
+TNvpNode
+--------
+Node base class for the TNvpList
+===============================================================================================
+*)
+
+CONSTRUCTOR TNvpNode.Create (TheName, TheValue : STRING);
+BEGIN
+ INHERITED Create;
+ Name := TheName;
+ Value := TheValue;
+END;
+
+
+(*
+===============================================================================================
+TNvpList
+--------
+A generic List of Name-Value Pairs, based on the TObjectList introduced in Delphi 5
+===============================================================================================
+*)
+
+PROCEDURE TNvpList.Add (Node : TNvpNode);
+VAR
+ I : INTEGER;
+BEGIN
+ FOR I := Count-1 DOWNTO 0 DO
+ IF Node.Name > TNvpNode (Items [I]).Name THEN BEGIN
+ Insert (I+1, Node);
+ EXIT;
+ END;
+ Insert (0, Node);
+END;
+
+
+
+FUNCTION TNvpList.Node (Name : STRING) : TNvpNode;
+ // Binary search for Node
+VAR
+ L, H : INTEGER; // Low, High Limit
+ T, C : INTEGER; // Test Index, Comparison result
+ Last : INTEGER; // Last Test Index
+BEGIN
+ IF Count=0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+
+ L := 0;
+ H := Count;
+ Last := -1;
+ REPEAT
+ T := (L+H) DIV 2;
+ IF T=Last THEN BREAK;
+ Result := TNvpNode (Items [T]);
+ C := CompareStr (Result.Name, Name);
+ IF C = 0 THEN EXIT
+ ELSE IF C < 0 THEN L := T
+ ELSE H := T;
+ Last := T;
+ UNTIL FALSE;
+ Result := NIL;
+END;
+
+
+FUNCTION TNvpList.Node (Index : INTEGER) : TNvpNode;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := NIL
+ ELSE Result := TNvpNode (Items [Index]);
+END;
+
+
+FUNCTION TNvpList.Value (Name : STRING) : STRING;
+VAR
+ Nvp : TNvpNode;
+BEGIN
+ Nvp := TNvpNode (Node (Name));
+ IF Nvp <> NIL
+ THEN Result := Nvp.Value
+ ELSE Result := '';
+END;
+
+
+FUNCTION TNvpList.Value (Index : INTEGER) : STRING;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := ''
+ ELSE Result := TNvpNode (Items [Index]).Value;
+END;
+
+
+FUNCTION TNvpList.Name (Index : INTEGER) : STRING;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := ''
+ ELSE Result := TNvpNode (Items [Index]).Name;
+END;
+
+
+(*
+===============================================================================================
+TAttrList
+List of Attributes. The "Analyze" method extracts the Attributes from the given Buffer.
+Is used for extraction of Attributes in Start-Tags, Empty-Element Tags and the "pseudo"
+attributes in XML Prologs, Text Declarations and PIs.
+===============================================================================================
+*)
+
+PROCEDURE TAttrList.Analyze (Start : PChar; VAR Final : PChar);
+ // Analyze the Buffer for Attribute=Name pairs.
+ // Terminates when there is a character which is not IN CNameStart
+ // (e.g. '?>' or '>' or '/>')
+TYPE
+ TPhase = (phName, phEq, phValue);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ Name : STRING;
+ Value : STRING;
+ Attr : TAttr;
+BEGIN
+ Clear;
+ Phase := phName;
+ Final := Start;
+ REPEAT
+ IF (Final^ = #0) OR (Final^ = '>') THEN BREAK;
+ IF NOT (Final^ IN CWhitespace) THEN
+ CASE Phase OF
+ phName : BEGIN
+ IF NOT (Final^ IN CNameStart) THEN EXIT;
+ ExtractName (Final, CWhitespace + ['=', '/'], F);
+ SetStringSF (Name, Final, F);
+ Final := F;
+ Phase := phEq;
+ END;
+ phEq : BEGIN
+ IF Final^ = '=' THEN
+ Phase := phValue
+ END;
+ phValue : BEGIN
+ IF Final^ IN CQuoteChar THEN BEGIN
+ ExtractQuote (Final, Value, F);
+ Attr := TAttr.Create;
+ Attr.Name := Name;
+ Attr.Value := Value;
+ Attr.ValueType := vtNormal;
+ Add (Attr);
+ Final := F;
+ Phase := phName;
+ END;
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+END;
+
+
+(*
+===============================================================================================
+TElemList
+List of TElemDef nodes.
+===============================================================================================
+*)
+
+FUNCTION TElemList.Node (Name : STRING) : TElemDef;
+ // Binary search for the Node with the given Name
+VAR
+ L, H : INTEGER; // Low, High Limit
+ T, C : INTEGER; // Test Index, Comparison result
+ Last : INTEGER; // Last Test Index
+BEGIN
+ IF Count=0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+
+ L := 0;
+ H := Count;
+ Last := -1;
+ REPEAT
+ T := (L+H) DIV 2;
+ IF T=Last THEN BREAK;
+ Result := TElemDef (Items [T]);
+ C := CompareStr (Result.Name, Name);
+ IF C = 0 THEN EXIT
+ ELSE IF C < 0 THEN L := T
+ ELSE H := T;
+ Last := T;
+ UNTIL FALSE;
+ Result := NIL;
+END;
+
+
+PROCEDURE TElemList.Add (Node : TElemDef);
+VAR
+ I : INTEGER;
+BEGIN
+ FOR I := Count-1 DOWNTO 0 DO
+ IF Node.Name > TElemDef (Items [I]).Name THEN BEGIN
+ Insert (I+1, Node);
+ EXIT;
+ END;
+ Insert (0, Node);
+END;
+
+
+(*
+===============================================================================================
+TScannerXmlParser
+A TXmlParser descendant for the TCustomXmlScanner component
+===============================================================================================
+*)
+
+TYPE
+ TScannerXmlParser = CLASS (TXmlParser)
+ Scanner : TCustomXmlScanner;
+ CONSTRUCTOR Create (TheScanner : TCustomXmlScanner);
+ FUNCTION LoadExternalEntity (SystemId, PublicId,
+ Notation : STRING) : TXmlParser; OVERRIDE;
+ FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; OVERRIDE;
+ PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); OVERRIDE;
+ END;
+
+CONSTRUCTOR TScannerXmlParser.Create (TheScanner : TCustomXmlScanner);
+BEGIN
+ INHERITED Create;
+ Scanner := TheScanner;
+END;
+
+
+FUNCTION TScannerXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
+BEGIN
+ IF Assigned (Scanner.FOnLoadExternal)
+ THEN Scanner.FOnLoadExternal (Scanner, SystemId, PublicId, Notation, Result)
+ ELSE Result := INHERITED LoadExternalEntity (SystemId, PublicId, Notation);
+END;
+
+
+FUNCTION TScannerXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
+BEGIN
+ IF Assigned (Scanner.FOnTranslateEncoding)
+ THEN Result := Scanner.FOnTranslateEncoding (Scanner, CurEncoding, Source)
+ ELSE Result := INHERITED TranslateEncoding (Source);
+END;
+
+
+PROCEDURE TScannerXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
+BEGIN
+ WITH DtdElementRec DO
+ CASE ElementType OF
+ deElement : Scanner.WhenElement (ElemDef);
+ deAttList : Scanner.WhenAttList (ElemDef);
+ deEntity : Scanner.WhenEntity (EntityDef);
+ deNotation : Scanner.WhenNotation (NotationDef);
+ dePI : Scanner.WhenPI (STRING (Target), STRING (Content), AttrList);
+ deComment : Scanner.WhenComment (StrSFPas (Start, Final));
+ deError : Scanner.WhenDtdError (Pos);
+ END;
+END;
+
+
+(*
+===============================================================================================
+TCustomXmlScanner
+===============================================================================================
+*)
+
+CONSTRUCTOR TCustomXmlScanner.Create (AOwner: TComponent);
+BEGIN
+ INHERITED;
+ FXmlParser := TScannerXmlParser.Create (Self);
+END;
+
+
+DESTRUCTOR TCustomXmlScanner.Destroy;
+BEGIN
+ FXmlParser.Free;
+ INHERITED;
+END;
+
+
+PROCEDURE TCustomXmlScanner.LoadFromFile (Filename : TFilename);
+ // Load XML Document from file
+BEGIN
+ FXmlParser.LoadFromFile (Filename);
+END;
+
+
+PROCEDURE TCustomXmlScanner.LoadFromBuffer (Buffer : PChar);
+ // Load XML Document from buffer
+BEGIN
+ FXmlParser.LoadFromBuffer (Buffer);
+END;
+
+
+PROCEDURE TCustomXmlScanner.SetBuffer (Buffer : PChar);
+ // Refer to Buffer
+BEGIN
+ FXmlParser.SetBuffer (Buffer);
+END;
+
+
+FUNCTION TCustomXmlScanner.GetFilename : TFilename;
+BEGIN
+ Result := FXmlParser.Source;
+END;
+
+
+FUNCTION TCustomXmlScanner.GetNormalize : BOOLEAN;
+BEGIN
+ Result := FXmlParser.Normalize;
+END;
+
+
+PROCEDURE TCustomXmlScanner.SetNormalize (Value : BOOLEAN);
+BEGIN
+ FXmlParser.Normalize := Value;
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN);
+ // Is called when the parser has parsed the xml ?> declaration of the prolog
+BEGIN
+ IF Assigned (FOnXmlProlog) THEN FOnXmlProlog (Self, XmlVersion, Encoding, Standalone);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenComment (Comment : STRING);
+ // Is called when the parser has parsed a
+BEGIN
+ IF Assigned (FOnComment) THEN FOnComment (Self, Comment);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenPI (Target, Content: STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed a
+BEGIN
+ IF Assigned (FOnPI) THEN FOnPI (Self, Target, Content, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenDtdRead (RootElementName : STRING);
+ // Is called when the parser has completely parsed the DTD
+BEGIN
+ IF Assigned (FOnDtdRead) THEN FOnDtdRead (Self, RootElementName);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenStartTag (TagName : STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed a start tag like
+BEGIN
+ IF Assigned (FOnStartTag) THEN FOnStartTag (Self, TagName, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenEmptyTag (TagName : STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed an Empty Element Tag like
+BEGIN
+ IF Assigned (FOnEmptyTag) THEN FOnEmptyTag (Self, TagName, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenEndTag (TagName : STRING);
+ // Is called when the parser has parsed an End Tag like
+ The user should first determine the available device ids by using
+ the supplied application "pa_devs".
+*}
+function Pa_GetDefaultOutputDevice(): TPaDeviceIndex; cdecl; external LibName;
+
+
+{** The type used to represent monotonic time in seconds that can be used
+ for syncronisation. The type is used for the outTime argument to the
+ PaStreamCallback and as the result of Pa_GetStreamTime().
+
+ @see PaStreamCallback, Pa_GetStreamTime
+*}
+type TPaTime = cdouble;
+
+
+{** A type used to specify one or more sample formats. Each value indicates
+ a possible format for sound data passed to and from the stream callback,
+ Pa_ReadStream and Pa_WriteStream.
+
+ The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
+ and aUInt8 are usually implemented by all implementations.
+
+ The floating point representation (paFloat32) uses +1.0 and -1.0 as the
+ maximum and minimum respectively.
+
+ paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+
+ The paNonInterleaved flag indicates that a multichannel buffer is passed
+ as a set of non-interleaved pointers.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
+ @see paFloat32, paInt16, paInt32, paInt24, paInt8
+ @see paUInt8, paCustomFormat, paNonInterleaved
+*}
+type TPaSampleFormat = culong;
+const
+ paFloat32 = TPaSampleFormat($00000001); {**< @see PaSampleFormat *}
+ paInt32 = TPaSampleFormat($00000002); {**< @see PaSampleFormat *}
+ paInt24 = TPaSampleFormat($00000004); {**< Packed 24 bit format. @see PaSampleFormat *}
+ paInt16 = TPaSampleFormat($00000008); {**< @see PaSampleFormat *}
+ paInt8 = TPaSampleFormat($00000010); {**< @see PaSampleFormat *}
+ paUInt8 = TPaSampleFormat($00000020); {**< @see PaSampleFormat *}
+ paCustomFormat = TPaSampleFormat($00010000); {**< @see PaSampleFormat *}
+ paNonInterleaved = TPaSampleFormat($80000000);
+
+{** A structure providing information and capabilities of PortAudio devices.
+ Devices may support input, output or both input and output.
+*}
+type
+ PPaDeviceInfo = ^TPaDeviceInfo;
+ TPaDeviceInfo = record
+ structVersion: cint; {* this is struct version 2 *}
+ name: PChar;
+ hostApi: TPaHostApiIndex; {* note this is a host API index, not a type id*}
+
+ maxInputChannels: cint;
+ maxOutputChannels: cint;
+
+ {* Default latency values for interactive performance. *}
+ defaultLowInputLatency: TPaTime;
+ defaultLowOutputLatency: TPaTime;
+ {* Default latency values for robust non-interactive applications (eg. playing sound files). *}
+ defaultHighInputLatency: TPaTime;
+ defaultHighOutputLatency: TPaTime;
+
+ defaultSampleRate: cdouble;
+ end;
+
+
+{** Retrieve a pointer to a PaDeviceInfo structure containing information
+ about the specified device.
+ @return A pointer to an immutable PaDeviceInfo structure. If the device
+ parameter is out of range the function returns NULL.
+
+ @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
+
+ @see PaDeviceInfo, PaDeviceIndex
+*}
+function Pa_GetDeviceInfo( device: TPaDeviceIndex ): PPaDeviceInfo; cdecl; external LibName;
+
+
+{** Parameters for one direction (input or output) of a stream.
+*}
+type
+ PPaStreamParameters = ^TPaStreamParameters;
+ TPaStreamParameters = record
+ {** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+ specifying the device to be used or the special constant
+ paUseHostApiSpecificDeviceSpecification which indicates that the actual
+ device(s) to use are specified in hostApiSpecificStreamInfo.
+ This field must not be set to paNoDevice.
+ *}
+ device: TPaDeviceIndex;
+
+ {** The number of channels of sound to be delivered to the
+ stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
+ It can range from 1 to the value of maxInputChannels in the
+ PaDeviceInfo record for the device specified by the device parameter.
+ *}
+ channelCount: cint;
+
+ {** The sample format of the buffer provided to the stream callback,
+ a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
+ by the PaSampleFormat enumeration.
+ *}
+ sampleFormat: TPaSampleFormat;
+
+ {** The desired latency in seconds. Where practical, implementations should
+ configure their latency based on these parameters, otherwise they may
+ choose the closest viable latency instead. Unless the suggested latency
+ is greater than the absolute upper limit for the device implementations
+ should round the suggestedLatency up to the next practial value - ie to
+ provide an equal or higher latency than suggestedLatency wherever possibe.
+ Actual latency values for an open stream may be retrieved using the
+ inputLatency and outputLatency fields of the PaStreamInfo structure
+ returned by Pa_GetStreamInfo().
+ @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
+ *}
+ suggestedLatency: TPaTime;
+
+ {** An optional pointer to a host api specific data structure
+ containing additional information for device setup and/or stream processing.
+ hostApiSpecificStreamInfo is never required for correct operation,
+ if not used it should be set to NULL.
+ *}
+ hostApiSpecificStreamInfo: Pointer;
+ end;
+
+
+{** Return code for Pa_IsFormatSupported indicating success. *}
+const paFormatIsSupported = (0);
+
+{** Determine whether it would be possible to open a stream with the specified
+ parameters.
+
+ @param inputParameters A structure that describes the input parameters used to
+ open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. inputParameters must be NULL for
+ output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used
+ to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. outputParameters must be NULL for
+ input-only streams.
+
+ @param sampleRate The required sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+
+ @return Returns 0 if the format is supported, and an error code indicating why
+ the format is not supported otherwise. The constant paFormatIsSupported is
+ provided to compare with the return value for success.
+
+ @see paFormatIsSupported, PaStreamParameters
+*}
+function Pa_IsFormatSupported( inputParameters: PPaStreamParameters;
+ outputParameters: PPaStreamParameters;
+ sampleRate: cdouble ): TPaError; cdecl; external LibName;
+
+
+
+{* Streaming types and functions *}
+
+
+{**
+ A single PaStream can provide multiple channels of real-time
+ streaming audio input and output to a client application. A stream
+ provides access to audio hardware represented by one or more
+ PaDevices. Depending on the underlying Host API, it may be possible
+ to open multiple streams using the same device, however this behavior
+ is implementation defined. Portable applications should assume that
+ a PaDevice may be simultaneously used by at most one PaStream.
+
+ Pointers to PaStream objects are passed between PortAudio functions that
+ operate on streams.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
+ Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
+ Pa_GetStreamTime, Pa_GetStreamCpuLoad
+
+*}
+type
+ PPaStream = Pointer;
+
+{** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
+ or Pa_OpenDefaultStream() to indicate that the stream callback will
+ accept buffers of any size.
+*}
+const paFramesPerBufferUnspecified = (0);
+
+
+{** Flags used to control the behavior of a stream. They are passed as
+ parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
+ ORed together.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+ @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
+ paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
+*}
+type TPaStreamFlags = culong;
+
+{** @see PaStreamFlags *}
+const paNoFlag = TPaStreamFlags(0);
+
+{** Disable default clipping of out of range samples.
+ @see PaStreamFlags
+*}
+const paClipOff = TPaStreamFlags($00000001);
+
+{** Disable default dithering.
+ @see PaStreamFlags
+*}
+const paDitherOff = TPaStreamFlags($00000002);
+
+{** Flag requests that where possible a full duplex stream will not discard
+ overflowed input samples without calling the stream callback. This flag is
+ only valid for full duplex callback streams and only when used in combination
+ with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
+ this flag incorrectly results in a paInvalidFlag error being returned from
+ Pa_OpenStream and Pa_OpenDefaultStream.
+
+ @see PaStreamFlags, paFramesPerBufferUnspecified
+*}
+const paNeverDropInput = TPaStreamFlags($00000004);
+
+{** Call the stream callback to fill initial output buffers, rather than the
+ default behavior of priming the buffers with zeros (silence). This flag has
+ no effect for input-only and blocking read/write streams.
+
+ @see PaStreamFlags
+*}
+const paPrimeOutputBuffersUsingStreamCallback = TPaStreamFlags($00000008);
+
+{** A mask specifying the platform specific bits.
+ @see PaStreamFlags
+*}
+const paPlatformSpecificFlags = TPaStreamFlags($FFFF0000);
+
+{**
+ Timing information for the buffers passed to the stream callback.
+*}
+type
+ PPaStreamCallbackTimeInfo = ^TPaStreamCallbackTimeInfo;
+ TPaStreamCallbackTimeInfo = record
+ inputBufferAdcTime: TPaTime;
+ currentTime: TPaTime;
+ outputBufferDacTime: TPaTime;
+ end;
+
+
+{**
+ Flag bit constants for the statusFlags to PaStreamCallback.
+
+ @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
+ paPrimingOutput
+*}
+type TPaStreamCallbackFlags = culong;
+
+{** In a stream opened with paFramesPerBufferUnspecified, indicates that
+ input data is all silence (zeros) because no real data is available. In a
+ stream opened without paFramesPerBufferUnspecified, it indicates that one or
+ more zero samples have been inserted into the input buffer to compensate
+ for an input underflow.
+ @see PaStreamCallbackFlags
+*}
+const paInputUnderflow = TPaStreamCallbackFlags($00000001);
+
+{** In a stream opened with paFramesPerBufferUnspecified, indicates that data
+ prior to the first sample of the input buffer was discarded due to an
+ overflow, possibly because the stream callback is using too much CPU time.
+ Otherwise indicates that data prior to one or more samples in the
+ input buffer was discarded.
+ @see PaStreamCallbackFlags
+*}
+const paInputOverflow = TPaStreamCallbackFlags($00000002);
+
+{** Indicates that output data (or a gap) was inserted, possibly because the
+ stream callback is using too much CPU time.
+ @see PaStreamCallbackFlags
+*}
+const paOutputUnderflow = TPaStreamCallbackFlags($00000004);
+
+{** Indicates that output data will be discarded because no room is available.
+ @see PaStreamCallbackFlags
+*}
+const paOutputOverflow = TPaStreamCallbackFlags($00000008);
+
+{** Some of all of the output data will be used to prime the stream, input
+ data may be zero.
+ @see PaStreamCallbackFlags
+*}
+const paPrimingOutput = TPaStreamCallbackFlags($00000010);
+
+{**
+ Allowable return values for the PaStreamCallback.
+ @see PaStreamCallback
+*}
+type TPaStreamCallbackResult = {enum}cint; const
+{enum_begin PaStreamCallbackResult}
+ paContinue=0;
+ paComplete=1;
+ paAbort=2;
+{enum_end PaStreamCallbackResult}
+
+{**
+ Functions of type PaStreamCallback are implemented by PortAudio clients.
+ They consume, process or generate audio in response to requests from an
+ active PortAudio stream.
+
+ @param input and @param output are arrays of interleaved samples,
+ the format, packing and number of channels used by the buffers are
+ determined by parameters to Pa_OpenStream().
+
+ @param frameCount The number of sample frames to be processed by
+ the stream callback.
+
+ @param timeInfo The time in seconds when the first sample of the input
+ buffer was received at the audio input, the time in seconds when the first
+ sample of the output buffer will begin being played at the audio output, and
+ the time in seconds when the stream callback was called.
+ See also Pa_GetStreamTime()
+
+ @param statusFlags Flags indicating whether input and/or output buffers
+ have been inserted or will be dropped to overcome underflow or overflow
+ conditions.
+
+ @param userData The value of a user supplied pointer passed to
+ Pa_OpenStream() intended for storing synthesis data etc.
+
+ @return
+ The stream callback should return one of the values in the
+ PaStreamCallbackResult enumeration. To ensure that the callback continues
+ to be called, it should return paContinue (0). Either paComplete or paAbort
+ can be returned to finish stream processing, after either of these values is
+ returned the callback will not be called again. If paAbort is returned the
+ stream will finish as soon as possible. If paComplete is returned, the stream
+ will continue until all buffers generated by the callback have been played.
+ This may be useful in applications such as soundfile players where a specific
+ duration of output is required. However, it is not necessary to utilise this
+ mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
+ be used to stop the stream. The callback must always fill the entire output
+ buffer irrespective of its return value.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+
+ @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
+ PortAudio API functions from within the stream callback.
+*}
+type
+ PPaStreamCallback = ^TPaStreamCallback;
+ TPaStreamCallback = function(
+ input: Pointer; output: Pointer;
+ frameCount: culong;
+ timeInfo: PPaStreamCallbackTimeInfo;
+ statusFlags: TPaStreamCallbackFlags;
+ userData: Pointer ): cint; cdecl;
+
+
+{** Opens a stream for either input, output or both.
+
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+
+ @param inputParameters A structure that describes the input parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ inputParameters must be NULL for output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ outputParameters must be NULL for input-only streams.
+
+ @param sampleRate The desired sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+
+ @param framesPerBuffer The number of frames passed to the stream callback
+ function, or the preferred block granularity for a blocking read/write stream.
+ The special value paFramesPerBufferUnspecified (0) may be used to request that
+ the stream callback will recieve an optimal (and possibly varying) number of
+ frames based on host requirements and the requested latency settings.
+ Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
+ stream may introduce an additional layer of buffering which could introduce
+ additional latency. PortAudio guarantees that the additional latency
+ will be kept to the theoretical minimum however, it is strongly recommended
+ that a non-zero framesPerBuffer value only be used when your algorithm
+ requires a fixed number of frames per stream callback.
+
+ @param streamFlags Flags which modify the behaviour of the streaming process.
+ This parameter may contain a combination of flags ORed together. Some flags may
+ only be relevant to certain buffer formats.
+
+ @param streamCallback A pointer to a client supplied function that is responsible
+ for processing and filling input and output buffers. If this parameter is NULL
+ the stream will be opened in 'blocking read/write' mode. In blocking mode,
+ the client can receive sample data using Pa_ReadStream and write sample data
+ using Pa_WriteStream, the number of samples that may be read or written
+ without blocking is returned by Pa_GetStreamReadAvailable and
+ Pa_GetStreamWriteAvailable respectively.
+
+ @param userData A client supplied pointer which is passed to the stream callback
+ function. It could for example, contain a pointer to instance data necessary
+ for processing the audio buffers. This parameter is ignored if streamCallback
+ is NULL.
+
+ @return
+ Upon success Pa_OpenStream() returns paNoError and places a pointer to a
+ valid PaStream in the stream argument. The stream is inactive (stopped).
+ If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
+ PaError for possible error codes) and the value of stream is invalid.
+
+ @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
+ Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
+*}
+function Pa_OpenStream( var stream: PPaStream;
+ inputParameters: PPaStreamParameters;
+ outputParameters: PPaStreamParameters;
+ sampleRate: cdouble;
+ framesPerBuffer: culong;
+ streamFlags: TPaStreamFlags;
+ streamCallback: PPaStreamCallback;
+ userData: Pointer ): TPaError; cdecl; external LibName;
+
+
+{** A simplified version of Pa_OpenStream() that opens the default input
+ and/or output devices.
+
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+
+ @param numInputChannels The number of channels of sound that will be supplied
+ to the stream callback or returned by Pa_ReadStream. It can range from 1 to
+ the value of maxInputChannels in the PaDeviceInfo record for the default input
+ device. If 0 the stream is opened as an output-only stream.
+
+ @param numOutputChannels The number of channels of sound to be delivered to the
+ stream callback or passed to Pa_WriteStream. It can range from 1 to the value
+ of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
+ If 0 the stream is opened as an output-only stream.
+
+ @param sampleFormat The sample format of both the input and output buffers
+ provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
+ sampleFormat may be any of the formats described by the PaSampleFormat
+ enumeration.
+
+ @param sampleRate Same as Pa_OpenStream parameter of the same name.
+ @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
+ @param streamCallback Same as Pa_OpenStream parameter of the same name.
+ @param userData Same as Pa_OpenStream parameter of the same name.
+
+ @return As for Pa_OpenStream
+
+ @see Pa_OpenStream, PaStreamCallback
+*}
+function Pa_OpenDefaultStream( var stream: PPaStream;
+ numInputChannels: cint;
+ numOutputChannels: cint;
+ sampleFormat: TPaSampleFormat;
+ sampleRate: cdouble;
+ framesPerBuffer: culong;
+ streamCallback: PPaStreamCallback;
+ userData: Pointer ): TPaError; cdecl; external LibName;
+
+
+{** Closes an audio stream. If the audio stream is active it
+ discards any pending buffers as if Pa_AbortStream() had been called.
+*}
+function Pa_CloseStream( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+{** Functions of type PaStreamFinishedCallback are implemented by PortAudio
+ clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
+ function. Once registered they are called when the stream becomes inactive
+ (ie once a call to Pa_StopStream() will not block).
+ A stream will become inactive after the stream callback returns non-zero,
+ or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
+ output, if the stream callback returns paComplete, or Pa_StopStream is called,
+ the stream finished callback will not be called until all generated sample data
+ has been played.
+
+ @param userData The userData parameter supplied to Pa_OpenStream()
+
+ @see Pa_SetStreamFinishedCallback
+*}
+type
+ PPaStreamFinishedCallback = ^TPaStreamFinishedCallback;
+ TPaStreamFinishedCallback = procedure( userData: Pointer ); cdecl;
+
+
+{** Register a stream finished callback function which will be called when the
+ stream becomes inactive. See the description of PaStreamFinishedCallback for
+ further details about when the callback will be called.
+
+ @param stream a pointer to a PaStream that is in the stopped state - if the
+ stream is not stopped, the stream's finished callback will remain unchanged
+ and an error code will be returned.
+
+ @param streamFinishedCallback a pointer to a function with the same signature
+ as PaStreamFinishedCallback, that will be called when the stream becomes
+ inactive. Passing NULL for this parameter will un-register a previously
+ registered stream finished callback function.
+
+ @return on success returns paNoError, otherwise an error code indicating the cause
+ of the error.
+
+ @see PaStreamFinishedCallback
+*}
+function Pa_SetStreamFinishedCallback( stream: PPaStream;
+ streamFinishedCallback: PPaStreamFinishedCallback ): TPaError; cdecl; external LibName;
+
+
+{** Commences audio processing.
+*}
+function Pa_StartStream( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+{** Terminates audio processing. It waits until all pending
+ audio buffers have been played before it returns.
+*}
+function Pa_StopStream( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+{** Terminates audio processing immediately without waiting for pending
+ buffers to complete.
+*}
+function Pa_AbortStream( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+{** Determine whether the stream is stopped.
+ A stream is considered to be stopped prior to a successful call to
+ Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
+ If a stream callback returns a value other than paContinue the stream is NOT
+ considered to be stopped.
+
+ @return Returns one (1) when the stream is stopped, zero (0) when
+ the stream is running or, a PaErrorCode (which are always negative) if
+ PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
+*}
+function Pa_IsStreamStopped( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+{** Determine whether the stream is active.
+ A stream is active after a successful call to Pa_StartStream(), until it
+ becomes inactive either as a result of a call to Pa_StopStream() or
+ Pa_AbortStream(), or as a result of a return value other than paContinue from
+ the stream callback. In the latter case, the stream is considered inactive
+ after the last buffer has finished playing.
+
+ @return Returns one (1) when the stream is active (ie playing or recording
+ audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
+ if PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
+*}
+function Pa_IsStreamActive( stream: PPaStream ): TPaError; cdecl; external LibName;
+
+
+
+{** A structure containing unchanging information about an open stream.
+ @see Pa_GetStreamInfo
+*}
+type
+ PPaStreamInfo = ^TPaStreamInfo;
+ TPaStreamInfo = record
+ {** this is struct version 1 *}
+ structVersion: cint;
+
+ {** The input latency of the stream in seconds. This value provides the most
+ accurate estimate of input latency available to the implementation. It may
+ differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+ The value of this field will be zero (0.) for output-only streams.
+ @see PaTime
+ *}
+ inputLatency: TPaTime;
+
+ {** The output latency of the stream in seconds. This value provides the most
+ accurate estimate of output latency available to the implementation. It may
+ differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+ The value of this field will be zero (0.) for input-only streams.
+ @see PaTime
+ *}
+ outputLatency: TPaTime;
+
+ {** The sample rate of the stream in Hertz (samples per second). In cases
+ where the hardware sample rate is inaccurate and PortAudio is aware of it,
+ the value of this field may be different from the sampleRate parameter
+ passed to Pa_OpenStream(). If information about the actual hardware sample
+ rate is not available, this field will have the same value as the sampleRate
+ parameter passed to Pa_OpenStream().
+ *}
+ sampleRate: cdouble;
+ end;
+
+
+{** Retrieve a pointer to a PaStreamInfo structure containing information
+ about the specified stream.
+ @return A pointer to an immutable PaStreamInfo structure. If the stream
+ parameter invalid, or an error is encountered, the function returns NULL.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid until the specified stream is closed.
+
+ @see PaStreamInfo
+*}
+function Pa_GetStreamInfo( stream: PPaStream ): PPaStreamInfo; cdecl; external LibName;
+
+
+{** Determine the current time for the stream according to the same clock used
+ to generate buffer timestamps. This time may be used for syncronising other
+ events to the audio stream, for example synchronizing audio to MIDI.
+
+ @return The stream's current time in seconds, or 0 if an error occurred.
+
+ @see PaTime, PaStreamCallback
+*}
+function Pa_GetStreamTime( stream: PPaStream ): TPaTime; cdecl; external LibName;
+
+
+{** Retrieve CPU usage information for the specified stream.
+ The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
+ audio processing routines including, but not limited to the client supplied
+ stream callback. This function does not work with blocking read/write streams.
+
+ This function may be called from the stream callback function or the
+ application.
+
+ @return
+ A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
+ that the stream callback is consuming the maximum number of CPU cycles possible
+ to maintain real-time operation. A value of 0.5 would imply that PortAudio and
+ the stream callback was consuming roughly 50% of the available CPU time. The
+ return value may exceed 1.0. A value of 0.0 will always be returned for a
+ blocking read/write stream, or if an error occurrs.
+*}
+function Pa_GetStreamCpuLoad( stream: PPaStream ): cdouble; cdecl; external LibName;
+
+
+{** Read samples from an input stream. The function doesn't return until
+ the entire buffer has been filled - this may involve waiting for the operating
+ system to supply the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the inputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ inputParameters->numChannels. If non-interleaved samples were requested,
+ buffer is a pointer to the first element of an array of non-interleaved
+ buffer pointers, one for each channel.
+
+ @param frames The number of frames to be read into buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or PaInputOverflowed if input
+ data was discarded by PortAudio after the previous call and before this call.
+*}
+function Pa_ReadStream( stream: PPaStream;
+ buffer: Pointer;
+ frames: culong ): TPaError; cdecl; external LibName;
+
+
+{** Write samples to an output stream. This function doesn't return until the
+ entire buffer has been consumed - this may involve waiting for the operating
+ system to consume the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the outputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ outputParameters->numChannels. If non-interleaved samples were requested,
+ buffer is a pointer to the first element of an array of non-interleaved
+ buffer pointers, one for each channel.
+
+ @param frames The number of frames to be written from buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or paOutputUnderflowed if
+ additional output data was inserted after the previous call and before this
+ call.
+*}
+function Pa_WriteStream( stream: PPaStream;
+ buffer: Pointer;
+ frames: culong ): TPaError; cdecl; external LibName;
+
+
+{** Retrieve the number of frames that can be read from the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be read from the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*}
+function Pa_GetStreamReadAvailable( stream: PPaStream ): cslong; cdecl; external LibName;
+
+
+{** Retrieve the number of frames that can be written to the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be written to the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*}
+function Pa_GetStreamWriteAvailable( stream: PPaStream ): cslong; cdecl; external LibName;
+
+
+{** Retrieve the host type handling an open stream.
+
+ @return Returns a non-negative value representing the host API type
+ handling an open stream or, a PaErrorCode (which are always negative)
+ if PortAudio is not initialized or an error is encountered.
+*}
+function Pa_GetStreamHostApiType( stream: PPaStream ): TPaHostApiTypeId; cdecl; external LibName;
+
+
+{* Miscellaneous utilities *}
+
+
+{** Retrieve the size of a given sample format in bytes.
+
+ @return The size in bytes of a single sample in the specified format,
+ or paSampleFormatNotSupported if the format is not supported.
+*}
+function Pa_GetSampleSize( format: TPaSampleFormat ): TPaError; cdecl; external LibName;
+
+
+{** Put the caller to sleep for at least 'msec' milliseconds. This function is
+ provided only as a convenience for authors of portable code (such as the tests
+ and examples in the PortAudio distribution.)
+
+ The function may sleep longer than requested so don't rely on this for accurate
+ musical timing.
+*}
+procedure Pa_Sleep( msec: clong ); cdecl; external LibName;
+
+implementation
+
+end.
diff --git a/src/lib/portmixer/delphi/portmixer.pas b/src/lib/portmixer/delphi/portmixer.pas
new file mode 100644
index 00000000..d657cf85
--- /dev/null
+++ b/src/lib/portmixer/delphi/portmixer.pas
@@ -0,0 +1,151 @@
+{*
+ * PortMixer
+ * PortMixer API Header File
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *}
+unit portmixer;
+
+{$IFDEF FPC}
+ {$PACKRECORDS C} (* GCC/Visual C/C++ compatible record packing *)
+ {$MODE DELPHI }
+{$ENDIF}
+
+interface
+
+uses
+ ctypes,
+ portaudio;
+
+const
+{$IFDEF MSWINDOWS}
+ LibName = 'portmixer.dll';
+{$ENDIF}
+{$IFDEF LINUX}
+ LibName = 'libportmixer.so';
+{$ENDIF}
+{$IFDEF DARWIN}
+// LibName = 'libportmixer.dylib';
+// {$LINKLIB libportaudio}
+{$ENDIF}
+
+type
+ PPxMixer = Pointer;
+ TPxVolume = cfloat; {* 0.0 (min) --> 1.0 (max) *}
+ TPxBalance = cfloat; {* -1.0 (left) --> 1.0 (right) *}
+
+{*
+ Px_OpenMixer() returns a mixer which will work with the given PortAudio
+ audio device. Pass 0 as the index for the first (default) mixer.
+*}
+
+function Px_OpenMixer( pa_stream: Pointer; i: cint ): PPxMixer; cdecl; external LibName;
+
+{*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*}
+
+procedure Px_CloseMixer( mixer: PPxMixer ); cdecl; external LibName;
+
+{*
+ Px_GetNumMixers returns the number of mixers which could be
+ used with the given PortAudio device. On most systems, there
+ will be only one mixer for each device; however there may be
+ multiple mixers for each device, or possibly multiple mixers
+ which are independent of any particular PortAudio device.
+*}
+
+function Px_GetNumMixers( mixer: PPxMixer ): cint; cdecl; external LibName;
+function Px_GetMixerName( mixer: PPxMixer; i: cint ): PChar; cdecl; external LibName;
+
+{*
+ Master (output) volume
+*}
+
+function Px_GetMasterVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
+procedure Px_SetMasterVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
+
+{*
+ Main output volume
+*}
+
+function Px_GetPCMOutputVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
+procedure Px_SetPCMOutputVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
+function Px_SupportsPCMOutputVolume( mixer: PPxMixer ): cint; cdecl; external LibName;
+
+{*
+ All output volumes
+*}
+
+function Px_GetNumOutputVolumes( mixer: PPxMixer ): cint; cdecl; external LibName;
+function Px_GetOutputVolumeName( mixer: PPxMixer; i: cint ): PChar; cdecl; external LibName;
+function Px_GetOutputVolume( mixer: PPxMixer; i: cint ): TPxVolume; cdecl; external LibName;
+procedure Px_SetOutputVolume( mixer: PPxMixer; i: cint; volume: TPxVolume ); cdecl; external LibName;
+
+{*
+ Input source
+*}
+
+function Px_GetNumInputSources( mixer: PPxMixer ): cint; cdecl; external LibName;
+function Px_GetInputSourceName( mixer: PPxMixer; i: cint): PChar; cdecl; external LibName;
+function Px_GetCurrentInputSource( mixer: PPxMixer ): cint; cdecl; external LibName; {* may return -1 == none *}
+procedure Px_SetCurrentInputSource( mixer: PPxMixer; i: cint ); cdecl; external LibName;
+
+{*
+ Input volume
+*}
+
+function Px_GetInputVolume( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
+procedure Px_SetInputVolume( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
+
+{*
+ Balance
+*}
+
+function Px_SupportsOutputBalance( mixer: PPxMixer ): cint; cdecl; external LibName;
+function Px_GetOutputBalance( mixer: PPxMixer ): TPxBalance; cdecl; external LibName;
+procedure Px_SetOutputBalance( mixer: PPxMixer; balance: TPxBalance ); cdecl; external LibName;
+
+{*
+ Playthrough
+*}
+
+function Px_SupportsPlaythrough( mixer: PPxMixer ): cint; cdecl; external LibName;
+function Px_GetPlaythrough( mixer: PPxMixer ): TPxVolume; cdecl; external LibName;
+procedure Px_SetPlaythrough( mixer: PPxMixer; volume: TPxVolume ); cdecl; external LibName;
+
+implementation
+
+end.
diff --git a/src/lib/projectM/cwrapper/Makefile.in b/src/lib/projectM/cwrapper/Makefile.in
new file mode 100644
index 00000000..d2be8613
--- /dev/null
+++ b/src/lib/projectM/cwrapper/Makefile.in
@@ -0,0 +1,30 @@
+OBJECTS = projectM-cwrapper.o
+LIBRARY = libprojectM-cwrapper.a
+
+CXX = @CXX@
+CXXFLAGS += @CXXFLAGS@
+INCLUDES = -I@libprojectM_INCLUDEDIR@/libprojectM
+DEFINES = -DPROJECTM_VERSION_INT=@libprojectM_VERSION_INT@
+RANLIB = @RANLIB@
+
+.PHONY: all clean distclean strip
+
+all : $(LIBRARY)
+
+$(LIBRARY): $(OBJECTS)
+ ar ruv $(LIBRARY) $(OBJECTS)
+ $(RANLIB) $(LIBRARY)
+
+%.o : %.cpp
+ $(CXX) $(CXXFLAGS) $(DEFINES) $(INCLUDES) -c $(<) -o $@
+
+clean :
+ rm -f $(LIBRARY)
+ rm -f $(OBJECTS)
+
+distclean: clean
+ rm -rf Makefile
+
+strip :
+ strip $(LIBRARY)
+ $(RANLIB) $(LIBRARY)
diff --git a/src/lib/projectM/cwrapper/projectM-cwrapper.cpp b/src/lib/projectM/cwrapper/projectM-cwrapper.cpp
new file mode 100644
index 00000000..ebf43554
--- /dev/null
+++ b/src/lib/projectM/cwrapper/projectM-cwrapper.cpp
@@ -0,0 +1,104 @@
+#include "projectM-cwrapper.h"
+
+#define PM_CLASS(pm) ((projectM*)pm)
+
+#if (PROJECTM_VERSION_INT > 1000000)
+#define PM_PCM(pm) (PM_CLASS(pm)->pcm())
+#else
+#define PM_PCM(pm) (PM_CLASS(pm)->pcm)
+#endif
+
+projectM_ptr projectM_create1(char* config_file)
+{
+ return projectM_ptr(new projectM(config_file));
+}
+
+#if (PROJECTM_VERSION_INT < 1000000)
+projectM_ptr projectM_create2(int gx, int gy, int fps, int texsize,
+ int width, int height, char* preset_url,
+ char* title_fonturl, char* title_menuurl)
+{
+ return projectM_ptr(new projectM(gx, gy, fps, texsize, width, height,
+ preset_url, title_fonturl, title_menuurl));}
+#endif
+
+void projectM_resetGL(projectM_ptr pm, int width, int height)
+{
+ PM_CLASS(pm)->projectM_resetGL(width, height);
+}
+
+void projectM_setTitle(projectM_ptr pm, char* title)
+{
+ PM_CLASS(pm)->projectM_setTitle(title);
+}
+
+void projectM_renderFrame(projectM_ptr pm)
+{
+ PM_CLASS(pm)->renderFrame();
+}
+
+unsigned projectM_initRenderToTexture(projectM_ptr pm)
+{
+ return PM_CLASS(pm)->initRenderToTexture();
+}
+
+void projectM_key_handler(projectM_ptr pm, projectMEvent event,
+ projectMKeycode keycode, projectMModifier modifier)
+{
+ PM_CLASS(pm)->key_handler(event, keycode, modifier);
+}
+
+void projectM_free(projectM_ptr pm)
+{
+ delete PM_CLASS(pm);
+}
+
+void PCM_addPCMfloat(projectM_ptr pm, float *PCMdata, int samples)
+{
+ PM_PCM(pm)->addPCMfloat(PCMdata, samples);
+}
+
+void PCM_addPCM16(projectM_ptr pm, short pcm_data[2][512])
+{
+ PM_PCM(pm)->addPCM16(pcm_data);
+}
+
+void PCM_addPCM16Data(projectM_ptr pm, const short* pcm_data, short samples)
+{
+ PM_PCM(pm)->addPCM16Data(pcm_data, samples);
+}
+
+void PCM_addPCM8(projectM_ptr pm, unsigned char pcm_data[2][1024])
+{
+ PM_PCM(pm)->addPCM8(pcm_data);
+}
+
+void PCM_addPCM8_512(projectM_ptr pm, const unsigned char pcm_data[2][512])
+{
+ PM_PCM(pm)->addPCM8_512(pcm_data);
+}
+
+#define COPY_FIELD(c_ptr, s, fld) (c_ptr->fld = s.fld)
+
+#if (PROJECTM_VERSION_INT > 1000000)
+void projectM_settings(projectM_ptr pm, Settings* settings)
+{
+ const projectM::Settings& pmSettings = PM_CLASS(pm)->settings();
+
+ COPY_FIELD(settings, pmSettings, meshX);
+ COPY_FIELD(settings, pmSettings, meshY);
+ COPY_FIELD(settings, pmSettings, fps);
+ COPY_FIELD(settings, pmSettings, textureSize);
+ COPY_FIELD(settings, pmSettings, windowWidth);
+ COPY_FIELD(settings, pmSettings, windowHeight);
+ settings->presetURL = pmSettings.presetURL.c_str();
+ settings->titleFontURL = pmSettings.titleFontURL.c_str();
+ settings->menuFontURL = pmSettings.menuFontURL.c_str();
+ COPY_FIELD(settings, pmSettings, smoothPresetDuration);
+ COPY_FIELD(settings, pmSettings, presetDuration);
+ COPY_FIELD(settings, pmSettings, beatSensitivity);
+ COPY_FIELD(settings, pmSettings, aspectCorrection);
+ COPY_FIELD(settings, pmSettings, easterEgg);
+ COPY_FIELD(settings, pmSettings, shuffleEnabled);
+}
+#endif
diff --git a/src/lib/projectM/cwrapper/projectM-cwrapper.h b/src/lib/projectM/cwrapper/projectM-cwrapper.h
new file mode 100644
index 00000000..43f36ef4
--- /dev/null
+++ b/src/lib/projectM/cwrapper/projectM-cwrapper.h
@@ -0,0 +1,67 @@
+#ifndef __PROJECTM_CWRAPPER_H__
+#define __PROJECTM_CWRAPPER_H__
+
+#include "projectM.hpp"
+
+// PROJECTM_VERSION define is not very helpful, lets create our own
+#define PROJECTM_VERSION_1_00_00 1000000 // 1.00.00 = 1.0 or 1.01 (same version number for 1.0 and 1.01)
+#define PROJECTM_VERSION_1_10_00 1010000 // 1.10.00 = 1.1 (bigger than 1.2 due to strange versioning)
+#define PROJECTM_VERSION_1_02_00 1002000 // 1.02.00 = 1.2
+
+// version of projectM to wrap (see PROJECTM_VERSION)
+#ifndef PROJECTM_VERSION_INT
+#define PROJECTM_VERSION_INT PROJECTM_VERSION_1_02_00
+#endif
+
+extern "C" {
+
+ #if (PROJECTM_VERSION_INT > 1000000)
+ struct Settings {
+ int meshX;
+ int meshY;
+ int fps;
+ int textureSize;
+ int windowWidth;
+ int windowHeight;
+ const char* presetURL;
+ const char* titleFontURL;
+ const char* menuFontURL;
+ int smoothPresetDuration;
+ int presetDuration;
+ float beatSensitivity;
+ char aspectCorrection;
+ float easterEgg;
+ char shuffleEnabled;
+ };
+ #endif
+
+ typedef void* projectM_ptr;
+
+ DLLEXPORT projectM_ptr projectM_create1(char* config_file);
+ #if (PROJECTM_VERSION_INT < 1000000)
+ DLLEXPORT projectM_ptr projectM_create2(int gx, int gy, int fps, int texsize,
+ int width, int height, char* preset_url,
+ char* title_fonturl, char* title_menuurl);
+ #endif
+
+ DLLEXPORT void projectM_resetGL(projectM_ptr pm, int width, int height);
+ DLLEXPORT void projectM_setTitle(projectM_ptr pm, char* title);
+ DLLEXPORT void projectM_renderFrame(projectM_ptr pm);
+ DLLEXPORT unsigned projectM_initRenderToTexture(projectM_ptr pm);
+ DLLEXPORT void projectM_key_handler(projectM_ptr pm, projectMEvent event,
+ projectMKeycode keycode, projectMModifier modifier);
+
+ DLLEXPORT void projectM_free(projectM_ptr pm);
+
+ DLLEXPORT void PCM_addPCMfloat(projectM_ptr pm, float *PCMdata, int samples);
+ DLLEXPORT void PCM_addPCM16(projectM_ptr pm, short [2][512]);
+ DLLEXPORT void PCM_addPCM16Data(projectM_ptr pm, const short* pcm_data, short samples);
+ DLLEXPORT void PCM_addPCM8(projectM_ptr pm, unsigned char [2][1024]);
+ DLLEXPORT void PCM_addPCM8_512(projectM_ptr pm, const unsigned char [2][512]);
+
+ #if (PROJECTM_VERSION_INT > 1000000)
+ DLLEXPORT void projectM_settings(projectM_ptr pm, Settings* settings);
+ #endif
+}
+
+#endif
diff --git a/src/lib/projectM/cwrapper/projectM-cwrapper.sln b/src/lib/projectM/cwrapper/projectM-cwrapper.sln
new file mode 100644
index 00000000..e05f79a3
--- /dev/null
+++ b/src/lib/projectM/cwrapper/projectM-cwrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "projectM-cwrapper", "projectM-cwrapper.vcproj", "{8E653284-12F3-4A90-9D0D-4195557051F7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8E653284-12F3-4A90-9D0D-4195557051F7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8E653284-12F3-4A90-9D0D-4195557051F7}.Debug|Win32.Build.0 = Debug|Win32
+ {8E653284-12F3-4A90-9D0D-4195557051F7}.Release|Win32.ActiveCfg = Release|Win32
+ {8E653284-12F3-4A90-9D0D-4195557051F7}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/lib/projectM/cwrapper/projectM-cwrapper.vcproj b/src/lib/projectM/cwrapper/projectM-cwrapper.vcproj
new file mode 100644
index 00000000..c0902099
--- /dev/null
+++ b/src/lib/projectM/cwrapper/projectM-cwrapper.vcproj
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/projectM/projectM-0_9.inc b/src/lib/projectM/projectM-0_9.inc
new file mode 100644
index 00000000..a3908c77
--- /dev/null
+++ b/src/lib/projectM/projectM-0_9.inc
@@ -0,0 +1,427 @@
+{$IFDEF Unix}
+uses
+ baseunix;
+{$ENDIF}
+
+const
+{$IFDEF MSWINDOWS}
+ libprojectM = 'libprojectM.dll';
+{$ELSE}
+ libprojectM = 'libprojectM.so';
+{$ENDIF}
+
+{**************** INTERNAL SECTION ****************}
+
+
+type
+ PPCfloat = ^PCfloat;
+
+type
+ _TContextType = cint;
+const
+ AGL_CONTEXT = 0;
+ CGL_CONTEXT = 1;
+ NSGL_CONTEXT = 2;
+ GLX_CONTEXT = 3;
+ WGL_CONTEXT = 4;
+
+type
+ _PRenderTarget = ^_TRenderTarget;
+ _TRenderTarget = record
+ { Texture size }
+ texsize: cint;
+
+ { Application context }
+ origContextType: _TContextType;
+
+ usePbuffers: cint;
+
+ {$ifdef LINUX}
+ lock_func: procedure(); cdecl;
+ unlock_func: procedure(); cdecl;
+ {$endif}
+
+ { Opaque pbuffer context and pbuffer }
+ {$ifdef DARWIN}
+ origContext: Pointer;
+ pbufferContext: Pointer;
+ pbuffer: Pointer;
+ {$endif}
+
+ { Render target texture ID for non-pbuffer systems }
+ textureID: array[0..2] of GLuint;
+ end;
+
+ _PProjectM = ^_TProjectM;
+ _TProjectM = record
+ presetURL: PChar;
+ presetName: PChar;
+ fontURL: PChar;
+
+ hasInit: cint;
+
+ noSwitch: cint;
+ pcmframes: cint;
+ freqframes: cint;
+ totalframes: cint;
+
+ showfps: cint;
+ showtitle: cint;
+ showpreset: cint;
+ showhelp: cint;
+ showstats: cint;
+
+ studio: cint;
+
+ fbuffer: PGLubyte;
+
+ {$IFNDEF MSWINDOWS}
+ { The first ticks value of the application }
+ startTime: timeval;
+ {$ELSE}
+ startTime: clong;
+ {$ENDIF}
+ Time: cfloat;
+
+ { Render target texture ID }
+ renderTarget: _PRenderTarget;
+
+ disp: array[0..79] of Char;
+
+ wave_o: cfloat;
+
+ //int texsize=1024; //size of texture to do actual graphics
+ fvw: cint; //fullscreen dimensions
+ fvh: cint;
+ wvw: cint; //windowed dimensions
+ wvh: cint;
+ vw: cint; //runtime dimensions
+ vh: cint;
+ fullscreen: cint;
+
+ maxsamples: cint; //size of PCM buffer
+ numsamples: cint; //size of new PCM info
+ pcmdataL: PCfloat; //holder for most recent pcm data
+ pcmdataR: PCfloat; //holder for most recent pcm data
+
+ avgtime: cint; //# frames per preset
+
+ title: PChar;
+ drawtitle: cint;
+
+ correction: cint;
+
+ vol: cfloat;
+
+ //per pixel equation variables
+ gridx: PPCfloat; //grid containing interpolated mesh
+ gridy: PPCfloat;
+ origtheta: PPCfloat; //grid containing interpolated mesh reference values
+ origrad: PPCfloat;
+ origx: PPCfloat; //original mesh
+ origy: PPCfloat;
+ origx2: PPCfloat; //original mesh
+ origy2: PPCfloat;
+
+ { Timing information }
+ mspf: cint;
+ timed: cint;
+ timestart: cint;
+ nohard: cint;
+ count: cint;
+ realfps,
+ fpsstart: cfloat;
+
+ { PCM data }
+ vdataL: array[0..511] of cfloat; //holders for FFT data (spectrum)
+ vdataR: array[0..511] of cfloat;
+
+ { Various toggles }
+ doPerPixelEffects: cint;
+ doIterative: cint;
+
+ { ENGINE VARIABLES }
+ { From engine_vars.h }
+ preset_name: array[0..255] of Char;
+
+ { PER FRAME CONSTANTS BEGIN }
+ zoom: cfloat;
+ zoomexp: cfloat;
+ rot: cfloat;
+ warp: cfloat;
+
+ sx: cfloat;
+ sy: cfloat;
+ dx: cfloat;
+ dy: cfloat;
+ cx: cfloat;
+ cy: cfloat;
+
+ gy: cint;
+ gx: cint;
+
+ decay: cfloat;
+
+ wave_r: cfloat;
+ wave_g: cfloat;
+ wave_b: cfloat;
+ wave_x: cfloat;
+ wave_y: cfloat;
+ wave_mystery: cfloat;
+
+ ob_size: cfloat;
+ ob_r: cfloat;
+ ob_g: cfloat;
+ ob_b: cfloat;
+ ob_a: cfloat;
+
+ ib_size: cfloat;
+ ib_r: cfloat;
+ ib_g: cfloat;
+ ib_b: cfloat;
+ ib_a: cfloat;
+
+ meshx: cint;
+ meshy: cint;
+
+ mv_a: cfloat;
+ mv_r: cfloat;
+ mv_g: cfloat;
+ mv_b: cfloat;
+ mv_l: cfloat;
+ mv_x: cfloat;
+ mv_y: cfloat;
+ mv_dy: cfloat;
+ mv_dx: cfloat;
+
+ treb: cfloat;
+ mid: cfloat;
+ bass: cfloat;
+ bass_old: cfloat;
+ beat_sensitivity: cfloat;
+ treb_att: cfloat;
+ mid_att: cfloat;
+ bass_att: cfloat;
+ progress: cfloat;
+ frame: cint;
+
+ { PER_FRAME CONSTANTS END }
+
+ { PER_PIXEL CONSTANTS BEGIN }
+
+ x_per_pixel: cfloat;
+ y_per_pixel: cfloat;
+ rad_per_pixel: cfloat;
+ ang_per_pixel: cfloat;
+
+ { PER_PIXEL CONSTANT END }
+
+
+ fRating: cfloat;
+ fGammaAdj: cfloat;
+ fVideoEchoZoom: cfloat;
+ fVideoEchoAlpha: cfloat;
+
+ nVideoEchoOrientation: cint;
+ nWaveMode: cint;
+ bAdditiveWaves: cint;
+ bWaveDots: cint;
+ bWaveThick: cint;
+ bModWaveAlphaByVolume: cint;
+ bMaximizeWaveColor: cint;
+ bTexWrap: cint;
+ bDarkenCenter: cint;
+ bRedBlueStereo: cint;
+ bBrighten: cint;
+ bDarken: cint;
+ bSolarize: cint;
+ bInvert: cint;
+ bMotionVectorsOn: cint;
+ fps: cint;
+
+ fWaveAlpha: cfloat;
+ fWaveScale: cfloat;
+ fWaveSmoothing: cfloat;
+ fWaveParam: cfloat;
+ fModWaveAlphaStart: cfloat;
+ fModWaveAlphaEnd: cfloat;
+ fWarpAnimSpeed: cfloat;
+ fWarpScale: cfloat;
+ fShader: cfloat;
+
+
+ { Q VARIABLES START }
+
+ q1: cfloat;
+ q2: cfloat;
+ q3: cfloat;
+ q4: cfloat;
+ q5: cfloat;
+ q6: cfloat;
+ q7: cfloat;
+ q8: cfloat;
+
+
+ { Q VARIABLES END }
+
+ zoom_mesh: PPCfloat;
+ zoomexp_mesh: PPCfloat;
+ rot_mesh: PPCfloat;
+
+ sx_mesh: PPCfloat;
+ sy_mesh: PPCfloat;
+ dx_mesh: PPCfloat;
+ dy_mesh: PPCfloat;
+ cx_mesh: PPCfloat;
+ cy_mesh: PPCfloat;
+
+ x_mesh: PPCfloat;
+ y_mesh: PPCfloat;
+ rad_mesh: PPCfloat;
+ theta_mesh: PPCfloat;
+ end;
+
+ PProjectMState = ^TProjectMState;
+ TProjectMState = record
+ fontURLStr: string;
+ presetURLStr: string;
+ titleStr: string;
+ pm: _TProjectM;
+ end;
+
+{ projectM.h declarations }
+procedure _projectM_init(pm: _PProjectM); cdecl; external libprojectM name 'projectM_init';
+procedure _projectM_reset(pm: _PProjectM); cdecl; external libprojectM name 'projectM_reset';
+procedure _projectM_resetGL(pm: _PProjectM; width: cint; height: cint); cdecl; external libprojectM name 'projectM_resetGL';
+procedure _projectM_setTitle(pm: _PProjectM; title: PChar); cdecl; external libprojectM name 'projectM_setTitle';
+procedure _renderFrame(pm: _PProjectM); cdecl; external libprojectM name 'renderFrame';
+
+{ PCM.h declarations }
+procedure _addPCMfloat(pcm_data: PCfloat; samples: cint); cdecl; external libprojectM name 'addPCMfloat';
+procedure _addPCM16(pcm_data: PPCM16); cdecl; external libprojectM name 'addPCM16';
+procedure _addPCM16Data(pcm_data: PCshort; samples: cshort); cdecl; external libprojectM name 'addPCM16Data';
+procedure _addPCM8_512(pcm_data: PPCM8_512); cdecl; external libprojectM name 'addPCM8';
+
+{ console_interface.h declarations }
+procedure _key_handler(pm: _PProjectM;
+ event: TProjectMEvent;
+ keycode: TProjectMKeycode;
+ modifier: TProjectMModifier); cdecl; external libprojectM name 'key_handler';
+
+
+
+
+{**************** EXTERNAL SECTION ****************}
+
+
+constructor TProjectM.Create(gx, gy: cint; fps: integer;
+ texsize: integer; width, height: integer;
+ const presetsDir, fontsDir: string;
+ const titleFont, menuFont: string);
+var
+ state: PProjectMState;
+begin
+ inherited Create();
+
+ New(state);
+ data := state;
+
+ with state^ do
+ begin
+ // copy strings (Note: do not use e.g. PChar(presetsDir) directly, it might
+ // be a pointer to local stack data that is invalid after the calling function returns)
+ fontURLStr := fontsDir;
+ presetURLStr := presetsDir;
+
+ _projectM_reset(@pm);
+
+ pm.fullscreen := 0;
+ pm.renderTarget^.texsize := texsize;
+ pm.gx := gx;
+ pm.gy := gy;
+ pm.fps := fps;
+ pm.renderTarget^.usePbuffers := 0;
+ pm.fontURL := PChar(fontURLStr);
+ pm.presetURL := PChar(presetURLStr);
+
+ _projectM_init(@pm);
+ end;
+end;
+
+procedure TProjectM.ResetGL(width, height: integer);
+begin
+ _projectM_resetGL(@PProjectMState(data).pm, width, height);
+end;
+
+procedure TProjectM.SetTitle(const title: string);
+var
+ state: PProjectMState;
+begin
+ state := PProjectMState(data);
+ with state^ do
+ begin
+ titleStr := title;
+ pm.title := PChar(titleStr);
+ pm.showtitle := 1;
+ end;
+end;
+
+procedure TProjectM.RenderFrame();
+begin
+ _renderFrame(@PProjectMState(data).pm);
+end;
+
+procedure TProjectM.AddPCMfloat(pcmData: PSingle; samples: integer);
+begin
+ _addPCMfloat(PCfloat(pcmData), samples);
+end;
+
+procedure TProjectM.AddPCM16(pcmData: PPCM16);
+begin
+ _addPCM16(pcmData);
+end;
+
+procedure TProjectM.AddPCM16Data(pcmData: PSmallint; samples: Smallint);
+begin
+ _addPCM16Data(PCshort(pcmData), samples);
+end;
+
+procedure TProjectM.AddPCM8_512(pcmData: PPCM8_512);
+begin
+ _addPCM8_512(pcmData);
+end;
+
+procedure TProjectM.KeyHandler(event: TProjectMEvent;
+ keycode: TProjectMKeycode;
+ modifier: TProjectMModifier);
+begin
+ _key_handler(@PProjectMState(data).pm, event, keycode, modifier);
+end;
+
+procedure TProjectM.RandomPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_r_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.PreviousPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_p_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.NextPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_n_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.ToggleShowPresetNames();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_F3, PROJECTM_KMOD_LSHIFT);
+end;
+
+destructor TProjectM.Destroy();
+begin
+ Dispose(PProjectMState(data));
+ data := nil;
+ inherited;
+end;
+
diff --git a/src/lib/projectM/projectM-1_0.inc b/src/lib/projectM/projectM-1_0.inc
new file mode 100644
index 00000000..8e84894d
--- /dev/null
+++ b/src/lib/projectM/projectM-1_0.inc
@@ -0,0 +1,188 @@
+//uses
+
+(**
+ * Note: be careful with ProjectM's versioning scheme.
+ *
+ * Version | Version in pkg-config .pc file
+ * ---------+--------------------------------------------
+ * 1.00 | 1.00
+ * 1.01 | 1.00
+ * 1.1 | 1.10
+ * 1.2 | 1.2 (= 1.02)
+ *
+ * So the version number of 1.1 is bigger than that of 1.2.
+ *)
+
+const
+{$IFDEF MSWINDOWS}
+ // Note: static linking is not possible with delphi because it does neither
+ // accept gcc nor MSVC object files (only Intel-style ones).
+ libprojectM_cwrapper = 'projectM-cwrapper.dll';
+{$ELSE}
+ // static libs are not supported in the "external"-clause
+ libprojectM_cwrapper = '';
+ // statically link the cwrapper and dynamically link projectM
+ {$L 'cwrapper/libprojectM-cwrapper.a'}
+ {$LINKLIB projectM}
+{$ENDIF}
+
+{**************** INTERNAL SECTION ****************}
+
+
+type
+ _PProjectM = Pointer;
+
+{ projectM.hpp declarations }
+function _projectM_create1(config_file: PChar): _PProjectM; cdecl; external libprojectM_cwrapper name 'projectM_create1';
+{$IF PROJECTM_VERSION < 1000000} // 0.9x
+function _projectM_create2(gx: cint; gy: cint; fps: cint;
+ texsize: cint; width: cint; height: cint;
+ preset_url: PChar; title_fonturl: PChar; title_menuurl: PChar): _PProjectM; cdecl; external libprojectM_cwrapper name 'projectM_create2';
+{$IFEND}
+
+procedure _projectM_resetGL(pm: _PProjectM; width: cint; height: cint); cdecl; external libprojectM_cwrapper name 'projectM_resetGL';
+procedure _projectM_setTitle(pm: _PProjectM; title: PChar); cdecl; external libprojectM_cwrapper name 'projectM_setTitle';
+procedure _projectM_renderFrame(pm: _PProjectM); cdecl; external libprojectM_cwrapper name 'projectM_renderFrame';
+function _projectM_initRenderToTexture(pm: _PProjectM): cuint; cdecl; external libprojectM_cwrapper name 'projectM_initRenderToTexture';
+
+procedure _projectM_free(pm: _PProjectM); cdecl; external libprojectM_cwrapper name 'projectM_free';
+
+procedure _projectM_key_handler(pm: _PProjectM; event: TProjectMEvent;
+ keycode: TProjectMKeycode; modifier: TProjectMModifier); cdecl; external libprojectM_cwrapper name 'projectM_key_handler';
+
+{$IF PROJECTM_VERSION > 1000000} // > 1.01
+procedure _projectM_settings(pm: _PProjectM; settings: PSettings); cdecl; external libprojectM_cwrapper name 'projectM_settings';
+{$IFEND}
+
+{ PCM.hpp declarations }
+procedure _PCM_addPCMfloat(pm: _PProjectM; pcm_data: PSingle; samples: cint); cdecl; external libprojectM_cwrapper name 'PCM_addPCMfloat';
+procedure _PCM_addPCM16(pm: _PProjectM; pcm_data: PPCM16); cdecl; external libprojectM_cwrapper name 'PCM_addPCM16';
+procedure _PCM_addPCM16Data(pm: _PProjectM; pcm_data: PCshort; samples: cshort); cdecl; external libprojectM_cwrapper name 'PCM_addPCM16Data';
+procedure _PCM_addPCM8_512(pm: _PProjectM; pcm_data: PPCM8_512); cdecl; external libprojectM_cwrapper name 'PCM_addPCM8_512';
+procedure _PCM_addPCM8_1024(pm: _PProjectM; pcm_data: PPCM8_1024); cdecl; external libprojectM_cwrapper name 'PCM_addPCM8';
+
+
+{**************** EXTERNAL SECTION ****************}
+
+// This constructor is present in projectM 1.0(1) but does not work with
+// linux because of a bug.
+(*
+constructor TProjectM.Create(gx, gy: integer; fps: integer;
+ texsize: integer; width, height: integer;
+ const presetsDir, fontsDir: string;
+ const titleFont, menuFont: string);
+begin
+ data := _projectM_create2(gx, gy, fps, texsize, width, height,
+ PChar(presetsDir),
+ PChar(fontsDir + PathDelim + titleFont),
+ PChar(fontsDir + PathDelim + menuFont));
+end;
+*)
+
+constructor TProjectM.Create(const configFile: string);
+begin
+ inherited Create();
+
+ // we cannot catch C++ exceptions in delphi, so we have to check
+ // if configFile is valid first
+ if (not FileExists(configFile)) then
+ raise Exception.Create('Invalid file: ' + configFile);
+
+ data := _projectM_create1(PChar(configFile));
+ if (data = nil) then
+ raise Exception.Create('Creation of projectM object failed');
+end;
+
+procedure TProjectM.ResetGL(width, height: Integer);
+begin
+ _projectM_resetGL(data, width, height);
+end;
+
+procedure TProjectM.SetTitle(const title: string);
+begin
+ _projectM_setTitle(data, PChar(title));
+end;
+
+procedure TProjectM.RenderFrame();
+begin
+ _projectM_renderFrame(data);
+end;
+
+procedure TProjectM.AddPCMfloat(pcmData: PSingle; samples: integer);
+begin
+ _PCM_addPCMfloat(data, pcmData, samples);
+end;
+
+procedure TProjectM.AddPCM16(pcmData: PPCM16);
+begin
+ _PCM_addPCM16(data, pcmData);
+end;
+
+{**
+ * Passes interleaved stereo PCM-samples to projectM.
+ *}
+procedure TProjectM.AddPCM16Data(pcmData: PSmallint; samples: Smallint);
+begin
+ _PCM_addPCM16Data(data, PCshort(pcmData), samples);
+end;
+
+procedure TProjectM.AddPCM8_512(pcmData: PPCM8_512);
+begin
+ _PCM_addPCM8_512(data, pcmData);
+end;
+
+procedure TProjectM.AddPCM8_1024(pcmData: PPCM8_1024);
+begin
+ _PCM_addPCM8_1024(data, pcmData);
+end;
+
+{**
+ * If the result is > -1 projectM will render to a texture.
+ * The texture-ID is the return-value.
+ *}
+function TProjectM.InitRenderToTexture(): GLuint;
+begin
+ result := _projectM_initRenderToTexture(data);
+end;
+
+procedure TProjectM.KeyHandler(event: TProjectMEvent;
+ keycode: TProjectMKeycode;
+ modifier: TProjectMModifier);
+begin
+ _projectM_key_handler(data, event, keycode, modifier);
+end;
+
+procedure TProjectM.RandomPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_r_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.PreviousPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_p_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.NextPreset();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_n_LOWERCASE, PROJECTM_KMOD_LSHIFT);
+end;
+
+procedure TProjectM.ToggleShowPresetNames();
+begin
+ KeyHandler(PROJECTM_KEYDOWN, PROJECTM_K_F3, PROJECTM_KMOD_LSHIFT);
+end;
+
+{$IF PROJECTM_VERSION > 1000000} // > 1.01
+procedure TProjectM.Settings(var settings: TSettings);
+begin
+ _projectM_settings(data, @settings);
+end;
+{$IFEND}
+
+destructor TProjectM.Destroy();
+begin
+ _projectM_free(data);
+ data := nil;
+ inherited;
+end;
+
diff --git a/src/lib/projectM/projectM.pas b/src/lib/projectM/projectM.pas
new file mode 100644
index 00000000..4adba17d
--- /dev/null
+++ b/src/lib/projectM/projectM.pas
@@ -0,0 +1,232 @@
+unit projectM;
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+ {$H+} (* use AnsiString *)
+ {$PACKENUM 4} (* use 4-byte enums *)
+ {$PACKRECORDS C} (* C/C++-compatible record packing *)
+{$ELSE}
+ {$MINENUMSIZE 4} (* use 4-byte enums *)
+{$ENDIF}
+
+interface
+
+uses
+ SysUtils,
+ ctypes,
+ gl,
+ UConfig;
+
+type
+ // 16bit non-interleaved data
+ TPCM16 = array[0..1, 0..511] of Smallint;
+ PPCM16 = ^TPCM16;
+ // 8bit non-interleaved data (512 samples)
+ TPCM8_512 = array[0..1, 0..511] of byte;
+ PPCM8_512 = ^TPCM8_512;
+ // 8bit non-interleaved data (1024 samples)
+ TPCM8_1024 = array[0..1, 0..1023] of byte;
+ PPCM8_1024 = ^TPCM8_512;
+
+{ Event types }
+type
+ TProjectMEvent = cint;
+const
+ PROJECTM_KEYUP = 0;
+ PROJECTM_KEYDOWN = 1;
+ PROJECTM_VIDEORESIZE = 2;
+ PROJECTM_VIDEOQUIT = 3;
+ PROJECTM_NONE = 4;
+
+{ Keycodes }
+type
+ TProjectMKeycode = cint;
+const
+ PROJECTM_K_RETURN = 0;
+ PROJECTM_K_RIGHT = 1;
+ PROJECTM_K_LEFT = 2;
+ PROJECTM_K_UP = 3;
+ PROJECTM_K_DOWN = 4;
+ PROJECTM_K_PAGEUP = 5;
+ PROJECTM_K_PAGEDOWN = 6;
+ PROJECTM_K_INSERT = 7;
+ PROJECTM_K_DELETE = 8;
+ PROJECTM_K_ESCAPE = 9;
+ PROJECTM_K_LSHIFT = 10;
+ PROJECTM_K_RSHIFT = 11;
+ PROJECTM_K_CAPSLOCK = 12;
+ PROJECTM_K_LCTRL = 13;
+ PROJECTM_K_HOME = 14;
+ PROJECTM_K_END = 15;
+ PROJECTM_K_BACKSPACE = 16;
+
+ PROJECTM_K_F1 = 17;
+ PROJECTM_K_F2 = (PROJECTM_K_F1 + 1);
+ PROJECTM_K_F3 = (PROJECTM_K_F1 + 2);
+ PROJECTM_K_F4 = (PROJECTM_K_F1 + 3);
+ PROJECTM_K_F5 = (PROJECTM_K_F1 + 4);
+ PROJECTM_K_F6 = (PROJECTM_K_F1 + 5);
+ PROJECTM_K_F7 = (PROJECTM_K_F1 + 6);
+ PROJECTM_K_F8 = (PROJECTM_K_F1 + 7);
+ PROJECTM_K_F9 = (PROJECTM_K_F1 + 8);
+ PROJECTM_K_F10 = (PROJECTM_K_F1 + 9);
+ PROJECTM_K_F11 = (PROJECTM_K_F1 + 10);
+ PROJECTM_K_F12 = (PROJECTM_K_F1 + 11);
+
+ PROJECTM_K_0 = 48;
+ PROJECTM_K_1 = (PROJECTM_K_0 + 1);
+ PROJECTM_K_2 = (PROJECTM_K_0 + 2);
+ PROJECTM_K_3 = (PROJECTM_K_0 + 3);
+ PROJECTM_K_4 = (PROJECTM_K_0 + 4);
+ PROJECTM_K_5 = (PROJECTM_K_0 + 5);
+ PROJECTM_K_6 = (PROJECTM_K_0 + 6);
+ PROJECTM_K_7 = (PROJECTM_K_0 + 7);
+ PROJECTM_K_8 = (PROJECTM_K_0 + 8);
+ PROJECTM_K_9 = (PROJECTM_K_0 + 9);
+
+ { Upper case }
+ PROJECTM_K_A_UPPERCASE = 65;
+ PROJECTM_K_B_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 1);
+ PROJECTM_K_C_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 2);
+ PROJECTM_K_D_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 3);
+ PROJECTM_K_E_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 4);
+ PROJECTM_K_F_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 5);
+ PROJECTM_K_G_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 6);
+ PROJECTM_K_H_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 7);
+ PROJECTM_K_I_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 8);
+ PROJECTM_K_J_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 9);
+ PROJECTM_K_K_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 10);
+ PROJECTM_K_L_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 11);
+ PROJECTM_K_M_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 12);
+ PROJECTM_K_N_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 13);
+ PROJECTM_K_O_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 14);
+ PROJECTM_K_P_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 15);
+ PROJECTM_K_Q_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 16);
+ PROJECTM_K_R_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 17);
+ PROJECTM_K_S_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 18);
+ PROJECTM_K_T_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 19);
+ PROJECTM_K_U_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 20);
+ PROJECTM_K_V_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 21);
+ PROJECTM_K_W_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 22);
+ PROJECTM_K_X_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 23);
+ PROJECTM_K_Y_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 24);
+ PROJECTM_K_Z_UPPERCASE = (PROJECTM_K_A_UPPERCASE + 25);
+
+ { Lower case }
+ PROJECTM_K_a_LOWERCASE = 97;
+ PROJECTM_K_b_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 1);
+ PROJECTM_K_c_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 2);
+ PROJECTM_K_d_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 3);
+ PROJECTM_K_e_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 4);
+ PROJECTM_K_f_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 5);
+ PROJECTM_K_g_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 6);
+ PROJECTM_K_h_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 7);
+ PROJECTM_K_i_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 8);
+ PROJECTM_K_j_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 9);
+ PROJECTM_K_k_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 10);
+ PROJECTM_K_l_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 11);
+ PROJECTM_K_m_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 12);
+ PROJECTM_K_n_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 13);
+ PROJECTM_K_o_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 14);
+ PROJECTM_K_p_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 15);
+ PROJECTM_K_q_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 16);
+ PROJECTM_K_r_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 17);
+ PROJECTM_K_s_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 18);
+ PROJECTM_K_t_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 19);
+ PROJECTM_K_u_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 20);
+ PROJECTM_K_v_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 21);
+ PROJECTM_K_w_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 22);
+ PROJECTM_K_x_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 23);
+ PROJECTM_K_y_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 24);
+ PROJECTM_K_z_LOWERCASE = (PROJECTM_K_a_LOWERCASE + 25);
+
+ PROJECTM_K_NONE = (PROJECTM_K_z_LOWERCASE + 1);
+
+{ Modifiers }
+type
+ TProjectMModifier = cint;
+const
+ PROJECTM_KMOD_LSHIFT = 0;
+ PROJECTM_KMOD_RSHIFT = 1;
+ PROJECTM_KMOD_CAPS = 2;
+ PROJECTM_KMOD_LCTRL = 3;
+ PROJECTM_KMOD_RCTRL = 4;
+
+type
+ PSettings = ^TSettings;
+ TSettings = record
+ meshX: cint;
+ meshY: cint;
+ fps: cint;
+ textureSize: cint;
+ windowWidth: cint;
+ windowHeight: cint;
+ presetURL: PChar;
+ titleFontURL: PChar;
+ menuFontURL: PChar;
+ smoothPresetDuration: cint;
+ presetDuration: cint;
+ beatSensitivity: cfloat;
+ aspectCorrection: byte;
+ easterEgg: cfloat;
+ shuffleEnabled: byte;
+ end;
+
+type
+ PProjectM = ^TProjectM;
+ TProjectM = class(TObject)
+ private
+ data: Pointer;
+ public
+ {$IF PROJECTM_VERSION < 1000000} // 0.9x
+ constructor Create(gx, gy: integer; fps: integer;
+ texsize: integer; width, height: integer;
+ const presetsDir, fontsDir: string;
+ const titleFont: string = 'Vera.ttf';
+ const menuFont: string = 'Vera.ttf'); overload;
+ {$IFEND}
+ {$IF PROJECTM_VERSION >= 1000000}
+ constructor Create(const configFile: string); overload;
+ {$IFEND}
+
+ procedure ResetGL(width, height: Integer);
+ procedure SetTitle(const title: string);
+ procedure RenderFrame();
+
+ procedure AddPCMfloat(pcmData: PSingle; samples: integer);
+ procedure AddPCM16(pcmData: PPCM16);
+ procedure AddPCM16Data(pcmData: PSmallint; samples: Smallint);
+ procedure AddPCM8_512(pcmData: PPCM8_512);
+ {$IF PROJECTM_VERSION >= 1000000}
+ procedure AddPCM8_1024(pcmData: PPCM8_1024);
+ {$IFEND}
+
+ procedure RandomPreset();
+ procedure PreviousPreset();
+ procedure NextPreset();
+ procedure ToggleShowPresetNames();
+
+ {$IF PROJECTM_VERSION >= 1000000}
+ function InitRenderToTexture(): GLuint;
+ {$IFEND}
+
+ procedure KeyHandler(event: TProjectMEvent;
+ keycode: TProjectMKeycode;
+ modifier: TProjectMModifier);
+
+ {$IF PROJECTM_VERSION > 1000000} // > 1.01
+ procedure Settings(var settings: TSettings);
+ {$IFEND}
+
+ destructor Destroy(); override;
+ end;
+
+implementation
+
+{$IF PROJECTM_VERSION >= 1000000}
+ {$I projectM-1_0.inc}
+{$ELSE}
+ {$I projectM-0_9.inc}
+{$IFEND}
+
+end.
diff --git a/src/lib/requirements.txt b/src/lib/requirements.txt
new file mode 100644
index 00000000..a5af1ac4
--- /dev/null
+++ b/src/lib/requirements.txt
@@ -0,0 +1,39 @@
+Included in SVN ..
+---------------------------------------------------------------------------
+
+
+Jedi-sdl
+ http://sourceforge.net/projects/jedi-sdl
+
+pngImage
+ http://pngdelphi.sourceforge.net/
+
+BASS.pas
+ http://www.un4seen.com/download.php?bass23
+
+zlportio
+ http://www.specosoft.com/en/download.html
+
+ffmpeg
+ http://www.iversenit.dk/dev/ffmpeg-headers/
+
+SQLLite Wrapper
+ http://www.itwriting.com/sqlitesimple.php
+
+======================================
+For LINUX build
+======================================
+On top of the above pas files, you will need development libraries for them.
+
+here are the instructions needed to compile on ubunty ( 7.04 )
+
+ sudo apt-get install libavcodec-dev libavformat-dev libsqlite3-dev libsdl-ttf2.0-dev libsdl-image1.2-dev portaudio19-dev
+
+in order to build the configure file ( with autogen.sh )
+
+ sudo apt-get install automake autoconf
+
+
+for Fedora 8 ( contributed by kdub )
+
+ yum install ffmpeg-devel portaudio-devel SDL_ttf-devel SDL_image-devel sqlite-devel
diff --git a/src/lib/samplerate/samplerate.pas b/src/lib/samplerate/samplerate.pas
new file mode 100644
index 00000000..784b87da
--- /dev/null
+++ b/src/lib/samplerate/samplerate.pas
@@ -0,0 +1,199 @@
+{*
+** Copyright (C) 2002-2004 Erik de Castro Lopo
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+*}
+
+{*
+** API documentation is available here:
+** http://www.mega-nerd.com/SRC/api.html
+*}
+
+unit samplerate;
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+ {$PACKENUM 4} (* use 4-byte enums *)
+ {$PACKRECORDS C} (* GCC/Visual C/C++ compatible record packing *)
+{$ELSE}
+ {$MINENUMSIZE 4} (* use 4-byte enums *)
+{$ENDIF}
+
+
+interface
+
+uses
+ ctypes,
+ UConfig;
+
+const
+{$IFDEF MSWINDOWS}
+ LibName = 'libsamplerate-0.dll';
+{$ENDIF}
+{$IFDEF UNIX}
+ LibName = 'samplerate';
+ {$IFDEF DARWIN}
+ {$LINKLIB libsamplerate}
+ {$ENDIF}
+{$ENDIF}
+
+{ Opaque data type SRC_STATE. }
+type
+ PSRC_STATE = ^SRC_STATE;
+ SRC_STATE = record
+ // opaque
+ end;
+
+{ SRC_DATA is used to pass data to src_simple() and src_process(). }
+type
+ PSRC_DATA = ^SRC_DATA;
+ SRC_DATA = record
+ data_in, data_out: PCfloat;
+ input_frames, output_frames: clong;
+ input_frames_used, output_frames_gen: clong;
+ end_of_input: cint;
+ src_ratio: cdouble;
+ end;
+
+{ SRC_CB_DATA is used with callback based API. }
+type
+ SRC_CB_DATA = record
+ frames: clong;
+ data_in: PCfloat;
+ end;
+
+{*
+** User supplied callback function type for use with src_callback_new()
+** and src_callback_read(). First parameter is the same pointer that was
+** passed into src_callback_new(). Second parameter is pointer to a
+** pointer. The user supplied callback function must modify *data to
+** point to the start of the user supplied float array. The user supplied
+** function must return the number of frames that **data points to.
+*}
+src_callback_t = function (cb_data: pointer; var data: PCfloat): clong; cdecl;
+
+{*
+** Standard initialisation function : return an anonymous pointer to the
+** internal state of the converter. Choose a converter from the enums below.
+** Error returned in *error.
+*}
+function src_new(converter_type: cint; channels: cint; error: PCint): PSRC_STATE; cdecl; external LibName;
+
+{*
+** Initilisation for callback based API : return an anonymous pointer to the
+** internal state of the converter. Choose a converter from the enums below.
+** The cb_data pointer can point to any data or be set to NULL. Whatever the
+** value, when processing, user supplied function "func" gets called with
+** cb_data as first parameter.
+*}
+function src_callback_new(func: src_callback_t; converter_type: cint; channels: cint;
+ error: Pinteger; cb_data: pointer): PSRC_STATE; cdecl; external LibName;
+
+{*
+** Cleanup all internal allocations.
+** Always returns NULL.
+*}
+function src_delete(state: PSRC_STATE): PSRC_STATE; cdecl; external LibName;
+
+{*
+** Standard processing function.
+** Returns non zero on error.
+*}
+function src_process(state: PSRC_STATE; data: PSRC_DATA): cint; cdecl; external LibName;
+
+{*
+** Callback based processing function. Read up to frames worth of data from
+** the converter int *data and return frames read or -1 on error.
+*}
+function src_callback_read(state: PSRC_STATE; src_ratio: cdouble;
+ frames: clong; data: PCfloat): clong; cdecl; external LibName;
+
+{*
+** Simple interface for performing a single conversion from input buffer to
+** output buffer at a fixed conversion ratio.
+** Simple interface does not require initialisation as it can only operate on
+** a single buffer worth of audio.
+*}
+function src_simple(data: PSRC_DATA; converter_type: cint; channels: cint): cint; cdecl; external LibName;
+
+{*
+** This library contains a number of different sample rate converters,
+** numbered 0 through N.
+**
+** Return a string giving either a name or a more full description of each
+** sample rate converter or NULL if no sample rate converter exists for
+** the given value. The converters are sequentially numbered from 0 to N.
+*}
+function src_get_name(converter_type: cint): {const} Pchar; cdecl; external LibName;
+function src_get_description(converter_type: cint): {const} Pchar; cdecl; external LibName;
+function src_get_version(): {const} Pchar; cdecl; external LibName;
+
+{*
+** Set a new SRC ratio. This allows step responses
+** in the conversion ratio.
+** Returns non zero on error.
+*}
+function src_set_ratio(state: PSRC_STATE; new_ratio: cdouble): cint; cdecl; external LibName;
+
+{*
+** Reset the internal SRC state.
+** Does not modify the quality settings.
+** Does not free any memory allocations.
+** Returns non zero on error.
+*}
+function src_reset(state: PSRC_STATE): cint; cdecl; external LibName;
+
+{*
+** Return TRUE if ratio is a valid conversion ratio, FALSE
+** otherwise.
+*}
+function src_is_valid_ratio(ratio: cdouble): cint; cdecl; external LibName;
+
+{*
+** Return an error number.
+*}
+function src_error(state: PSRC_STATE): cint; cdecl; external LibName;
+
+{*
+** Convert the error number into a string.
+*}
+function src_strerror(error: cint): {const} Pchar; cdecl; external LibName;
+
+{*
+** The following enums can be used to set the interpolator type
+** using the function src_set_converter().
+*}
+const
+ SRC_SINC_BEST_QUALITY = 0;
+ SRC_SINC_MEDIUM_QUALITY = 1;
+ SRC_SINC_FASTEST = 2;
+ SRC_ZERO_ORDER_HOLD = 3;
+ SRC_LINEAR = 4;
+
+{*
+** Extra helper functions for converting from short to float and
+** back again.
+*}
+procedure src_short_to_float_array(input: {const} PCshort; output: PCfloat; len: cint); cdecl; external LibName;
+procedure src_float_to_short_array(input: {const} PCfloat; output: PCshort; len: cint); cdecl; external LibName;
+
+{$IF LIBSAMPLERATE_VERSION >= 1003} // 0.1.3
+procedure src_int_to_float_array(input: {const} PCint; output: PCfloat; len: cint); cdecl; external LibName;
+procedure src_float_to_int_array(input: {const} PCfloat; output: PCint; len: cint); cdecl; external LibName;
+{$IFEND}
+
+implementation
+
+end.
diff --git a/src/lib/zlib/zlib.pas b/src/lib/zlib/zlib.pas
new file mode 100644
index 00000000..31d6a68b
--- /dev/null
+++ b/src/lib/zlib/zlib.pas
@@ -0,0 +1,215 @@
+(*
+ * zlib pascal headers
+ * This file is part of Free Pascal, released under the LGPL.
+ *)
+
+{$ifdef FPC}
+ {$ifndef NO_SMART_LINK}
+ {$smartlink on}
+ {$endif}
+{$endif}
+unit zlib;
+
+interface
+
+{$ifdef FPC}
+ {$mode objfpc} // Needed for array of const
+ {$H+} // use AnsiString
+ {$PACKRECORDS C}
+{$endif}
+
+uses
+ ctypes;
+
+const
+ ZLIB_VERSION = '1.2.3';
+
+{$ifdef MSWINDOWS}
+ libz = 'zlib1';
+{$else}
+ libz = 'z';
+ {$IFDEF DARWIN}
+ {$linklib libz}
+ {$ENDIF}
+{$endif}
+
+type
+ { Compatible with paszlib }
+ uInt = cuint;
+ uLong = culong;
+ uLongf = uLong; {FAR}
+ PuLongf = ^uLongf;
+ z_off_t = clong;
+ pbyte = ^byte;
+ bytef = byte; {FAR}
+ pbytef = ^byte;
+ voidpf = pointer;
+
+ TAllocfunc = function (opaque: voidpf; items: uInt; size: uInt): voidpf; cdecl;
+ TFreeFunc = procedure (opaque: voidpf; address: voidpf); cdecl;
+
+ TInternalState = record
+ end;
+ PInternalState = ^TInternalstate;
+
+ TZStream = record
+ next_in: pbytef;
+ avail_in: uInt;
+ total_in: uLong;
+ next_out: pbytef;
+ avail_out: uInt;
+ total_out: uLong;
+ msg: pchar;
+ state: PInternalState;
+ zalloc: TAllocFunc;
+ zfree: TFreeFunc;
+ opaque: voidpf;
+ data_type: cint;
+ adler: uLong;
+ reserved: uLong;
+ end;
+ TZStreamRec = TZStream;
+ PZstream = ^TZStream;
+ gzFile = pointer;
+
+
+const
+ Z_NO_FLUSH = 0;
+ Z_PARTIAL_FLUSH = 1;
+ Z_SYNC_FLUSH = 2;
+ Z_FULL_FLUSH = 3;
+ Z_FINISH = 4;
+ Z_BLOCK = 5;
+
+ Z_OK = 0;
+ Z_STREAM_END = 1;
+ Z_NEED_DICT = 2;
+ Z_ERRNO = -(1);
+ Z_STREAM_ERROR = -(2);
+ Z_DATA_ERROR = -(3);
+ Z_MEM_ERROR = -(4);
+ Z_BUF_ERROR = -(5);
+ Z_VERSION_ERROR = -(6);
+
+ Z_NO_COMPRESSION = 0;
+ Z_BEST_SPEED = 1;
+ Z_BEST_COMPRESSION = 9;
+ Z_DEFAULT_COMPRESSION = -(1);
+
+ Z_FILTERED = 1;
+ Z_HUFFMAN_ONLY = 2;
+ Z_RLE = 3;
+ Z_FIXED = 4;
+ Z_DEFAULT_STRATEGY = 0;
+
+ Z_BINARY = 0;
+ Z_TEXT = 1;
+ Z_ASCII = Z_TEXT;
+ Z_UNKNOWN = 2;
+
+ Z_DEFLATED = 8;
+
+ Z_NULL = 0;
+
+function zlibVersionpchar(): pchar; cdecl; external libz name 'zlibVersion';
+function zlibVersion(): string;
+
+function deflate(var strm: TZStream; flush: integer): integer; cdecl; external libz name 'deflate';
+function deflateEnd(var strm: TZStream): integer; cdecl; external libz name 'deflateEnd';
+function inflate(var strm: TZStream; flush: integer): integer; cdecl; external libz name 'inflate';
+function inflateEnd(var strm: TZStream): integer; cdecl; external libz name 'inflateEnd';
+function deflateSetDictionary(var strm: TZStream; dictionary: pbytef; dictLength: uInt): integer; cdecl; external libz name 'deflateSetDictionary';
+function deflateCopy(var dest, source: TZstream): integer; cdecl; external libz name 'deflateCopy';
+function deflateReset(var strm: TZStream): integer; cdecl; external libz name 'deflateReset';
+function deflateParams(var strm: TZStream; level: integer; strategy: integer): integer; cdecl; external libz name 'deflateParams';
+//...
+function inflateSetDictionary(var strm: TZStream; dictionary: pbytef; dictLength: uInt): integer; cdecl; external libz name 'inflateSetDictionary';
+function inflateSync(var strm: TZStream): integer; cdecl; external libz name 'inflateSync';
+//...
+function inflateReset(var strm: TZStream): integer; cdecl; external libz name 'inflateReset';
+
+function compress(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong): integer; cdecl; external libz name 'compress';
+function compress2(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong; level: integer): integer; cdecl; external libz name 'compress2';
+function uncompress(dest: pbytef; destLen: puLongf; source : pbytef; sourceLen: uLong): integer; cdecl; external libz name 'uncompress';
+
+function gzopen(path: pchar; mode: pchar): gzFile; cdecl; external libz name 'gzopen';
+function gzdopen(fd: integer; mode: pchar): gzFile; cdecl; external libz name 'gzdopen';
+function gzsetparams(thefile: gzFile; level: integer; strategy: integer): integer; cdecl; external libz name 'gzsetparams';
+function gzread(thefile: gzFile; buf: pointer; len: cardinal): integer; cdecl; external libz name 'gzread';
+function gzwrite(thefile: gzFile; buf: pointer; len: cardinal): integer; cdecl; external libz name 'gzwrite';
+function gzprintf(thefile: gzFile; format: pbytef; args: array of const): integer; cdecl; external libz name 'gzprintf';
+function gzputs(thefile: gzFile; s: pbytef): integer; cdecl; external libz name 'gzputs';
+function gzgets(thefile: gzFile; buf: pbytef; len: integer): pchar; cdecl; external libz name 'gzgets';
+function gzputc(thefile: gzFile; c: integer): integer; cdecl; external libz name 'gzputc';
+function gzgetc(thefile: gzFile): integer; cdecl; external libz name 'gzgetc';
+function gzflush(thefile: gzFile; flush: integer): integer; cdecl; external libz name 'gzflush';
+function gzseek(thefile: gzFile; offset: z_off_t; whence: integer): z_off_t; cdecl; external libz name 'gzseek';
+function gzrewind(thefile: gzFile): integer; cdecl; external libz name 'gzrewind';
+function gztell(thefile: gzFile): z_off_t; cdecl; external libz name 'gztell';
+function gzeof(thefile: gzFile): integer; cdecl; external libz name 'gzeof';
+function gzclose(thefile: gzFile): integer; cdecl; external libz name 'gzclose';
+function gzerror(thefile: gzFile; var errnum: integer): pchar; cdecl; external libz name 'gzerror';
+
+function adler32(adler: uLong; buf: pbytef; len: uInt): uLong; cdecl; external libz name 'adler32';
+function crc32(crc: uLong; buf: pbytef; len: uInt): uLong; cdecl; external libz name 'crc32';
+
+function deflateInit_(var strm: TZStream; level: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'deflateInit_';
+function deflateInit(var strm: TZStream; level : integer) : integer;
+function inflateInit_(var strm: TZStream; version: pchar; stream_size: integer): integer; cdecl; external libz name 'inflateInit_';
+function inflateInit(var strm:TZStream) : integer;
+function deflateInit2_(var strm: TZStream; level: integer; method: integer; windowBits: integer; memLevel: integer; strategy: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'deflateInit2_';
+function deflateInit2(var strm: TZStream; level, method, windowBits, memLevel, strategy: integer): integer;
+function inflateInit2_(var strm: TZStream; windowBits: integer; version: pchar; stream_size: integer): integer; cdecl; external libz name 'inflateInit2_';
+function inflateInit2(var strm: TZStream; windowBits: integer): integer;
+
+function zErrorpchar(err: integer): pchar; cdecl; external libz name 'zError';
+function zError(err: integer): string;
+function inflateSyncPoint(z: PZstream): integer; cdecl; external libz name 'inflateSyncPoint';
+function get_crc_table(): pointer; cdecl; external libz name 'get_crc_table';
+
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+
+implementation
+
+function zlibversion(): string;
+begin
+ zlibversion := string(zlibversionpchar);
+end;
+
+function deflateInit(var strm: TZStream; level: integer) : integer;
+begin
+ deflateInit := deflateInit_(strm, level, ZLIB_VERSION, sizeof(TZStream));
+end;
+
+function inflateInit(var strm: TZStream): integer;
+begin
+ inflateInit := inflateInit_(strm, ZLIB_VERSION, sizeof(TZStream));
+end;
+
+function deflateInit2(var strm: TZStream; level, method, windowBits, memLevel, strategy: integer) : integer;
+begin
+ deflateInit2 := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, sizeof(TZStream));
+end;
+
+function inflateInit2(var strm: TZStream; windowBits: integer): integer;
+begin
+ inflateInit2 := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(TZStream));
+end;
+
+function zError(err: integer): string;
+begin
+ zerror := string(zErrorpchar(err));
+end;
+
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+begin
+ Result := GetMemory(Items * Size);
+end;
+
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+begin
+ FreeMem(Block);
+end;
+
+end.
diff --git a/src/m4/ac_define_dir.m4 b/src/m4/ac_define_dir.m4
new file mode 100644
index 00000000..f3d8734f
--- /dev/null
+++ b/src/m4/ac_define_dir.m4
@@ -0,0 +1,47 @@
+##### http://autoconf-archive.cryp.to/ac_define_dir.html
+#
+# SYNOPSIS
+#
+# AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+#
+# DESCRIPTION
+#
+# This macro sets VARNAME to the expansion of the DIR variable,
+# taking care of fixing up ${prefix} and such.
+#
+# VARNAME is then offered as both an output variable and a C
+# preprocessor symbol.
+#
+# Example:
+#
+# AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+#
+# LAST MODIFICATION
+#
+# 2006-10-13
+#
+# COPYLEFT
+#
+# Copyright (c) 2006 Stepan Kasal
+# Copyright (c) 2006 Andreas Schwab
+# Copyright (c) 2006 Guido U. Draheim
+# Copyright (c) 2006 Alexandre Oliva
+#
+# Copying and distribution of this file, with or without
+# modification, are permitted in any medium without royalty provided
+# the copyright notice and this notice are preserved.
+
+AC_DEFUN([AC_DEFINE_DIR], [
+ prefix_NONE=
+ exec_prefix_NONE=
+ test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}. Thus we have to use `eval' twice.
+ eval ac_define_dir="\"[$]$2\""
+ eval ac_define_dir="\"$ac_define_dir\""
+ AC_SUBST($1, "$ac_define_dir")
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3])
+ test "$prefix_NONE" && prefix=NONE
+ test "$exec_prefix_NONE" && exec_prefix=NONE
+])
diff --git a/src/m4/fpc.m4 b/src/m4/fpc.m4
new file mode 100644
index 00000000..896c53d2
--- /dev/null
+++ b/src/m4/fpc.m4
@@ -0,0 +1,176 @@
+dnl ** Version 1.1 of file is part of the LGPLed
+dnl ** J Sound System (http://jss.sourceforge.net)
+dnl **
+dnl ** Checks for Free Pascal Compiler by Matti "ccr/TNSP" Hamalainen
+dnl ** (C) Copyright 2000-2001 Tecnic Software productions (TNSP)
+dnl **
+dnl ** Versions
+dnl ** --------
+dnl ** 1.0 - Created
+dnl **
+dnl ** 1.1 - Added stuff to enable unix -> win32
+dnl ** cross compilation.
+dnl **
+dnl ** 1.x - A few fixes (by the UltraStar Deluxe Team)
+dnl **
+
+AC_DEFUN([AC_PROG_FPC], [
+
+AC_ARG_VAR(PFLAGS, [Free Pascal Compiler flags (replaces all other flags)])
+AC_ARG_VAR(PFLAGS_DEBUG, [Free Pascal Compiler debug flags @<:@-gl -Coi -Xs- -vew -dDEBUG_MODE@:>@])
+AC_ARG_VAR(PFLAGS_RELEASE, [Free Pascal Compiler release flags @<:@-O2 -Xs -vew@:>@])
+AC_ARG_VAR(PFLAGS_EXTRA, [Free Pascal Compiler additional flags])
+
+dnl set DEBUG/RELEASE flags to default-values if unset
+
+dnl - Do not use -dDEBUG because this will enable range-checks that will fail with USDX.
+dnl - Disable -Xs which is defined in fpc.cfg (TODO: is this necessary?).
+dnl - For FPC we have to use DEBUG_MODE instead of DEBUG to enable the apps debug-mode
+dnl because DEBUG enables some additional compiler-flags in fpc.cfg too
+PFLAGS_DEBUG=${PFLAGS_DEBUG-"-gl -Xs- -vew -dDEBUG_MODE"}
+dnl -dRELEASE works too but we define our own settings
+PFLAGS_RELEASE=${PFLAGS_RELEASE-"-O2 -Xs -vew"}
+
+
+AC_ARG_ENABLE(dummy_fpc1,[
+Free Pascal Compiler specific options:])
+
+AC_ARG_WITH(fpc,
+ [AS_HELP_STRING([--with-fpc=DIR],
+ [Directory of the FPC executable @<:@PATH@:>@])],
+ [PPC_PATH=$withval], [])
+
+FPC_DEBUG="no"
+
+AC_ARG_ENABLE(release,
+ [AS_HELP_STRING([--enable-release],
+ [Enable FPC release options @<:@default=yes@:>@])],
+ [test $enableval = "no" && FPC_DEBUG="yes"], [])
+
+AC_ARG_ENABLE(debug,
+ [AS_HELP_STRING([--enable-debug],
+ [Enable FPC debug options (= --disable-release) @<:@default=no@:>@])],
+ [test $enableval = "yes" && FPC_DEBUG="yes"], [])
+
+AC_ARG_ENABLE(profile,
+ [AS_HELP_STRING([--enable-profile],
+ [Enable FPC profiling options @<:@default=no@:>@])],
+ [PFLAGS_EXTRA="$PFLAGS_EXTRA -pg"], [])
+
+
+dnl ** set PFLAGS depending on whether it is already set by the user
+dnl Note: the user's PFLAGS must *follow* this script's flags
+dnl to enable the user to overwrite the settings.
+if test x${PFLAGS+assigned} = x; then
+dnl PFLAGS not set by the user
+ if test x$FPC_DEBUG = xyes; then
+ PFLAGS="$PFLAGS_DEBUG"
+ PFLAGS_MAKE="[\$](PFLAGS_DEBUG)"
+ else
+ PFLAGS="$PFLAGS_RELEASE"
+ PFLAGS_MAKE="[\$](PFLAGS_RELEASE)"
+ fi
+else
+dnl PFLAGS set by the user, just add additional flags
+ PFLAGS="$PFLAGS"
+ PFLAGS_MAKE="$PFLAGS"
+fi
+
+dnl ** find compiler executable
+
+PPC_CHECK_PROGS="fpc FPC ppc386 ppc PPC386 ppos2"
+
+if test -z "$PPC_PATH"; then
+ PPC_PATH=$PATH
+ AC_CHECK_PROGS(PPC, $PPC_CHECK_PROGS)
+ AC_CHECK_PROGS(FPCMAKE, [fpcmake])
+else
+ AC_PATH_PROGS(PPC, $PPC_CHECK_PROGS, [], $PPC_PATH)
+ AC_PATH_PROGS(FPCMAKE, [fpcmake], [], $PPC_PATH)
+fi
+if test -z "$PPC"; then
+ AC_MSG_ERROR([no Free Pascal Compiler found in $PPC_PATH])
+fi
+if test -z "$FPCMAKE"; then
+ AC_MSG_ERROR([fpcmake not found in $PPC_PATH])
+fi
+
+AC_PROG_FPC_WORKS
+AC_PROG_FPC_LINKS
+
+dnl *** Get the FPC version and some paths
+FPC_VERSION=`${PPC} -iV`
+FPC_PLATFORM=`${PPC} -iTO`
+FPC_PROCESSOR=`${PPC} -iTP`
+
+if test "x$prefix" != xNONE; then
+ FPC_PREFIX=$prefix
+else
+ FPC_PREFIX=$ac_default_prefix
+fi
+FPC_BASE_PATH="${FPC_PREFIX}/lib/fpc/${FPC_VERSION}"
+FPC_UNIT_PATH="${FPC_BASE_PATH}/units/${FPC_PLATFORM}"
+
+AC_SUBST(PFLAGS)
+AC_SUBST(PFLAGS_MAKE)
+AC_SUBST(PFLAGS_EXTRA)
+AC_SUBST(PFLAGS_DEBUG)
+AC_SUBST(PFLAGS_RELEASE)
+
+AC_SUBST(FPC_VERSION)
+AC_SUBST(FPC_PLATFORM)
+AC_SUBST(FPC_PROCESSOR)
+
+AC_SUBST(FPC_PREFIX)
+AC_SUBST(FPC_BASE_PATH)
+AC_SUBST(FPC_UNIT_PATH)
+])
+
+PFLAGS_TEST="$PFLAGS $PFLAGS_EXTRA"
+
+dnl ***
+dnl *** Check if FPC works and can compile a program
+dnl ***
+AC_DEFUN([AC_PROG_FPC_WORKS],
+[AC_CACHE_CHECK([whether the Free Pascal Compiler ($PPC $PFLAGS_TEST) works], ac_cv_prog_ppc_works,
+[
+rm -f conftest*
+echo "program foo; begin writeln; end." > conftest.pp
+${PPC} ${PFLAGS_TEST} conftest.pp >> config.log
+
+if test -f conftest || test -f conftest.exe; then
+dnl *** It works!
+ ac_cv_prog_ppc_works="yes"
+
+else
+ ac_cv_prog_ppc_works="no"
+fi
+rm -f conftest*
+dnl AC_MSG_RESULT($ac_cv_prog_ppc_works)
+if test x$ac_cv_prog_ppc_works = xno; then
+ AC_MSG_ERROR([installation or configuration problem: Cannot create executables.])
+fi
+])])
+
+
+dnl ***
+dnl *** Check if FPC can link with standard libraries
+dnl ***
+AC_DEFUN([AC_PROG_FPC_LINKS],
+[AC_CACHE_CHECK([whether the Free Pascal Compiler ($PPC $PFLAGS_TEST) can link], ac_cv_prog_ppc_works,
+[
+rm -f conftest*
+echo "program foo; uses crt; begin writeln; end." > conftest.pp
+${PPC} ${PFLAGS_TEST} conftest.pp >> config.log
+if test -f conftest || test -f conftest.exe; then
+ ac_cv_prog_ppc_links="yes"
+else
+ ac_cv_prog_ppc_links="no"
+fi
+rm -f conftest*
+AC_MSG_RESULT($ac_cv_prog_ppc_links)
+if test x$ac_cv_prog_ppc_links = xno; then
+ AC_MSG_ERROR([installation or configuration problem: Cannot link with some standard libraries.])
+fi
+])])
+
diff --git a/src/package_debian.sh b/src/package_debian.sh
new file mode 100644
index 00000000..bdb341a2
--- /dev/null
+++ b/src/package_debian.sh
@@ -0,0 +1,32 @@
+# This script should be run post-compile
+# and i should move files to the correct location for packaging ... ( for DEB package )
+
+rm -fr ../../../deb-package
+rm -fr ../../../packages
+clear
+
+mkdir ../../../packages
+
+mkdir ../../../deb-package
+mkdir ../../../deb-package/DEBIAN
+mkdir ../../../deb-package/usr
+mkdir ../../../deb-package/usr/local
+mkdir ../../../deb-package/usr/local/share
+mkdir ../../../deb-package/usr/local/share/UltraStarDeluxe
+mkdir ../../../deb-package/usr/bin
+
+cp ../../UltraStar ../../../deb-package/usr/bin/UltraStarDeluxe
+
+cp -a ../../Themes/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
+cp -a ../../Sounds/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
+cp -a ../../Skins/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
+cp -a ../../Languages/ ../../../deb-package/usr/local/share/UltraStarDeluxe/
+
+cp UltraStarDeluxe.control ../../../deb-package/DEBIAN/control
+
+cd ../../../
+
+dpkg-deb --build ./deb-package
+mv deb-package.deb ./packages/UltraStarDeluxe_1.1_i386.deb
+
+rm -fr ../../../deb-package
diff --git a/src/rccompile-delphi.bat b/src/rccompile-delphi.bat
new file mode 100644
index 00000000..7f0e2f0e
--- /dev/null
+++ b/src/rccompile-delphi.bat
@@ -0,0 +1 @@
+BRC32 -r -foUltraStar.res UltraStar.rc
diff --git a/src/rccompile-fpc.bat b/src/rccompile-fpc.bat
new file mode 100644
index 00000000..ed8d57aa
--- /dev/null
+++ b/src/rccompile-fpc.bat
@@ -0,0 +1,3 @@
+@set PATH=C:\Programme\lazarus\fpc\2.2.0\bin\i386-win32\;%PATH%
+windres.exe -i UltraStar.rc -o UltraStar.res
+
diff --git a/src/switches.inc b/src/switches.inc
new file mode 100644
index 00000000..eb67e72c
--- /dev/null
+++ b/src/switches.inc
@@ -0,0 +1,111 @@
+// compiler/IDE dependent config
+{$IFDEF FPC}
+ {$H+} // use AnsiString instead of ShortString as String-type (default in Delphi)
+
+ {$IFDEF DARWIN}
+ {$R-} // disable range-checks (eddie: please test if this is still necessary)
+ {$ENDIF}
+
+ // if -dDEBUG is specified on the command-line, FPC uses some default
+ // compiler-flags specified in fpc.cfg -> use -dDEBUG_MODE instead
+ {$IFDEF DEBUG_MODE}
+ {$DEFINE DEBUG}
+ {$ENDIF}
+
+ {$DEFINE HasInline}
+{$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}
+{$ENDIF}
+
+
+// platform dependent config
+{$IF Defined(MSWINDOWS)}
+ // include defines but no constants
+ {$I config-win.inc}
+
+ // enable debug-mode. For development only!
+ {.$DEFINE DEBUG}
+ {$IFDEF DEBUG}
+ // windows apps are either GUI- or console-apps. Console-apps will open
+ // an additional console-window for output. For development only!
+ {$DEFINE CONSOLE}
+ {$ENDIF}
+
+ {$DEFINE HaveBASS}
+ {$UNDEF UseSerialPort}
+ {$DEFINE UseMIDIPort}
+{$ELSEIF Defined(LINUX)}
+ // include defines but no constants
+ {$I config-linux.inc}
+
+ // use "configure --enable-debug", "make debug" or
+ // the command-line parameter "-debug" instead of defining DEBUG directly
+ {.$DEFINE DEBUG}
+ // linux apps are always console-apps so leave this defined.
+ {$DEFINE CONSOLE}
+{$ELSEIF Defined(DARWIN)}
+ // include defines but no constants
+ {$I config-darwin.inc}
+
+ // enable debug-mode. For development only!
+ {.$DEFINE DEBUG}
+ {$DEFINE CONSOLE}
+ {.$DEFINE HaveBASS}
+ {$DEFINE UTF8_FILENAMES}
+{$IFEND}
+
+// audio config
+{$IF Defined(HaveBASS)}
+ {$DEFINE UseBASSPlayback}
+ {$DEFINE UseBASSDecoder}
+ {$DEFINE UseBASSInput}
+{$ELSEIF Defined(HavePortaudio)}
+ {$DEFINE UseSDLPlayback}
+ {.$DEFINE UsePortaudioPlayback}
+ {$DEFINE UsePortaudioInput}
+ {$IFDEF HavePortmixer}
+ {$DEFINE UsePortmixer}
+ {$ENDIF}
+{$IFEND}
+
+// ffmpeg config
+{$IFDEF HaveFFmpeg}
+ {$DEFINE UseFFmpegDecoder}
+ {$DEFINE UseFFmpegResample}
+ {$DEFINE UseFFmpegVideo}
+ {$IFDEF HaveSWScale}
+ {$DEFINE UseSWScale}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF HaveLibsamplerate}
+ {$DEFINE UseSRCResample}
+{$ENDIF}
+
+// projectM config
+{$IF Defined(HaveProjectM)}
+ {$DEFINE UseProjectM}
+{$IFEND}
+
+// specify some useful defines
+
+{$IF Defined(UseFFmpegVideo) or Defined(UseFFmpegDecoder)}
+ {$DEFINE UseFFmpeg}
+{$IFEND}
+
+{$IF Defined(UseBASSInput) or Defined(UseBASSPlayback) or Defined(UseBASSDecoder)}
+ {$DEFINE UseBASS}
+{$IFEND}
+
+{$IF Defined(UsePortaudioInput) or Defined(UsePortaudioPlayback)}
+ {$DEFINE UsePortaudio}
+{$IFEND}
diff --git a/src/ultrastardx.control b/src/ultrastardx.control
new file mode 100644
index 00000000..a1bb17f0
--- /dev/null
+++ b/src/ultrastardx.control
@@ -0,0 +1,19 @@
+Package: ultrastardx
+Priority: optional
+Section: games
+Installed-Size: 18400
+Maintainer: Jay Binks
+Architecture: i386
+Version: 1.1.1
+Depends: libc6 (>= 2.1), libsdl1.2debian-alsa, libportaudio2, libavcodec1d, libavformat1d, libsqlite3-0, libsdl-ttf2.0-0, libsdl-image1.2
+Description:
+ Karaoke Software for PC like Singstar for PS2.
+ It evaluates your singing by analyzing your voice pitch.
+ Songs can be created with integrated Editor.
+ .
+ This is a Fork of the UltraStar Project with many massive improvements.
+ .
+ http://www.ultrastardeluxe.org/
+
+
+
diff --git a/src/ultrastardx.desktop b/src/ultrastardx.desktop
new file mode 100644
index 00000000..d49f05ef
--- /dev/null
+++ b/src/ultrastardx.desktop
@@ -0,0 +1,17 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+
+Name=UltraStar Deluxe
+Comment=Karaoke program that evaluates your performance
+Comment[de]=Singe Karaoke und messe dich mit anderen Spielern
+
+Icon=ultrastardx
+
+TryExec=ultrastardx
+Exec=ultrastardx
+StartupNotify=false
+Terminal=false
+
+Type=Application
+Categories=Application;Game;ArcadeGame;
--
cgit v1.2.3