From 959831f4ef5a3e797f576c3de08cd65032c997ad Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 18:54:10 +1000 Subject: Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard. --- .../examples/21.Quake3Explorer/Makefile | 76 +- .../examples/21.Quake3Explorer/Quake3Explorer.dev | 198 +- .../21.Quake3Explorer/Quake3Explorer.vcproj | 264 +- .../21.Quake3Explorer/Quake3Explorer_vc10.vcxproj | 390 +- .../21.Quake3Explorer/Quake3Explorer_vc11.vcxproj | 398 +- .../21.Quake3Explorer/Quake3Explorer_vc8.vcproj | 420 +- .../21.Quake3Explorer/Quake3Explorer_vc9.vcproj | 408 +- .../examples/21.Quake3Explorer/main.cpp | 4356 ++++++++++---------- .../examples/21.Quake3Explorer/q3factory.cpp | 1648 ++++---- .../examples/21.Quake3Explorer/q3factory.h | 298 +- .../examples/21.Quake3Explorer/sound.cpp | 196 +- .../examples/21.Quake3Explorer/sound.h | 36 +- 12 files changed, 4344 insertions(+), 4344 deletions(-) (limited to 'libraries/irrlicht-1.8/examples/21.Quake3Explorer') diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Makefile b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Makefile index b2c6927..f714782 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Makefile +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Makefile @@ -1,38 +1,38 @@ -# Makefile for Irrlicht Examples -# It's usually sufficient to change just the target name and source file list -# and be sure that CXX is set to a valid compiler -Target = 21.Quake3Explorer -Sources = main.cpp sound.cpp q3factory.cpp - -# general compiler settings -CPPFLAGS = -I../../include -I/usr/X11R6/include -#CXXFLAGS = -O3 -ffast-math -CXXFLAGS = -g -Wall - -#default target is Linux -all: all_linux - -ifeq ($(HOSTTYPE), x86_64) -LIBSELECT=64 -endif - -# target specific settings -all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -all_linux clean_linux: SYSTEM=Linux -all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm -all_win32 clean_win32: SYSTEM=Win32-gcc -all_win32 clean_win32: SUF=.exe -# name of the binary - only valid for targets which set SYSTEM -DESTPATH = ../../bin/$(SYSTEM)/$(Target)$(SUF) - -all_linux all_win32: - $(warning Building...) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS) - -clean: clean_linux clean_win32 - $(warning Cleaning...) - -clean_linux clean_win32: - @$(RM) $(DESTPATH) - -.PHONY: all all_win32 clean clean_linux clean_win32 +# Makefile for Irrlicht Examples +# It's usually sufficient to change just the target name and source file list +# and be sure that CXX is set to a valid compiler +Target = 21.Quake3Explorer +Sources = main.cpp sound.cpp q3factory.cpp + +# general compiler settings +CPPFLAGS = -I../../include -I/usr/X11R6/include +#CXXFLAGS = -O3 -ffast-math +CXXFLAGS = -g -Wall + +#default target is Linux +all: all_linux + +ifeq ($(HOSTTYPE), x86_64) +LIBSELECT=64 +endif + +# target specific settings +all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor +all_linux clean_linux: SYSTEM=Linux +all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm +all_win32 clean_win32: SYSTEM=Win32-gcc +all_win32 clean_win32: SUF=.exe +# name of the binary - only valid for targets which set SYSTEM +DESTPATH = ../../bin/$(SYSTEM)/$(Target)$(SUF) + +all_linux all_win32: + $(warning Building...) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS) + +clean: clean_linux clean_win32 + $(warning Cleaning...) + +clean_linux clean_win32: + @$(RM) $(DESTPATH) + +.PHONY: all all_win32 clean clean_linux clean_win32 diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.dev b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.dev index 193c6bd..b943f81 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.dev +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.dev @@ -1,99 +1,99 @@ -[Project] -FileName=Quake3Explorer.dev -Name=Irrlicht Example 21 Quake3 Explorer -UnitCount=5 -Type=1 -Ver=1 -ObjFiles= -Includes=..\..\include -Libs= -PrivateResource= -ResourceIncludes= -MakeIncludes= -Compiler= -CppCompiler= -Linker=../../lib/Win32-gcc/libIrrlicht.a_@@_ -IsCpp=1 -Icon= -ExeOutput=../../bin/Win32-gcc -ObjectOutput=obj -OverrideOutput=1 -OverrideOutputName=21.Quake3Explorer.exe -HostApplication= -Folders= -CommandLine= -IncludeVersionInfo=0 -SupportXPThemes=0 -CompilerSet=0 -CompilerSettings=0000000000000000000000 -UseCustomMakefile=0 -CustomMakefile= - -[Unit1] -FileName=main.cpp -CompileCpp=1 -Folder=Projekt1 -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[VersionInfo] -Major=0 -Minor=1 -Release=1 -Build=1 -LanguageID=1033 -CharsetID=1252 -CompanyName= -FileVersion= -FileDescription=Irrlicht Engine example compiled using DevCpp and gcc -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion= -AutoIncBuildNr=0 - -[Unit2] -FileName=q3factory.cpp -CompileCpp=1 -Folder=Irrlicht Example 21 Quake3 Explorer -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit3] -FileName=q3factory.h -CompileCpp=1 -Folder=Irrlicht Example 21 Quake3 Explorer -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit4] -FileName=sound.cpp -CompileCpp=1 -Folder=Irrlicht Example 21 Quake3 Explorer -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit5] -FileName=sound.h -CompileCpp=1 -Folder=Irrlicht Example 21 Quake3 Explorer -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - +[Project] +FileName=Quake3Explorer.dev +Name=Irrlicht Example 21 Quake3 Explorer +UnitCount=5 +Type=1 +Ver=1 +ObjFiles= +Includes=..\..\include +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker=../../lib/Win32-gcc/libIrrlicht.a_@@_ +IsCpp=1 +Icon= +ExeOutput=../../bin/Win32-gcc +ObjectOutput=obj +OverrideOutput=1 +OverrideOutputName=21.Quake3Explorer.exe +HostApplication= +Folders= +CommandLine= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 +UseCustomMakefile=0 +CustomMakefile= + +[Unit1] +FileName=main.cpp +CompileCpp=1 +Folder=Projekt1 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Irrlicht Engine example compiled using DevCpp and gcc +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit2] +FileName=q3factory.cpp +CompileCpp=1 +Folder=Irrlicht Example 21 Quake3 Explorer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=q3factory.h +CompileCpp=1 +Folder=Irrlicht Example 21 Quake3 Explorer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=sound.cpp +CompileCpp=1 +Folder=Irrlicht Example 21 Quake3 Explorer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=sound.h +CompileCpp=1 +Folder=Irrlicht Example 21 Quake3 Explorer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.vcproj b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.vcproj index b869cc4..dcd4561 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.vcproj +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer.vcproj @@ -1,132 +1,132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc10.vcxproj b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc10.vcxproj index 8ba3e72..1fe4cc8 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc10.vcxproj +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc10.vcxproj @@ -1,196 +1,196 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - 21.Quake3Explorer - {CDC4AAA9-72E1-4FFA-A04D-7EF59D8B97CD} - 21.Quake3Explorer - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\Win32-VisualStudio\ - ..\..\bin\Win64-VisualStudio\ - true - true - ..\..\bin\Win32-VisualStudio\ - ..\..\bin\Win64-VisualStudio\ - false - false - AllRules.ruleset - AllRules.ruleset - - - - - AllRules.ruleset - AllRules.ruleset - - - - - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - EditAndContinue - - - ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) - true - $(OutDir)Quake3MapShader.pdb - Console - - - - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - Level3 - ProgramDatabase - - - ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) - true - $(OutDir)Quake3MapShader.pdb - Console - - - - - - - true - Speed - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - false - - - Level3 - - - FastCall - - - ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) - false - Console - true - true - - - - - - - true - Speed - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - false - - - Level3 - - - FastCall - - - ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) - false - Console - true - true - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 21.Quake3Explorer + {CDC4AAA9-72E1-4FFA-A04D-7EF59D8B97CD} + 21.Quake3Explorer + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + true + true + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)Quake3MapShader.pdb + Console + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)Quake3MapShader.pdb + Console + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + + + Level3 + + + FastCall + + + ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + + + Level3 + + + FastCall + + + ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc11.vcxproj b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc11.vcxproj index d0c29b2..a5229f7 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc11.vcxproj +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc11.vcxproj @@ -1,200 +1,200 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - 21.Quake3Explorer - {CDC4AAA9-72E1-4FFA-A04D-7EF59D8B97CD} - 21.Quake3Explorer - Win32Proj - - - - Application - MultiByte - v110 - - - Application - MultiByte - v110 - - - Application - MultiByte - v110 - - - Application - MultiByte - v110 - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\Win32-VisualStudio\ - ..\..\bin\Win64-VisualStudio\ - true - true - ..\..\bin\Win32-VisualStudio\ - ..\..\bin\Win64-VisualStudio\ - false - false - AllRules.ruleset - AllRules.ruleset - - - - - AllRules.ruleset - AllRules.ruleset - - - - - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - EditAndContinue - - - ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) - true - $(OutDir)Quake3MapShader.pdb - Console - - - - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - Level3 - ProgramDatabase - - - ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) - true - $(OutDir)Quake3MapShader.pdb - Console - - - - - - - true - Speed - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - false - - - Level3 - - - FastCall - - - ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) - false - Console - true - true - - - - - - - true - Speed - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - false - - - Level3 - - - FastCall - - - ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe - ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) - false - Console - true - true - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 21.Quake3Explorer + {CDC4AAA9-72E1-4FFA-A04D-7EF59D8B97CD} + 21.Quake3Explorer + Win32Proj + + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + true + true + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)Quake3MapShader.pdb + Console + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + $(OutDir)Quake3MapShader.pdb + Console + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + + + Level3 + + + FastCall + + + ..\..\bin\Win32-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + true + Speed + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + false + + + Level3 + + + FastCall + + + ..\..\bin\Win64-VisualStudio\21.Quake3Explorer.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + false + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc8.vcproj b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc8.vcproj index 9045027..2b13531 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc8.vcproj +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc8.vcproj @@ -1,210 +1,210 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc9.vcproj b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc9.vcproj index 36aee41..4975a6c 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc9.vcproj +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/Quake3Explorer_vc9.vcproj @@ -1,204 +1,204 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/main.cpp b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/main.cpp index fdcdd03..4d41e1c 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/main.cpp +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/main.cpp @@ -1,2178 +1,2178 @@ -/** Example 021 Quake3 Explorer - -This Tutorial shows how to load different Quake 3 maps. - -Features: - - Load BSP Archives at Runtime from the menu - - Load a Map from the menu. Showing with Screenshot - - Set the VideoDriver at runtime from menu - - Adjust GammaLevel at runtime - - Create SceneNodes for the Shaders - - Load EntityList and create Entity SceneNodes - - Create Players with Weapons and with Collision Response - - Play music - -You can download the Quake III Arena demo ( copyright id software ) -at the following location: -ftp://ftp.idsoftware.com/idstuff/quake3/win32/q3ademo.exe - -Copyright 2006-2011 Burningwater, Thomas Alten -*/ - -#include "driverChoice.h" -#include -#include "q3factory.h" -#include "sound.h" - -/* - Game Data is used to hold Data which is needed to drive the game -*/ -struct GameData -{ - GameData ( const path &startupDir) : - retVal(0), StartupDir(startupDir), createExDevice(0), Device(0) - { - setDefault (); - } - - void setDefault (); - s32 save ( const path &filename ); - s32 load ( const path &filename ); - - s32 debugState; - s32 gravityState; - s32 flyTroughState; - s32 wireFrame; - s32 guiActive; - s32 guiInputActive; - f32 GammaValue; - s32 retVal; - s32 sound; - - path StartupDir; - stringw CurrentMapName; - array CurrentArchiveList; - - vector3df PlayerPosition; - vector3df PlayerRotation; - - tQ3EntityList Variable; - - Q3LevelLoadParameter loadParam; - SIrrlichtCreationParameters deviceParam; - funcptr_createDeviceEx createExDevice; - IrrlichtDevice *Device; -}; - -/* - set default settings -*/ -void GameData::setDefault () -{ - debugState = EDS_OFF; - gravityState = 1; - flyTroughState = 0; - wireFrame = 0; - guiActive = 1; - guiInputActive = 0; - GammaValue = 1.f; - - // default deviceParam; -#if defined ( _IRR_WINDOWS_ ) - deviceParam.DriverType = EDT_DIRECT3D9; -#else - deviceParam.DriverType = EDT_OPENGL; -#endif - deviceParam.WindowSize.Width = 800; - deviceParam.WindowSize.Height = 600; - deviceParam.Fullscreen = false; - deviceParam.Bits = 24; - deviceParam.ZBufferBits = 16; - deviceParam.Vsync = false; - deviceParam.AntiAlias = false; - - // default Quake3 loadParam - loadParam.defaultLightMapMaterial = EMT_LIGHTMAP; - loadParam.defaultModulate = EMFN_MODULATE_1X; - loadParam.defaultFilter = EMF_ANISOTROPIC_FILTER; - loadParam.verbose = 2; - loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material - loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture - loadParam.loadAllShaders = 1; // load all scripts in the script directory - loadParam.loadSkyShader = 0; // load sky Shader - loadParam.alpharef = 1; - - sound = 0; - - CurrentMapName = ""; - CurrentArchiveList.clear (); - - // Explorer Media directory - CurrentArchiveList.push_back ( StartupDir + "../../media/" ); - - // Add the original quake3 files before you load your custom map - // Most mods are using the original shaders, models&items&weapons - CurrentArchiveList.push_back("/q/baseq3/"); - - CurrentArchiveList.push_back(StartupDir + "../../media/map-20kdm2.pk3"); -} - -/* - Load the current game State from a typical quake3 cfg file -*/ -s32 GameData::load ( const path &filename ) -{ - if (!Device) - return 0; - - // the quake3 mesh loader can also handle *.shader and *.cfg file - IQ3LevelMesh* mesh = (IQ3LevelMesh*) Device->getSceneManager()->getMesh ( filename ); - if (!mesh) - return 0; - - tQ3EntityList &entityList = mesh->getEntityList (); - - stringc s; - u32 pos; - - for ( u32 e = 0; e != entityList.size (); ++e ) - { - //dumpShader ( s, &entityList[e], false ); - //printf ( s.c_str () ); - - for ( u32 g = 0; g != entityList[e].getGroupSize (); ++g ) - { - const SVarGroup *group = entityList[e].getGroup ( g ); - - for ( u32 index = 0; index < group->Variable.size (); ++index ) - { - const SVariable &v = group->Variable[index]; - pos = 0; - if ( v.name == "playerposition" ) - { - PlayerPosition = getAsVector3df ( v.content, pos ); - } - else - if ( v.name == "playerrotation" ) - { - PlayerRotation = getAsVector3df ( v.content, pos ); - } - } - } - } - - return 1; -} - -/* - Store the current game State in a quake3 configuration file -*/ -s32 GameData::save ( const path &filename ) -{ - return 0; - if (!Device) - return 0; - - c8 buf[128]; - u32 i; - - // Store current Archive for restart - CurrentArchiveList.clear(); - IFileSystem *fs = Device->getFileSystem(); - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - CurrentArchiveList.push_back ( fs->getFileArchive(i)->getFileList()->getPath() ); - } - - // Store Player Position and Rotation - ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera (); - if ( camera ) - { - PlayerPosition = camera->getPosition (); - PlayerRotation = camera->getRotation (); - } - - IWriteFile *file = fs->createAndWriteFile ( filename ); - if (!file) - return 0; - - snprintf ( buf, 128, "playerposition %.f %.f %.f\nplayerrotation %.f %.f %.f\n", - PlayerPosition.X, PlayerPosition.Z, PlayerPosition.Y, - PlayerRotation.X, PlayerRotation.Z, PlayerRotation.Y); - file->write ( buf, (s32) strlen ( buf ) ); - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - snprintf ( buf, 128, "archive %s\n",stringc ( fs->getFileArchive(i)->getFileList()->getPath() ).c_str () ); - file->write ( buf, (s32) strlen ( buf ) ); - } - - file->drop (); - return 1; -} - -/* - Representing a player -*/ -struct Q3Player : public IAnimationEndCallBack -{ - Q3Player () - : Device(0), MapParent(0), Mesh(0), WeaponNode(0), StartPositionCurrent(0) - { - animation[0] = 0; - memset(Anim, 0, sizeof(TimeFire)*4); - } - - virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node); - - void create ( IrrlichtDevice *device, - IQ3LevelMesh* mesh, - ISceneNode *mapNode, - IMetaTriangleSelector *meta - ); - void shutdown (); - void setAnim ( const c8 *name ); - void respawn (); - void setpos ( const vector3df &pos, const vector3df& rotation ); - - ISceneNodeAnimatorCollisionResponse * cam() { return camCollisionResponse ( Device ); } - - IrrlichtDevice *Device; - ISceneNode* MapParent; - IQ3LevelMesh* Mesh; - IAnimatedMeshSceneNode* WeaponNode; - s32 StartPositionCurrent; - TimeFire Anim[4]; - c8 animation[64]; - c8 buf[64]; -}; - - -/* End player -*/ -void Q3Player::shutdown () -{ - setAnim ( 0 ); - - dropElement (WeaponNode); - - if ( Device ) - { - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - dropElement ( camera ); - Device = 0; - } - - MapParent = 0; - Mesh = 0; -} - - -/* create a new player -*/ -void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *mapNode, IMetaTriangleSelector *meta ) -{ - setTimeFire ( Anim + 0, 200, FIRED ); - setTimeFire ( Anim + 1, 5000 ); - - if (!device) - return; - // load FPS weapon to Camera - Device = device; - Mesh = mesh; - MapParent = mapNode; - - ISceneManager *smgr = device->getSceneManager (); - IVideoDriver * driver = device->getVideoDriver(); - - ICameraSceneNode* camera = 0; - - SKeyMap keyMap[10]; - keyMap[0].Action = EKA_MOVE_FORWARD; - keyMap[0].KeyCode = KEY_UP; - keyMap[1].Action = EKA_MOVE_FORWARD; - keyMap[1].KeyCode = KEY_KEY_W; - - keyMap[2].Action = EKA_MOVE_BACKWARD; - keyMap[2].KeyCode = KEY_DOWN; - keyMap[3].Action = EKA_MOVE_BACKWARD; - keyMap[3].KeyCode = KEY_KEY_S; - - keyMap[4].Action = EKA_STRAFE_LEFT; - keyMap[4].KeyCode = KEY_LEFT; - keyMap[5].Action = EKA_STRAFE_LEFT; - keyMap[5].KeyCode = KEY_KEY_A; - - keyMap[6].Action = EKA_STRAFE_RIGHT; - keyMap[6].KeyCode = KEY_RIGHT; - keyMap[7].Action = EKA_STRAFE_RIGHT; - keyMap[7].KeyCode = KEY_KEY_D; - - keyMap[8].Action = EKA_JUMP_UP; - keyMap[8].KeyCode = KEY_KEY_J; - - keyMap[9].Action = EKA_CROUCH; - keyMap[9].KeyCode = KEY_KEY_C; - - camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 0.6f); - camera->setName ( "First Person Camera" ); - //camera->setFOV ( 100.f * core::DEGTORAD ); - camera->setFarValue( 20000.f ); - - IAnimatedMeshMD2* weaponMesh = (IAnimatedMeshMD2*) smgr->getMesh("gun.md2"); - if ( 0 == weaponMesh ) - return; - - if ( weaponMesh->getMeshType() == EAMT_MD2 ) - { - s32 count = weaponMesh->getAnimationCount(); - for ( s32 i = 0; i != count; ++i ) - { - snprintf ( buf, 64, "Animation: %s", weaponMesh->getAnimationName(i) ); - device->getLogger()->log(buf, ELL_INFORMATION); - } - } - - WeaponNode = smgr->addAnimatedMeshSceneNode( - weaponMesh, - smgr->getActiveCamera(), - 10, - vector3df( 0, 0, 0), - vector3df(-90,-90,90) - ); - WeaponNode->setMaterialFlag(EMF_LIGHTING, false); - WeaponNode->setMaterialTexture(0, driver->getTexture( "gun.jpg")); - WeaponNode->setLoopMode ( false ); - WeaponNode->setName ( "tommi the gun man" ); - - //create a collision auto response animator - ISceneNodeAnimator* anim = - smgr->createCollisionResponseAnimator( meta, camera, - vector3df(30,45,30), - getGravity ( "earth" ), - vector3df(0,40,0), - 0.0005f - ); - - camera->addAnimator( anim ); - anim->drop(); - - if ( meta ) - { - meta->drop (); - } - - respawn (); - setAnim ( "idle" ); -} - - -/* - so we need a good starting Position in the level. - we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" -*/ -void Q3Player::respawn () -{ - if (!Device) - return; - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - - Device->getLogger()->log( "respawn" ); - - if ( StartPositionCurrent >= Q3StartPosition ( - Mesh, camera,StartPositionCurrent++, - cam ()->getEllipsoidTranslation() ) - ) - { - StartPositionCurrent = 0; - } -} - -/* - set Player position from saved coordinates -*/ -void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation ) -{ - if (!Device) - return; - Device->getLogger()->log( "setpos" ); - - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - if ( camera ) - { - camera->setPosition ( pos ); - camera->setRotation ( rotation ); - //! New. FPSCamera and animators catches reset on animate 0 - camera->OnAnimate ( 0 ); - } -} - -/* set the Animation of the player and weapon -*/ -void Q3Player::setAnim ( const c8 *name ) -{ - if ( name ) - { - snprintf ( animation, 64, "%s", name ); - if ( WeaponNode ) - { - WeaponNode->setAnimationEndCallback ( this ); - WeaponNode->setMD2Animation ( animation ); - } - } - else - { - animation[0] = 0; - if ( WeaponNode ) - { - WeaponNode->setAnimationEndCallback ( 0 ); - } - } -} - - -// Callback -void Q3Player::OnAnimationEnd(IAnimatedMeshSceneNode* node) -{ - setAnim ( 0 ); -} - - - -/* GUI Elements -*/ -struct GUI -{ - GUI () - { - memset ( this, 0, sizeof ( *this ) ); - } - - void drop() - { - dropElement ( Window ); - dropElement ( Logo ); - } - - IGUIComboBox* VideoDriver; - IGUIComboBox* VideoMode; - IGUICheckBox* FullScreen; - IGUICheckBox* Bit32; - IGUIScrollBar* MultiSample; - IGUIButton* SetVideoMode; - - IGUIScrollBar* Tesselation; - IGUIScrollBar* Gamma; - IGUICheckBox* Collision; - IGUICheckBox* Visible_Map; - IGUICheckBox* Visible_Shader; - IGUICheckBox* Visible_Fog; - IGUICheckBox* Visible_Unresolved; - IGUICheckBox* Visible_Skydome; - IGUIButton* Respawn; - - IGUITable* ArchiveList; - IGUIButton* ArchiveAdd; - IGUIButton* ArchiveRemove; - IGUIFileOpenDialog* ArchiveFileOpen; - IGUIButton* ArchiveUp; - IGUIButton* ArchiveDown; - - IGUIListBox* MapList; - IGUITreeView* SceneTree; - IGUIStaticText* StatusLine; - IGUIImage* Logo; - IGUIWindow* Window; -}; - - -/* - CQuake3EventHandler controls the game -*/ -class CQuake3EventHandler : public IEventReceiver -{ -public: - - CQuake3EventHandler( GameData *gameData ); - virtual ~CQuake3EventHandler (); - - void Animate(); - void Render(); - - void AddArchive ( const path& archiveName ); - void LoadMap ( const stringw& mapName, s32 collision ); - void CreatePlayers(); - void AddSky( u32 dome, const c8 *texture ); - Q3Player *GetPlayer ( u32 index ) { return &Player[index]; } - - void CreateGUI(); - void SetGUIActive( s32 command); - - bool OnEvent(const SEvent& eve); - - -private: - - GameData *Game; - - IQ3LevelMesh* Mesh; - ISceneNode* MapParent; - ISceneNode* ShaderParent; - ISceneNode* ItemParent; - ISceneNode* UnresolvedParent; - ISceneNode* BulletParent; - ISceneNode* FogParent; - ISceneNode * SkyNode; - IMetaTriangleSelector *Meta; - - c8 buf[256]; - - Q3Player Player[2]; - - struct SParticleImpact - { - u32 when; - vector3df pos; - vector3df outVector; - }; - array Impacts; - void useItem( Q3Player * player); - void createParticleImpacts( u32 now ); - - void createTextures (); - void addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent); - - GUI gui; - void dropMap (); -}; - -/* Constructor -*/ -CQuake3EventHandler::CQuake3EventHandler( GameData *game ) -: Game(game), Mesh(0), MapParent(0), ShaderParent(0), ItemParent(0), UnresolvedParent(0), - BulletParent(0), FogParent(0), SkyNode(0), Meta(0) -{ - buf[0]=0; - // Also use 16 Bit Textures for 16 Bit RenderDevice - if ( Game->deviceParam.Bits == 16 ) - { - game->Device->getVideoDriver()->setTextureCreationFlag(ETCF_ALWAYS_16_BIT, true); - } - - // Quake3 Shader controls Z-Writing - game->Device->getSceneManager()->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); - - // create internal textures - createTextures (); - - sound_init ( game->Device ); - - Game->Device->setEventReceiver ( this ); -} - - -// destructor -CQuake3EventHandler::~CQuake3EventHandler () -{ - Player[0].shutdown (); - sound_shutdown (); - - Game->save( "explorer.cfg" ); - - Game->Device->drop(); -} - - -// create runtime textures smog, fog -void CQuake3EventHandler::createTextures() -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - - dimension2du dim(64, 64); - - video::IImage* image; - u32 i; - u32 x; - u32 y; - u32 * data; - for ( i = 0; i != 8; ++i ) - { - image = driver->createImage ( video::ECF_A8R8G8B8, dim); - data = (u32*) image->lock (); - for ( y = 0; y != dim.Height; ++y ) - { - for ( x = 0; x != dim.Width; ++x ) - { - data [x] = 0xFFFFFFFF; - } - data = (u32*) ( (u8*) data + image->getPitch() ); - } - image->unlock(); - snprintf ( buf, 64, "smoke_%02d", i ); - driver->addTexture( buf, image ); - image->drop (); - } - - // fog - for ( i = 0; i != 1; ++i ) - { - image = driver->createImage ( video::ECF_A8R8G8B8, dim); - data = (u32*) image->lock (); - for ( y = 0; y != dim.Height; ++y ) - { - for ( x = 0; x != dim.Width; ++x ) - { - data [x] = 0xFFFFFFFF; - } - data = (u32*) ( (u8*) data + image->getPitch() ); - } - image->unlock(); - snprintf ( buf, 64, "fog_%02d", i ); - driver->addTexture( buf, image ); - image->drop (); - } -} - - -/* - create the GUI -*/ -void CQuake3EventHandler::CreateGUI() -{ - - IGUIEnvironment *env = Game->Device->getGUIEnvironment(); - IVideoDriver * driver = Game->Device->getVideoDriver(); - - gui.drop(); - - // set skin font - IGUIFont* font = env->getFont("fontlucida.png"); - if (font) - env->getSkin()->setFont(font); - env->getSkin()->setColor ( EGDC_BUTTON_TEXT, video::SColor(240,0xAA,0xAA,0xAA) ); - env->getSkin()->setColor ( EGDC_3D_HIGH_LIGHT, video::SColor(240,0x22,0x22,0x22) ); - env->getSkin()->setColor ( EGDC_3D_FACE, video::SColor(240,0x44,0x44,0x44) ); - env->getSkin()->setColor ( EGDC_EDITABLE, video::SColor(240,0x44,0x44,0x44) ); - env->getSkin()->setColor ( EGDC_FOCUSED_EDITABLE, video::SColor(240,0x54,0x54,0x54) ); - env->getSkin()->setColor ( EGDC_WINDOW, video::SColor(240,0x66,0x66,0x66) ); - - // minimal gui size 800x600 - dimension2d dim ( 800, 600 ); - dimension2d vdim ( Game->Device->getVideoDriver()->getScreenSize() ); - - if ( vdim.Height >= dim.Height && vdim.Width >= dim.Width ) - { - //dim = vdim; - } - else - { - } - - gui.Window = env->addWindow ( rect ( 0, 0, dim.Width, dim.Height ), false, L"Quake3 Explorer" ); - gui.Window->setToolTipText ( L"Quake3Explorer. Loads and show various BSP File Format and Shaders." ); - gui.Window->getCloseButton()->setToolTipText ( L"Quit Quake3 Explorer" ); - - // add a status line help text - gui.StatusLine = env->addStaticText( 0, rect( 5,dim.Height - 30,dim.Width - 5,dim.Height - 10), - false, false, gui.Window, -1, true - ); - - - env->addStaticText ( L"VideoDriver:", rect( dim.Width - 400, 24, dim.Width - 310, 40 ),false, false, gui.Window, -1, false ); - gui.VideoDriver = env->addComboBox(rect( dim.Width - 300, 24, dim.Width - 10, 40 ),gui.Window); - gui.VideoDriver->addItem(L"Direct3D 9.0c", EDT_DIRECT3D9 ); - gui.VideoDriver->addItem(L"Direct3D 8.1", EDT_DIRECT3D8 ); - gui.VideoDriver->addItem(L"OpenGL 1.5", EDT_OPENGL); - gui.VideoDriver->addItem(L"Software Renderer", EDT_SOFTWARE); - gui.VideoDriver->addItem(L"Burning's Video (TM) Thomas Alten", EDT_BURNINGSVIDEO); - gui.VideoDriver->setSelected ( gui.VideoDriver->getIndexForItemData ( Game->deviceParam.DriverType ) ); - gui.VideoDriver->setToolTipText ( L"Use a VideoDriver" ); - - env->addStaticText ( L"VideoMode:", rect( dim.Width - 400, 44, dim.Width - 310, 60 ),false, false, gui.Window, -1, false ); - gui.VideoMode = env->addComboBox(rect( dim.Width - 300, 44, dim.Width - 10, 60 ),gui.Window); - gui.VideoMode->setToolTipText ( L"Supported Screenmodes" ); - IVideoModeList *modeList = Game->Device->getVideoModeList(); - if ( modeList ) - { - s32 i; - for ( i = 0; i != modeList->getVideoModeCount (); ++i ) - { - u16 d = modeList->getVideoModeDepth ( i ); - if ( d < 16 ) - continue; - - u16 w = modeList->getVideoModeResolution ( i ).Width; - u16 h = modeList->getVideoModeResolution ( i ).Height; - u32 val = w << 16 | h; - - if ( gui.VideoMode->getIndexForItemData ( val ) >= 0 ) - continue; - - f32 aspect = (f32) w / (f32) h; - const c8 *a = ""; - if ( core::equals ( aspect, 1.3333333333f ) ) a = "4:3"; - else if ( core::equals ( aspect, 1.6666666f ) ) a = "15:9 widescreen"; - else if ( core::equals ( aspect, 1.7777777f ) ) a = "16:9 widescreen"; - else if ( core::equals ( aspect, 1.6f ) ) a = "16:10 widescreen"; - else if ( core::equals ( aspect, 2.133333f ) ) a = "20:9 widescreen"; - - snprintf ( buf, sizeof ( buf ), "%d x %d, %s",w, h, a ); - gui.VideoMode->addItem ( stringw ( buf ).c_str(), val ); - } - } - gui.VideoMode->setSelected ( gui.VideoMode->getIndexForItemData ( - Game->deviceParam.WindowSize.Width << 16 | - Game->deviceParam.WindowSize.Height ) ); - - gui.FullScreen = env->addCheckBox ( Game->deviceParam.Fullscreen, rect( dim.Width - 400, 64, dim.Width - 300, 80 ), gui.Window,-1, L"Fullscreen" ); - gui.FullScreen->setToolTipText ( L"Set Fullscreen or Window Mode" ); - - gui.Bit32 = env->addCheckBox ( Game->deviceParam.Bits == 32, rect( dim.Width - 300, 64, dim.Width - 240, 80 ), gui.Window,-1, L"32Bit" ); - gui.Bit32->setToolTipText ( L"Use 16 or 32 Bit" ); - - env->addStaticText ( L"MultiSample:", rect( dim.Width - 235, 64, dim.Width - 150, 80 ),false, false, gui.Window, -1, false ); - gui.MultiSample = env->addScrollBar( true, rect( dim.Width - 150, 64, dim.Width - 70, 80 ), gui.Window,-1 ); - gui.MultiSample->setMin ( 0 ); - gui.MultiSample->setMax ( 8 ); - gui.MultiSample->setSmallStep ( 1 ); - gui.MultiSample->setLargeStep ( 1 ); - gui.MultiSample->setPos ( Game->deviceParam.AntiAlias ); - gui.MultiSample->setToolTipText ( L"Set the MultiSample (disable, 1x, 2x, 4x, 8x )" ); - - gui.SetVideoMode = env->addButton (rect( dim.Width - 60, 64, dim.Width - 10, 80 ), gui.Window, -1,L"set" ); - gui.SetVideoMode->setToolTipText ( L"Set Video Mode with current values" ); - - env->addStaticText ( L"Gamma:", rect( dim.Width - 400, 104, dim.Width - 310, 120 ),false, false, gui.Window, -1, false ); - gui.Gamma = env->addScrollBar( true, rect( dim.Width - 300, 104, dim.Width - 10, 120 ), gui.Window,-1 ); - gui.Gamma->setMin ( 50 ); - gui.Gamma->setMax ( 350 ); - gui.Gamma->setSmallStep ( 1 ); - gui.Gamma->setLargeStep ( 10 ); - gui.Gamma->setPos ( core::floor32 ( Game->GammaValue * 100.f ) ); - gui.Gamma->setToolTipText ( L"Adjust Gamma Ramp ( 0.5 - 3.5)" ); - Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); - - - env->addStaticText ( L"Tesselation:", rect( dim.Width - 400, 124, dim.Width - 310, 140 ),false, false, gui.Window, -1, false ); - gui.Tesselation = env->addScrollBar( true, rect( dim.Width - 300, 124, dim.Width - 10, 140 ), gui.Window,-1 ); - gui.Tesselation->setMin ( 2 ); - gui.Tesselation->setMax ( 12 ); - gui.Tesselation->setSmallStep ( 1 ); - gui.Tesselation->setLargeStep ( 1 ); - gui.Tesselation->setPos ( Game->loadParam.patchTesselation ); - gui.Tesselation->setToolTipText ( L"How smooth should curved surfaces be rendered" ); - - gui.Collision = env->addCheckBox ( true, rect( dim.Width - 400, 150, dim.Width - 300, 166 ), gui.Window,-1, L"Collision" ); - gui.Collision->setToolTipText ( L"Set collision on or off ( flythrough ). \nPress F7 on your Keyboard" ); - gui.Visible_Map = env->addCheckBox ( true, rect( dim.Width - 300, 150, dim.Width - 240, 166 ), gui.Window,-1, L"Map" ); - gui.Visible_Map->setToolTipText ( L"Show or not show the static part the Level. \nPress F3 on your Keyboard" ); - gui.Visible_Shader = env->addCheckBox ( true, rect( dim.Width - 240, 150, dim.Width - 170, 166 ), gui.Window,-1, L"Shader" ); - gui.Visible_Shader->setToolTipText ( L"Show or not show the Shader Nodes. \nPress F4 on your Keyboard" ); - gui.Visible_Fog = env->addCheckBox ( true, rect( dim.Width - 170, 150, dim.Width - 110, 166 ), gui.Window,-1, L"Fog" ); - gui.Visible_Fog->setToolTipText ( L"Show or not show the Fog Nodes. \nPress F5 on your Keyboard" ); - gui.Visible_Unresolved = env->addCheckBox ( true, rect( dim.Width - 110, 150, dim.Width - 10, 166 ), gui.Window,-1, L"Unresolved" ); - gui.Visible_Unresolved->setToolTipText ( L"Show the or not show the Nodes the Engine can't handle. \nPress F6 on your Keyboard" ); - gui.Visible_Skydome = env->addCheckBox ( true, rect( dim.Width - 110, 180, dim.Width - 10, 196 ), gui.Window,-1, L"Skydome" ); - gui.Visible_Skydome->setToolTipText ( L"Show the or not show the Skydome." ); - - //Respawn = env->addButton ( rect( dim.Width - 260, 90, dim.Width - 10, 106 ), 0,-1, L"Respawn" ); - - env->addStaticText ( L"Archives:", rect( 5, dim.Height - 530, dim.Width - 600,dim.Height - 514 ),false, false, gui.Window, -1, false ); - - gui.ArchiveAdd = env->addButton ( rect( dim.Width - 725, dim.Height - 530, dim.Width - 665, dim.Height - 514 ), gui.Window,-1, L"add" ); - gui.ArchiveAdd->setToolTipText ( L"Add an archive, usually packed zip-archives (*.pk3) to the Filesystem" ); - gui.ArchiveRemove = env->addButton ( rect( dim.Width - 660, dim.Height - 530, dim.Width - 600, dim.Height - 514 ), gui.Window,-1, L"del" ); - gui.ArchiveRemove->setToolTipText ( L"Remove the selected archive from the FileSystem." ); - gui.ArchiveUp = env->addButton ( rect( dim.Width - 575, dim.Height - 530, dim.Width - 515, dim.Height - 514 ), gui.Window,-1, L"up" ); - gui.ArchiveUp->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive up" ); - gui.ArchiveDown = env->addButton ( rect( dim.Width - 510, dim.Height - 530, dim.Width - 440, dim.Height - 514 ), gui.Window,-1, L"down" ); - gui.ArchiveDown->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive down" ); - - - gui.ArchiveList = env->addTable ( rect( 5,dim.Height - 510, dim.Width - 450,dim.Height - 410 ), gui.Window ); - gui.ArchiveList->addColumn ( L"Type", 0 ); - gui.ArchiveList->addColumn ( L"Real File Path", 1 ); - gui.ArchiveList->setColumnWidth ( 0, 60 ); - gui.ArchiveList->setColumnWidth ( 1, 284 ); - gui.ArchiveList->setToolTipText ( L"Show the attached Archives" ); - - - env->addStaticText ( L"Maps:", rect( 5, dim.Height - 400, dim.Width - 450,dim.Height - 380 ),false, false, gui.Window, -1, false ); - gui.MapList = env->addListBox ( rect( 5,dim.Height - 380, dim.Width - 450,dim.Height - 40 ), gui.Window, -1, true ); - gui.MapList->setToolTipText ( L"Show the current Maps in all Archives.\n Double-Click the Map to start the level" ); - - - // create a visible Scene Tree - env->addStaticText ( L"Scenegraph:", rect( dim.Width - 400, dim.Height - 400, dim.Width - 5,dim.Height - 380 ),false, false, gui.Window, -1, false ); - gui.SceneTree = env->addTreeView( rect( dim.Width - 400, dim.Height - 380, dim.Width - 5, dim.Height - 40 ), - gui.Window, -1, true, true, false ); - gui.SceneTree->setToolTipText ( L"Show the current Scenegraph" ); - gui.SceneTree->getRoot()->clearChildren(); - addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); - - - IGUIImageList* imageList = env->createImageList( driver->getTexture ( "iconlist.png" ), - dimension2di( 32, 32 ), true ); - - if ( imageList ) - { - gui.SceneTree->setImageList( imageList ); - imageList->drop (); - } - - - // load the engine logo - gui.Logo = env->addImage( driver->getTexture("irrlichtlogo3.png"), position2d(5, 16 ), true, 0 ); - gui.Logo->setToolTipText ( L"The great Irrlicht Engine" ); - - AddArchive ( "" ); -} - - -/* - Add an Archive to the FileSystems and updates the GUI -*/ -void CQuake3EventHandler::AddArchive ( const path& archiveName ) -{ - IFileSystem *fs = Game->Device->getFileSystem(); - u32 i; - - if ( archiveName.size () ) - { - bool exists = false; - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - if ( fs->getFileArchive(i)->getFileList()->getPath() == archiveName ) - { - exists = true; - break; - } - } - - if (!exists) - { - fs->addFileArchive(archiveName, true, false); - } - } - - // store the current archives in game data - // show the attached Archive in proper order - if ( gui.ArchiveList ) - { - gui.ArchiveList->clearRows(); - - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - IFileArchive * archive = fs->getFileArchive ( i ); - - u32 index = gui.ArchiveList->addRow(i); - - core::stringw typeName; - switch(archive->getType()) - { - case io::EFAT_ZIP: - typeName = "ZIP"; - break; - case io::EFAT_GZIP: - typeName = "gzip"; - break; - case io::EFAT_FOLDER: - typeName = "Mount"; - break; - case io::EFAT_PAK: - typeName = "PAK"; - break; - case io::EFAT_TAR: - typeName = "TAR"; - break; - default: - typeName = "archive"; - } - - gui.ArchiveList->setCellText ( index, 0, typeName ); - gui.ArchiveList->setCellText ( index, 1, archive->getFileList()->getPath() ); - } - } - - - // browse the archives for maps - if ( gui.MapList ) - { - gui.MapList->clear(); - - IGUISpriteBank *bank = Game->Device->getGUIEnvironment()->getSpriteBank("sprite_q3map"); - if ( 0 == bank ) - bank = Game->Device->getGUIEnvironment()->addEmptySpriteBank("sprite_q3map"); - - SGUISprite sprite; - SGUISpriteFrame frame; - core::rect r; - - bank->getSprites().clear(); - bank->getPositions().clear (); - gui.MapList->setSpriteBank ( bank ); - - u32 g = 0; - core::stringw s; - - // browse the attached file system - fs->setFileListSystem ( FILESYSTEM_VIRTUAL ); - fs->changeWorkingDirectoryTo ( "/maps/" ); - IFileList *fileList = fs->createFileList (); - fs->setFileListSystem ( FILESYSTEM_NATIVE ); - - for ( i=0; i< fileList->getFileCount(); ++i) - { - s = fileList->getFullFileName(i); - if ( s.find ( ".bsp" ) >= 0 ) - { - // get level screenshot. reformat texture to 128x128 - path c ( s ); - deletePathFromFilename ( c ); - cutFilenameExtension ( c, c ); - c = path ( "levelshots/" ) + c; - - dimension2du dim ( 128, 128 ); - IVideoDriver * driver = Game->Device->getVideoDriver(); - IImage* image = 0; - ITexture *tex = 0; - path filename; - - filename = c + ".jpg"; - if ( fs->existFile ( filename ) ) - image = driver->createImageFromFile( filename ); - if ( 0 == image ) - { - filename = c + ".tga"; - if ( fs->existFile ( filename ) ) - image = driver->createImageFromFile( filename ); - } - - if ( image ) - { - IImage* filter = driver->createImage ( video::ECF_R8G8B8, dim ); - image->copyToScalingBoxFilter ( filter, 0 ); - image->drop (); - image = filter; - } - - if ( image ) - { - tex = driver->addTexture ( filename, image ); - image->drop (); - } - - - bank->setTexture ( g, tex ); - - r.LowerRightCorner.X = dim.Width; - r.LowerRightCorner.Y = dim.Height; - gui.MapList->setItemHeight ( r.LowerRightCorner.Y + 4 ); - frame.rectNumber = bank->getPositions().size(); - frame.textureNumber = g; - - bank->getPositions().push_back(r); - - sprite.Frames.set_used ( 0 ); - sprite.Frames.push_back(frame); - sprite.frameTime = 0; - bank->getSprites().push_back(sprite); - - gui.MapList->addItem ( s.c_str (), g ); - g += 1; - } - } - fileList->drop (); - - gui.MapList->setSelected ( -1 ); - IGUIScrollBar * bar = (IGUIScrollBar*)gui.MapList->getElementFromId( 0 ); - if ( bar ) - bar->setPos ( 0 ); - - } - -} - -/* - clears the Map in Memory -*/ -void CQuake3EventHandler::dropMap () -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - - driver->removeAllHardwareBuffers (); - driver->removeAllTextures (); - - Player[0].shutdown (); - - - dropElement ( ItemParent ); - dropElement ( ShaderParent ); - dropElement ( UnresolvedParent ); - dropElement ( FogParent ); - dropElement ( BulletParent ); - - - Impacts.clear(); - - if ( Meta ) - { - Meta = 0; - } - - dropElement ( MapParent ); - dropElement ( SkyNode ); - - // clean out meshes, because textures are invalid - // TODO: better texture handling;-) - IMeshCache *cache = Game->Device->getSceneManager ()->getMeshCache(); - cache->clear (); - Mesh = 0; -} - -/* Load new map -*/ -void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision ) -{ - if ( 0 == mapName.size() ) - return; - - dropMap (); - - IFileSystem *fs = Game->Device->getFileSystem(); - ISceneManager *smgr = Game->Device->getSceneManager (); - - IReadFile* file = fs->createMemoryReadFile(&Game->loadParam, - sizeof(Game->loadParam), L"levelparameter.cfg", false); - - // load cfg file - smgr->getMesh( file ); - file->drop (); - - // load the actual map - Mesh = (IQ3LevelMesh*) smgr->getMesh(mapName); - if ( 0 == Mesh ) - return; - - /* - add the geometry mesh to the Scene ( polygon & patches ) - The Geometry mesh is optimised for faster drawing - */ - - IMesh *geometry = Mesh->getMesh(E_Q3_MESH_GEOMETRY); - if ( 0 == geometry || geometry->getMeshBufferCount() == 0) - return; - - Game->CurrentMapName = mapName; - - //create a collision list - Meta = 0; - - ITriangleSelector * selector = 0; - if (collision) - Meta = smgr->createMetaTriangleSelector(); - - //IMeshBuffer *b0 = geometry->getMeshBuffer(0); - //s32 minimalNodes = b0 ? core::s32_max ( 2048, b0->getVertexCount() / 32 ) : 2048; - s32 minimalNodes = 2048; - - MapParent = smgr->addOctreeSceneNode(geometry, 0, -1, minimalNodes); - MapParent->setName ( mapName ); - if ( Meta ) - { - selector = smgr->createOctreeTriangleSelector( geometry,MapParent, minimalNodes); - //selector = smgr->createTriangleSelector ( geometry, MapParent ); - Meta->addTriangleSelector( selector); - selector->drop (); - } - - // logical parent for the items - ItemParent = smgr->addEmptySceneNode(); - if ( ItemParent ) - ItemParent->setName ( "Item Container" ); - - ShaderParent = smgr->addEmptySceneNode(); - if ( ShaderParent ) - ShaderParent->setName ( "Shader Container" ); - - UnresolvedParent = smgr->addEmptySceneNode(); - if ( UnresolvedParent ) - UnresolvedParent->setName ( "Unresolved Container" ); - - FogParent = smgr->addEmptySceneNode(); - if ( FogParent ) - FogParent->setName ( "Fog Container" ); - - // logical parent for the bullets - BulletParent = smgr->addEmptySceneNode(); - if ( BulletParent ) - BulletParent->setName ( "Bullet Container" ); - - /* - now construct SceneNodes for each Shader - The Objects are stored in the quake mesh E_Q3_MESH_ITEMS - and the Shader ID is stored in the MaterialParameters - mostly dark looking skulls and moving lava.. or green flashing tubes? - */ - Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_ITEMS,ShaderParent, Meta, false ); - Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_FOG,FogParent, 0, false ); - Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_UNRESOLVED,UnresolvedParent, Meta, true ); - - /* - Now construct Models from Entity List - */ - Q3ModelFactory ( Game->loadParam, Game->Device, Mesh, ItemParent, false ); -} - -/* - Adds a SceneNode with an icon to the Scene Tree -*/ -void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent) -{ - IGUITreeViewNode* node; - wchar_t msg[128]; - - s32 imageIndex; - list::ConstIterator it = parent->getChildren().begin(); - for (; it != parent->getChildren().end(); ++it) - { - switch ( (*it)->getType () ) - { - case ESNT_Q3SHADER_SCENE_NODE: imageIndex = 0; break; - case ESNT_CAMERA: imageIndex = 1; break; - case ESNT_EMPTY: imageIndex = 2; break; - case ESNT_MESH: imageIndex = 3; break; - case ESNT_OCTREE: imageIndex = 3; break; - case ESNT_ANIMATED_MESH: imageIndex = 4; break; - case ESNT_SKY_BOX: imageIndex = 5; break; - case ESNT_BILLBOARD: imageIndex = 6; break; - case ESNT_PARTICLE_SYSTEM: imageIndex = 7; break; - case ESNT_TEXT: imageIndex = 8; break; - default:imageIndex = -1; break; - } - - if ( imageIndex < 0 ) - { - swprintf ( msg, 128, L"%hs,%hs", - Game->Device->getSceneManager ()->getSceneNodeTypeName ( (*it)->getType () ), - (*it)->getName() - ); - } - else - { - swprintf ( msg, 128, L"%hs",(*it)->getName() ); - } - - node = nodeParent->addChildBack( msg, 0, imageIndex ); - - // Add all Animators - list::ConstIterator ait = (*it)->getAnimators().begin(); - for (; ait != (*it)->getAnimators().end(); ++ait) - { - imageIndex = -1; - swprintf ( msg, 128, L"%hs", - Game->Device->getSceneManager ()->getAnimatorTypeName ( (*ait)->getType () ) - ); - - switch ( (*ait)->getType () ) - { - case ESNAT_FLY_CIRCLE: - case ESNAT_FLY_STRAIGHT: - case ESNAT_FOLLOW_SPLINE: - case ESNAT_ROTATION: - case ESNAT_TEXTURE: - case ESNAT_DELETION: - case ESNAT_COLLISION_RESPONSE: - case ESNAT_CAMERA_FPS: - case ESNAT_CAMERA_MAYA: - default: - break; - } - node->addChildBack( msg, 0, imageIndex ); - } - - addSceneTreeItem ( *it, node ); - } -} - - -// Adds life! -void CQuake3EventHandler::CreatePlayers() -{ - Player[0].create ( Game->Device, Mesh, MapParent, Meta ); -} - - -// Adds a skydome to the scene -void CQuake3EventHandler::AddSky( u32 dome, const c8 *texture) -{ - ISceneManager *smgr = Game->Device->getSceneManager (); - IVideoDriver * driver = Game->Device->getVideoDriver(); - - bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); - - if ( 0 == dome ) - { - // irrlicht order - //static const c8*p[] = { "ft", "lf", "bk", "rt", "up", "dn" }; - // quake3 order - static const c8*p[] = { "ft", "rt", "bk", "lf", "up", "dn" }; - - u32 i = 0; - snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); - SkyNode = smgr->addSkyBoxSceneNode( driver->getTexture ( buf ), 0, 0, 0, 0, 0 ); - - if (SkyNode) - { - for ( i = 0; i < 6; ++i ) - { - snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); - SkyNode->getMaterial(i).setTexture ( 0, driver->getTexture ( buf ) ); - } - } - } - else - if ( 1 == dome ) - { - snprintf ( buf, 64, "%s.jpg", texture ); - SkyNode = smgr->addSkyDomeSceneNode( - driver->getTexture( buf ), 32,32, - 1.f, 1.f, 1000.f, 0, 11); - } - else - if ( 2 == dome ) - { - snprintf ( buf, 64, "%s.jpg", texture ); - SkyNode = smgr->addSkyDomeSceneNode( - driver->getTexture( buf ), 16,8, - 0.95f, 2.f, 1000.f, 0, 11); - } - - if (SkyNode) - SkyNode->setName("Skydome"); - //SkyNode->getMaterial(0).ZBuffer = video::EMDF_DEPTH_LESS_EQUAL; - - driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); -} - - -// enable GUI elements -void CQuake3EventHandler::SetGUIActive( s32 command) -{ - bool inputState = false; - - ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); - - switch ( command ) - { - case 0: Game->guiActive = 0; inputState = !Game->guiActive; break; - case 1: Game->guiActive = 1; inputState = !Game->guiActive;;break; - case 2: Game->guiActive ^= 1; inputState = !Game->guiActive;break; - case 3: - if ( camera ) - inputState = !camera->isInputReceiverEnabled(); - break; - } - - if ( camera ) - { - camera->setInputReceiverEnabled ( inputState ); - Game->Device->getCursorControl()->setVisible( !inputState ); - } - - if ( gui.Window ) - { - gui.Window->setVisible ( Game->guiActive != 0 ); - } - - if ( Game->guiActive && - gui.SceneTree && Game->Device->getGUIEnvironment()->getFocus() != gui.SceneTree - ) - { - gui.SceneTree->getRoot()->clearChildren(); - addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); - } - - Game->Device->getGUIEnvironment()->setFocus ( Game->guiActive ? gui.Window: 0 ); -} - - -/* - Handle game input -*/ -bool CQuake3EventHandler::OnEvent(const SEvent& eve) -{ - if ( eve.EventType == EET_LOG_TEXT_EVENT ) - { - return false; - } - - if ( Game->guiActive && eve.EventType == EET_GUI_EVENT ) - { - if ( eve.GUIEvent.Caller == gui.MapList && eve.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN ) - { - s32 selected = gui.MapList->getSelected(); - if ( selected >= 0 ) - { - stringw loadMap = gui.MapList->getListItem ( selected ); - if ( 0 == MapParent || loadMap != Game->CurrentMapName ) - { - printf ( "Loading map %ls\n", loadMap.c_str() ); - LoadMap ( loadMap , 1 ); - if ( 0 == Game->loadParam.loadSkyShader ) - { - AddSky ( 1, "skydome2" ); - } - CreatePlayers (); - CreateGUI (); - SetGUIActive ( 0 ); - return true; - } - } - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveRemove && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Game->Device->getFileSystem()->removeFileArchive( gui.ArchiveList->getSelected() ); - Game->CurrentMapName = ""; - AddArchive ( "" ); - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveAdd && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - if ( 0 == gui.ArchiveFileOpen ) - { - Game->Device->getFileSystem()->setFileListSystem ( FILESYSTEM_NATIVE ); - gui.ArchiveFileOpen = Game->Device->getGUIEnvironment()->addFileOpenDialog ( L"Add Game Archive" , false,gui.Window ); - } - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_SELECTED ) - { - AddArchive ( gui.ArchiveFileOpen->getFileName() ); - gui.ArchiveFileOpen = 0; - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_DIRECTORY_SELECTED ) - { - AddArchive ( gui.ArchiveFileOpen->getDirectoryName() ); - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED ) - { - gui.ArchiveFileOpen = 0; - } - else - if ( ( eve.GUIEvent.Caller == gui.ArchiveUp || eve.GUIEvent.Caller == gui.ArchiveDown ) && - eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - s32 rel = eve.GUIEvent.Caller == gui.ArchiveUp ? -1 : 1; - if ( Game->Device->getFileSystem()->moveFileArchive ( gui.ArchiveList->getSelected (), rel ) ) - { - s32 newIndex = core::s32_clamp ( gui.ArchiveList->getSelected() + rel, 0, gui.ArchiveList->getRowCount() - 1 ); - AddArchive ( "" ); - gui.ArchiveList->setSelected ( newIndex ); - Game->CurrentMapName = ""; - } - } - else - if ( eve.GUIEvent.Caller == gui.VideoDriver && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) - { - Game->deviceParam.DriverType = (E_DRIVER_TYPE) gui.VideoDriver->getItemData ( gui.VideoDriver->getSelected() ); - } - else - if ( eve.GUIEvent.Caller == gui.VideoMode && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) - { - u32 val = gui.VideoMode->getItemData ( gui.VideoMode->getSelected() ); - Game->deviceParam.WindowSize.Width = val >> 16; - Game->deviceParam.WindowSize.Height = val & 0xFFFF; - } - else - if ( eve.GUIEvent.Caller == gui.FullScreen && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - Game->deviceParam.Fullscreen = gui.FullScreen->isChecked(); - } - else - if ( eve.GUIEvent.Caller == gui.Bit32 && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - Game->deviceParam.Bits = gui.Bit32->isChecked() ? 32 : 16; - } - else - if ( eve.GUIEvent.Caller == gui.MultiSample && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->deviceParam.AntiAlias = gui.MultiSample->getPos(); - } - else - if ( eve.GUIEvent.Caller == gui.Tesselation && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->loadParam.patchTesselation = gui.Tesselation->getPos (); - } - else - if ( eve.GUIEvent.Caller == gui.Gamma && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->GammaValue = gui.Gamma->getPos () * 0.01f; - Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); - } - else - if ( eve.GUIEvent.Caller == gui.SetVideoMode && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Game->retVal = 2; - Game->Device->closeDevice(); - } - else - if ( eve.GUIEvent.Caller == gui.Window && eve.GUIEvent.EventType == gui::EGET_ELEMENT_CLOSED ) - { - Game->Device->closeDevice(); - } - else - if ( eve.GUIEvent.Caller == gui.Collision && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - // set fly through active - Game->flyTroughState ^= 1; - Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); - - printf ( "collision %d\n", Game->flyTroughState == 0 ); - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Map && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - bool v = gui.Visible_Map->isChecked(); - - if ( MapParent ) - { - printf ( "static node set visible %d\n",v ); - MapParent->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Shader && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - bool v = gui.Visible_Shader->isChecked(); - - if ( ShaderParent ) - { - printf ( "shader node set visible %d\n",v ); - ShaderParent->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Skydome && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - if ( SkyNode ) - { - bool v = !SkyNode->isVisible(); - printf ( "skynode set visible %d\n",v ); - SkyNode->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Respawn && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Player[0].respawn (); - } - - return false; - } - - // fire - if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_SPACE && - eve.KeyInput.PressedDown == false) || - (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) - ) - { - ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); - if ( camera && camera->isInputReceiverEnabled () ) - { - useItem( Player + 0 ); - } - } - - // gui active - if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_F1 && - eve.KeyInput.PressedDown == false) || - (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) - ) - { - SetGUIActive ( 2 ); - } - - // check if user presses the key - if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.PressedDown == false) - { - // Escape toggles camera Input - if ( eve.KeyInput.Key == irr::KEY_ESCAPE ) - { - SetGUIActive ( 3 ); - } - else - if (eve.KeyInput.Key == KEY_F11) - { - // screenshot are taken without gamma! - IImage* image = Game->Device->getVideoDriver()->createScreenShot(); - if (image) - { - core::vector3df pos; - core::vector3df rot; - ICameraSceneNode * cam = Game->Device->getSceneManager()->getActiveCamera (); - if ( cam ) - { - pos = cam->getPosition (); - rot = cam->getRotation (); - } - - static const c8 *dName[] = { "null", "software", "burning", - "d3d8", "d3d9", "opengl" }; - - snprintf(buf, 256, "%s_%ls_%.0f_%.0f_%.0f_%.0f_%.0f_%.0f.jpg", - dName[Game->Device->getVideoDriver()->getDriverType()], - Game->CurrentMapName.c_str(), - pos.X, pos.Y, pos.Z, - rot.X, rot.Y, rot.Z - ); - path filename ( buf ); - filename.replace ( '/', '_' ); - printf ( "screenshot : %s\n", filename.c_str() ); - Game->Device->getVideoDriver()->writeImageToFile(image, filename, 100 ); - image->drop(); - } - } - else - if (eve.KeyInput.Key == KEY_F9) - { - s32 value = EDS_OFF; - - Game->debugState = ( Game->debugState + 1 ) & 3; - - switch ( Game->debugState ) - { - case 1: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL; break; - case 2: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_SKELETON; break; - } -/* - // set debug map data on/off - debugState = debugState == EDS_OFF ? - EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL: - EDS_OFF; -*/ - if ( ItemParent ) - { - list::ConstIterator it = ItemParent->getChildren().begin(); - for (; it != ItemParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( ShaderParent ) - { - list::ConstIterator it = ShaderParent->getChildren().begin(); - for (; it != ShaderParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( UnresolvedParent ) - { - list::ConstIterator it = UnresolvedParent->getChildren().begin(); - for (; it != UnresolvedParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( FogParent ) - { - list::ConstIterator it = FogParent->getChildren().begin(); - for (; it != FogParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( SkyNode ) - { - SkyNode->setDebugDataVisible ( value ); - } - - } - else - if (eve.KeyInput.Key == KEY_F8) - { - // set gravity on/off - Game->gravityState ^= 1; - Player[0].cam()->setGravity ( getGravity ( Game->gravityState ? "earth" : "none" ) ); - printf ( "gravity %s\n", Game->gravityState ? "earth" : "none" ); - } - else - if (eve.KeyInput.Key == KEY_F7) - { - // set fly through active - Game->flyTroughState ^= 1; - Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); - if ( gui.Collision ) - gui.Collision->setChecked ( Game->flyTroughState == 0 ); - - printf ( "collision %d\n", Game->flyTroughState == 0 ); - } - else - if (eve.KeyInput.Key == KEY_F2) - { - Player[0].respawn (); - } - else - if (eve.KeyInput.Key == KEY_F3) - { - if ( MapParent ) - { - bool v = !MapParent->isVisible (); - printf ( "static node set visible %d\n",v ); - MapParent->setVisible ( v ); - if ( gui.Visible_Map ) - gui.Visible_Map->setChecked ( v ); - } - } - else - if (eve.KeyInput.Key == KEY_F4) - { - if ( ShaderParent ) - { - bool v = !ShaderParent->isVisible (); - printf ( "shader node set visible %d\n",v ); - ShaderParent->setVisible ( v ); - if ( gui.Visible_Shader ) - gui.Visible_Shader->setChecked ( v ); - } - } - else - if (eve.KeyInput.Key == KEY_F5) - { - if ( FogParent ) - { - bool v = !FogParent->isVisible (); - printf ( "fog node set visible %d\n",v ); - FogParent->setVisible ( v ); - if ( gui.Visible_Fog ) - gui.Visible_Fog->setChecked ( v ); - } - - } - else - if (eve.KeyInput.Key == KEY_F6) - { - if ( UnresolvedParent ) - { - bool v = !UnresolvedParent->isVisible (); - printf ( "unresolved node set visible %d\n",v ); - UnresolvedParent->setVisible ( v ); - if ( gui.Visible_Unresolved ) - gui.Visible_Unresolved->setChecked ( v ); - } - } - } - - // check if user presses the key C ( for crouch) - if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_KEY_C ) - { - // crouch - ISceneNodeAnimatorCollisionResponse *anim = Player[0].cam (); - if ( anim && 0 == Game->flyTroughState ) - { - if ( false == eve.KeyInput.PressedDown ) - { - // stand up - anim->setEllipsoidRadius ( vector3df(30,45,30) ); - anim->setEllipsoidTranslation ( vector3df(0,40,0)); - - } - else - { - // on your knees - anim->setEllipsoidRadius ( vector3df(30,20,30) ); - anim->setEllipsoidTranslation ( vector3df(0,20,0)); - } - return true; - } - } - return false; -} - - - -/* - useItem -*/ -void CQuake3EventHandler::useItem( Q3Player * player) -{ - ISceneManager* smgr = Game->Device->getSceneManager(); - ICameraSceneNode* camera = smgr->getActiveCamera(); - - if (!camera) - return; - - SParticleImpact imp; - imp.when = 0; - - // get line of camera - - vector3df start = camera->getPosition(); - - if ( player->WeaponNode ) - { - start.X += 0.f; - start.Y += 0.f; - start.Z += 0.f; - } - - vector3df end = (camera->getTarget() - start); - end.normalize(); - start += end*20.0f; - - end = start + (end * camera->getFarValue()); - - triangle3df triangle; - line3d line(start, end); - - // get intersection point with map - scene::ISceneNode* hitNode; - if (smgr->getSceneCollisionManager()->getCollisionPoint( - line, Meta, end, triangle,hitNode)) - { - // collides with wall - vector3df out = triangle.getNormal(); - out.setLength(0.03f); - - imp.when = 1; - imp.outVector = out; - imp.pos = end; - - player->setAnim ( "pow" ); - player->Anim[1].next += player->Anim[1].delta; - } - else - { - // doesnt collide with wall - vector3df start = camera->getPosition(); - if ( player->WeaponNode ) - { - //start.X += 10.f; - //start.Y += -5.f; - //start.Z += 1.f; - } - - vector3df end = (camera->getTarget() - start); - end.normalize(); - start += end*20.0f; - end = start + (end * camera->getFarValue()); - } - - // create fire ball - ISceneNode* node = 0; - node = smgr->addBillboardSceneNode( BulletParent,dimension2d(10,10), start); - - node->setMaterialFlag(EMF_LIGHTING, false); - node->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture("fireball.bmp")); - node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); - node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR); - - f32 length = (f32)(end - start).getLength(); - const f32 speed = 5.8f; - u32 time = (u32)(length / speed); - - ISceneNodeAnimator* anim = 0; - - // set flight line - - anim = smgr->createFlyStraightAnimator(start, end, time); - node->addAnimator(anim); - anim->drop(); - - snprintf ( buf, 64, "bullet: %s on %.1f,%1.f,%1.f", - imp.when ? "hit" : "nohit", end.X, end.Y, end.Z ); - node->setName ( buf ); - - - anim = smgr->createDeleteAnimator(time); - node->addAnimator(anim); - anim->drop(); - - if (imp.when) - { - // create impact note - imp.when = Game->Device->getTimer()->getTime() + - (time + (s32) ( ( 1.f + Noiser::get() ) * 250.f )); - Impacts.push_back(imp); - } - - // play sound -} - -// rendered when bullets hit something -void CQuake3EventHandler::createParticleImpacts( u32 now ) -{ - ISceneManager* sm = Game->Device->getSceneManager(); - - struct smokeLayer - { - const c8 * texture; - f32 scale; - f32 minparticleSize; - f32 maxparticleSize; - f32 boxSize; - u32 minParticle; - u32 maxParticle; - u32 fadeout; - u32 lifetime; - }; - - smokeLayer smoke[] = - { - { "smoke2.jpg", 0.4f, 1.5f, 18.f, 20.f, 20, 50, 2000, 10000 }, - { "smoke3.jpg", 0.2f, 1.2f, 15.f, 20.f, 10, 30, 1000, 12000 } - }; - - - u32 i; - u32 g; - s32 factor = 1; - for ( g = 0; g != 2; ++g ) - { - smoke[g].minParticle *= factor; - smoke[g].maxParticle *= factor; - smoke[g].lifetime *= factor; - smoke[g].boxSize *= Noiser::get() * 0.5f; - } - - for ( i=0; i < Impacts.size(); ++i) - { - if (now < Impacts[i].when) - continue; - - // create smoke particle system - IParticleSystemSceneNode* pas = 0; - - for ( g = 0; g != 2; ++g ) - { - pas = sm->addParticleSystemSceneNode(false, BulletParent, -1, Impacts[i].pos); - - snprintf ( buf, 64, "bullet impact smoke at %.1f,%.1f,%1.f", - Impacts[i].pos.X,Impacts[i].pos.Y,Impacts[i].pos.Z); - pas->setName ( buf ); - - // create a flat smoke - vector3df direction = Impacts[i].outVector; - direction *= smoke[g].scale; - IParticleEmitter* em = pas->createBoxEmitter( - aabbox3d(-4.f,0.f,-4.f,20.f,smoke[g].minparticleSize,20.f), - direction,smoke[g].minParticle, smoke[g].maxParticle, - video::SColor(0,0,0,0),video::SColor(0,128,128,128), - 250,4000, 60); - - em->setMinStartSize (dimension2d( smoke[g].minparticleSize, smoke[g].minparticleSize)); - em->setMaxStartSize (dimension2d( smoke[g].maxparticleSize, smoke[g].maxparticleSize)); - - pas->setEmitter(em); - em->drop(); - - // particles get invisible - IParticleAffector* paf = pas->createFadeOutParticleAffector( - video::SColor ( 0, 0, 0, 0 ), smoke[g].fadeout); - pas->addAffector(paf); - paf->drop(); - - // particle system life time - ISceneNodeAnimator* anim = sm->createDeleteAnimator( smoke[g].lifetime); - pas->addAnimator(anim); - anim->drop(); - - pas->setMaterialFlag(video::EMF_LIGHTING, false); - pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); - pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); - pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture )); - } - - - // play impact sound - #ifdef USE_IRRKLANG -/* - if (irrKlang) - { - audio::ISound* sound = - irrKlang->play3D(impactSound, Impacts[i].pos, false, false, true); - - if (sound) - { - // adjust max value a bit to make to sound of an impact louder - sound->setMinDistance(400); - sound->drop(); - } - } -*/ - #endif - - - // delete entry - Impacts.erase(i); - i--; - } -} - -/* - render -*/ -void CQuake3EventHandler::Render() -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - if ( 0 == driver ) - return; - - // TODO: This does not work, yet. - const bool anaglyph=false; - if (anaglyph) - { - scene::ICameraSceneNode* cameraOld = Game->Device->getSceneManager()->getActiveCamera(); - driver->beginScene(true, true, SColor(0,0,0,0)); - driver->getOverrideMaterial().Material.ColorMask = ECP_NONE; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = ESNRP_SKY_BOX + - ESNRP_SOLID + - ESNRP_TRANSPARENT + - ESNRP_TRANSPARENT_EFFECT + - ESNRP_SHADOW; - Game->Device->getSceneManager()->drawAll(); - driver->clearZBuffer(); - - const vector3df oldPosition = cameraOld->getPosition(); - const vector3df oldTarget = cameraOld->getTarget(); - const matrix4 startMatrix = cameraOld->getAbsoluteTransformation(); - const vector3df focusPoint = (oldTarget - - cameraOld->getAbsolutePosition()).setLength(10000) + - cameraOld->getAbsolutePosition() ; - - scene::ICameraSceneNode* camera = cameraOld;//Game->Device->getSceneManager()->addCameraSceneNode(); - - //Left eye... - vector3df pos; - matrix4 move; - - move.setTranslation( vector3df(-1.5f,0.0f,0.0f) ); - pos=(startMatrix*move).getTranslation(); - - driver->getOverrideMaterial().Material.ColorMask = ECP_RED; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = - ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| - ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; - - camera->setPosition(pos); - camera->setTarget(focusPoint); - - Game->Device->getSceneManager()->drawAll(); - driver->clearZBuffer(); - - //Right eye... - move.setTranslation( vector3df(1.5f,0.0f,0.0f) ); - pos=(startMatrix*move).getTranslation(); - - driver->getOverrideMaterial().Material.ColorMask = ECP_GREEN + ECP_BLUE; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = - ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| - ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; - - camera->setPosition(pos); - camera->setTarget(focusPoint); - - Game->Device->getSceneManager()->drawAll(); - - driver->getOverrideMaterial().Material.ColorMask=ECP_ALL; - driver->getOverrideMaterial().EnableFlags=0; - driver->getOverrideMaterial().EnablePasses=0; - - if (camera != cameraOld) - { - Game->Device->getSceneManager()->setActiveCamera(cameraOld); - camera->remove(); - } - else - { - camera->setPosition(oldPosition); - camera->setTarget(oldTarget); - } - } - else - { - driver->beginScene(true, true, SColor(0,0,0,0)); - Game->Device->getSceneManager()->drawAll(); - } - Game->Device->getGUIEnvironment()->drawAll(); - driver->endScene(); -} - -/* - update the generic scene node -*/ -void CQuake3EventHandler::Animate() -{ - u32 now = Game->Device->getTimer()->getTime(); - - Q3Player * player = Player + 0; - - checkTimeFire ( player->Anim, 4, now ); - - // Query Scene Manager attributes - if ( player->Anim[0].flags & FIRED ) - { - ISceneManager *smgr = Game->Device->getSceneManager (); - wchar_t msg[128]; - IVideoDriver * driver = Game->Device->getVideoDriver(); - - IAttributes * attr = smgr->getParameters(); - swprintf ( msg, 128, - L"Q3 %s [%ls], FPS:%03d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)", - Game->CurrentMapName.c_str(), - driver->getName(), - driver->getFPS (), - (f32) driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ), - attr->getAttributeAsInt ( "culled" ), - attr->getAttributeAsInt ( "calls" ), - attr->getAttributeAsInt ( "drawn_solid" ), - attr->getAttributeAsInt ( "drawn_transparent" ), - attr->getAttributeAsInt ( "drawn_transparent_effect" ) - ); - Game->Device->setWindowCaption( msg ); - - swprintf ( msg, 128, - L"%03d fps, F1 GUI on/off, F2 respawn, F3-F6 toggle Nodes, F7 Collision on/off" - L", F8 Gravity on/off, Right Mouse Toggle GUI", - Game->Device->getVideoDriver()->getFPS () - ); - if ( gui.StatusLine ) - gui.StatusLine->setText ( msg ); - player->Anim[0].flags &= ~FIRED; - } - - // idle.. - if ( player->Anim[1].flags & FIRED ) - { - if ( strcmp ( player->animation, "idle" ) ) - player->setAnim ( "idle" ); - - player->Anim[1].flags &= ~FIRED; - } - - createParticleImpacts ( now ); - -} - - -/* The main game states -*/ -void runGame ( GameData *game ) -{ - if ( game->retVal >= 3 ) - return; - - game->Device = (*game->createExDevice) ( game->deviceParam ); - if ( 0 == game->Device) - { - // could not create selected driver. - game->retVal = 0; - return; - } - - // create an event receiver based on current game data - CQuake3EventHandler *eventHandler = new CQuake3EventHandler( game ); - - // load stored config - game->load ( "explorer.cfg" ); - - // add our media directory and archive to the file system - for ( u32 i = 0; i < game->CurrentArchiveList.size(); ++i ) - { - eventHandler->AddArchive ( game->CurrentArchiveList[i] ); - } - - // Load a Map or startup to the GUI - if ( game->CurrentMapName.size () ) - { - eventHandler->LoadMap ( game->CurrentMapName, 1 ); - if ( 0 == game->loadParam.loadSkyShader ) - eventHandler->AddSky ( 1, "skydome2" ); - eventHandler->CreatePlayers (); - eventHandler->CreateGUI (); - eventHandler->SetGUIActive ( 0 ); - - // set player to last position on restart - if ( game->retVal == 2 ) - { - eventHandler->GetPlayer( 0 )->setpos ( game->PlayerPosition, game->PlayerRotation ); - } - } - else - { - // start up empty - eventHandler->AddSky ( 1, "skydome2" ); - eventHandler->CreatePlayers (); - eventHandler->CreateGUI (); - eventHandler->SetGUIActive ( 1 ); - background_music ( "IrrlichtTheme.ogg" ); - } - - - game->retVal = 3; - while( game->Device->run() ) - { - eventHandler->Animate (); - eventHandler->Render (); - //if ( !game->Device->isWindowActive() ) - game->Device->yield(); - } - - game->Device->setGammaRamp ( 1.f, 1.f, 1.f, 0.f, 0.f ); - delete eventHandler; -} - -#if defined (_IRR_WINDOWS_) && 0 - #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") -#endif - - -/* The main routine, doing all setup -*/ -int IRRCALLCONV main(int argc, char* argv[]) -{ - path prgname(argv[0]); - GameData game ( deletePathFromPath ( prgname, 1 ) ); - - // dynamically load irrlicht - const c8 * dllName = argc > 1 ? argv[1] : "irrlicht.dll"; - game.createExDevice = load_createDeviceEx ( dllName ); - if ( 0 == game.createExDevice ) - { - game.retVal = 3; - printf ( "Could not load %s.\n", dllName ); - return game.retVal; // could not load dll - } - - // start without asking for driver - game.retVal = 1; - do - { - // if driver could not created, ask for another driver - if ( game.retVal == 0 ) - { - game.setDefault (); - // ask user for driver - game.deviceParam.DriverType=driverChoiceConsole(); - if (game.deviceParam.DriverType==video::EDT_COUNT) - game.retVal = 3; - } - runGame ( &game ); - } while ( game.retVal < 3 ); - - return game.retVal; -} - -/* -**/ +/** Example 021 Quake3 Explorer + +This Tutorial shows how to load different Quake 3 maps. + +Features: + - Load BSP Archives at Runtime from the menu + - Load a Map from the menu. Showing with Screenshot + - Set the VideoDriver at runtime from menu + - Adjust GammaLevel at runtime + - Create SceneNodes for the Shaders + - Load EntityList and create Entity SceneNodes + - Create Players with Weapons and with Collision Response + - Play music + +You can download the Quake III Arena demo ( copyright id software ) +at the following location: +ftp://ftp.idsoftware.com/idstuff/quake3/win32/q3ademo.exe + +Copyright 2006-2011 Burningwater, Thomas Alten +*/ + +#include "driverChoice.h" +#include +#include "q3factory.h" +#include "sound.h" + +/* + Game Data is used to hold Data which is needed to drive the game +*/ +struct GameData +{ + GameData ( const path &startupDir) : + retVal(0), StartupDir(startupDir), createExDevice(0), Device(0) + { + setDefault (); + } + + void setDefault (); + s32 save ( const path &filename ); + s32 load ( const path &filename ); + + s32 debugState; + s32 gravityState; + s32 flyTroughState; + s32 wireFrame; + s32 guiActive; + s32 guiInputActive; + f32 GammaValue; + s32 retVal; + s32 sound; + + path StartupDir; + stringw CurrentMapName; + array CurrentArchiveList; + + vector3df PlayerPosition; + vector3df PlayerRotation; + + tQ3EntityList Variable; + + Q3LevelLoadParameter loadParam; + SIrrlichtCreationParameters deviceParam; + funcptr_createDeviceEx createExDevice; + IrrlichtDevice *Device; +}; + +/* + set default settings +*/ +void GameData::setDefault () +{ + debugState = EDS_OFF; + gravityState = 1; + flyTroughState = 0; + wireFrame = 0; + guiActive = 1; + guiInputActive = 0; + GammaValue = 1.f; + + // default deviceParam; +#if defined ( _IRR_WINDOWS_ ) + deviceParam.DriverType = EDT_DIRECT3D9; +#else + deviceParam.DriverType = EDT_OPENGL; +#endif + deviceParam.WindowSize.Width = 800; + deviceParam.WindowSize.Height = 600; + deviceParam.Fullscreen = false; + deviceParam.Bits = 24; + deviceParam.ZBufferBits = 16; + deviceParam.Vsync = false; + deviceParam.AntiAlias = false; + + // default Quake3 loadParam + loadParam.defaultLightMapMaterial = EMT_LIGHTMAP; + loadParam.defaultModulate = EMFN_MODULATE_1X; + loadParam.defaultFilter = EMF_ANISOTROPIC_FILTER; + loadParam.verbose = 2; + loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material + loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture + loadParam.loadAllShaders = 1; // load all scripts in the script directory + loadParam.loadSkyShader = 0; // load sky Shader + loadParam.alpharef = 1; + + sound = 0; + + CurrentMapName = ""; + CurrentArchiveList.clear (); + + // Explorer Media directory + CurrentArchiveList.push_back ( StartupDir + "../../media/" ); + + // Add the original quake3 files before you load your custom map + // Most mods are using the original shaders, models&items&weapons + CurrentArchiveList.push_back("/q/baseq3/"); + + CurrentArchiveList.push_back(StartupDir + "../../media/map-20kdm2.pk3"); +} + +/* + Load the current game State from a typical quake3 cfg file +*/ +s32 GameData::load ( const path &filename ) +{ + if (!Device) + return 0; + + // the quake3 mesh loader can also handle *.shader and *.cfg file + IQ3LevelMesh* mesh = (IQ3LevelMesh*) Device->getSceneManager()->getMesh ( filename ); + if (!mesh) + return 0; + + tQ3EntityList &entityList = mesh->getEntityList (); + + stringc s; + u32 pos; + + for ( u32 e = 0; e != entityList.size (); ++e ) + { + //dumpShader ( s, &entityList[e], false ); + //printf ( s.c_str () ); + + for ( u32 g = 0; g != entityList[e].getGroupSize (); ++g ) + { + const SVarGroup *group = entityList[e].getGroup ( g ); + + for ( u32 index = 0; index < group->Variable.size (); ++index ) + { + const SVariable &v = group->Variable[index]; + pos = 0; + if ( v.name == "playerposition" ) + { + PlayerPosition = getAsVector3df ( v.content, pos ); + } + else + if ( v.name == "playerrotation" ) + { + PlayerRotation = getAsVector3df ( v.content, pos ); + } + } + } + } + + return 1; +} + +/* + Store the current game State in a quake3 configuration file +*/ +s32 GameData::save ( const path &filename ) +{ + return 0; + if (!Device) + return 0; + + c8 buf[128]; + u32 i; + + // Store current Archive for restart + CurrentArchiveList.clear(); + IFileSystem *fs = Device->getFileSystem(); + for ( i = 0; i != fs->getFileArchiveCount(); ++i ) + { + CurrentArchiveList.push_back ( fs->getFileArchive(i)->getFileList()->getPath() ); + } + + // Store Player Position and Rotation + ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera (); + if ( camera ) + { + PlayerPosition = camera->getPosition (); + PlayerRotation = camera->getRotation (); + } + + IWriteFile *file = fs->createAndWriteFile ( filename ); + if (!file) + return 0; + + snprintf ( buf, 128, "playerposition %.f %.f %.f\nplayerrotation %.f %.f %.f\n", + PlayerPosition.X, PlayerPosition.Z, PlayerPosition.Y, + PlayerRotation.X, PlayerRotation.Z, PlayerRotation.Y); + file->write ( buf, (s32) strlen ( buf ) ); + for ( i = 0; i != fs->getFileArchiveCount(); ++i ) + { + snprintf ( buf, 128, "archive %s\n",stringc ( fs->getFileArchive(i)->getFileList()->getPath() ).c_str () ); + file->write ( buf, (s32) strlen ( buf ) ); + } + + file->drop (); + return 1; +} + +/* + Representing a player +*/ +struct Q3Player : public IAnimationEndCallBack +{ + Q3Player () + : Device(0), MapParent(0), Mesh(0), WeaponNode(0), StartPositionCurrent(0) + { + animation[0] = 0; + memset(Anim, 0, sizeof(TimeFire)*4); + } + + virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node); + + void create ( IrrlichtDevice *device, + IQ3LevelMesh* mesh, + ISceneNode *mapNode, + IMetaTriangleSelector *meta + ); + void shutdown (); + void setAnim ( const c8 *name ); + void respawn (); + void setpos ( const vector3df &pos, const vector3df& rotation ); + + ISceneNodeAnimatorCollisionResponse * cam() { return camCollisionResponse ( Device ); } + + IrrlichtDevice *Device; + ISceneNode* MapParent; + IQ3LevelMesh* Mesh; + IAnimatedMeshSceneNode* WeaponNode; + s32 StartPositionCurrent; + TimeFire Anim[4]; + c8 animation[64]; + c8 buf[64]; +}; + + +/* End player +*/ +void Q3Player::shutdown () +{ + setAnim ( 0 ); + + dropElement (WeaponNode); + + if ( Device ) + { + ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); + dropElement ( camera ); + Device = 0; + } + + MapParent = 0; + Mesh = 0; +} + + +/* create a new player +*/ +void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *mapNode, IMetaTriangleSelector *meta ) +{ + setTimeFire ( Anim + 0, 200, FIRED ); + setTimeFire ( Anim + 1, 5000 ); + + if (!device) + return; + // load FPS weapon to Camera + Device = device; + Mesh = mesh; + MapParent = mapNode; + + ISceneManager *smgr = device->getSceneManager (); + IVideoDriver * driver = device->getVideoDriver(); + + ICameraSceneNode* camera = 0; + + SKeyMap keyMap[10]; + keyMap[0].Action = EKA_MOVE_FORWARD; + keyMap[0].KeyCode = KEY_UP; + keyMap[1].Action = EKA_MOVE_FORWARD; + keyMap[1].KeyCode = KEY_KEY_W; + + keyMap[2].Action = EKA_MOVE_BACKWARD; + keyMap[2].KeyCode = KEY_DOWN; + keyMap[3].Action = EKA_MOVE_BACKWARD; + keyMap[3].KeyCode = KEY_KEY_S; + + keyMap[4].Action = EKA_STRAFE_LEFT; + keyMap[4].KeyCode = KEY_LEFT; + keyMap[5].Action = EKA_STRAFE_LEFT; + keyMap[5].KeyCode = KEY_KEY_A; + + keyMap[6].Action = EKA_STRAFE_RIGHT; + keyMap[6].KeyCode = KEY_RIGHT; + keyMap[7].Action = EKA_STRAFE_RIGHT; + keyMap[7].KeyCode = KEY_KEY_D; + + keyMap[8].Action = EKA_JUMP_UP; + keyMap[8].KeyCode = KEY_KEY_J; + + keyMap[9].Action = EKA_CROUCH; + keyMap[9].KeyCode = KEY_KEY_C; + + camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 0.6f); + camera->setName ( "First Person Camera" ); + //camera->setFOV ( 100.f * core::DEGTORAD ); + camera->setFarValue( 20000.f ); + + IAnimatedMeshMD2* weaponMesh = (IAnimatedMeshMD2*) smgr->getMesh("gun.md2"); + if ( 0 == weaponMesh ) + return; + + if ( weaponMesh->getMeshType() == EAMT_MD2 ) + { + s32 count = weaponMesh->getAnimationCount(); + for ( s32 i = 0; i != count; ++i ) + { + snprintf ( buf, 64, "Animation: %s", weaponMesh->getAnimationName(i) ); + device->getLogger()->log(buf, ELL_INFORMATION); + } + } + + WeaponNode = smgr->addAnimatedMeshSceneNode( + weaponMesh, + smgr->getActiveCamera(), + 10, + vector3df( 0, 0, 0), + vector3df(-90,-90,90) + ); + WeaponNode->setMaterialFlag(EMF_LIGHTING, false); + WeaponNode->setMaterialTexture(0, driver->getTexture( "gun.jpg")); + WeaponNode->setLoopMode ( false ); + WeaponNode->setName ( "tommi the gun man" ); + + //create a collision auto response animator + ISceneNodeAnimator* anim = + smgr->createCollisionResponseAnimator( meta, camera, + vector3df(30,45,30), + getGravity ( "earth" ), + vector3df(0,40,0), + 0.0005f + ); + + camera->addAnimator( anim ); + anim->drop(); + + if ( meta ) + { + meta->drop (); + } + + respawn (); + setAnim ( "idle" ); +} + + +/* + so we need a good starting Position in the level. + we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" +*/ +void Q3Player::respawn () +{ + if (!Device) + return; + ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); + + Device->getLogger()->log( "respawn" ); + + if ( StartPositionCurrent >= Q3StartPosition ( + Mesh, camera,StartPositionCurrent++, + cam ()->getEllipsoidTranslation() ) + ) + { + StartPositionCurrent = 0; + } +} + +/* + set Player position from saved coordinates +*/ +void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation ) +{ + if (!Device) + return; + Device->getLogger()->log( "setpos" ); + + ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); + if ( camera ) + { + camera->setPosition ( pos ); + camera->setRotation ( rotation ); + //! New. FPSCamera and animators catches reset on animate 0 + camera->OnAnimate ( 0 ); + } +} + +/* set the Animation of the player and weapon +*/ +void Q3Player::setAnim ( const c8 *name ) +{ + if ( name ) + { + snprintf ( animation, 64, "%s", name ); + if ( WeaponNode ) + { + WeaponNode->setAnimationEndCallback ( this ); + WeaponNode->setMD2Animation ( animation ); + } + } + else + { + animation[0] = 0; + if ( WeaponNode ) + { + WeaponNode->setAnimationEndCallback ( 0 ); + } + } +} + + +// Callback +void Q3Player::OnAnimationEnd(IAnimatedMeshSceneNode* node) +{ + setAnim ( 0 ); +} + + + +/* GUI Elements +*/ +struct GUI +{ + GUI () + { + memset ( this, 0, sizeof ( *this ) ); + } + + void drop() + { + dropElement ( Window ); + dropElement ( Logo ); + } + + IGUIComboBox* VideoDriver; + IGUIComboBox* VideoMode; + IGUICheckBox* FullScreen; + IGUICheckBox* Bit32; + IGUIScrollBar* MultiSample; + IGUIButton* SetVideoMode; + + IGUIScrollBar* Tesselation; + IGUIScrollBar* Gamma; + IGUICheckBox* Collision; + IGUICheckBox* Visible_Map; + IGUICheckBox* Visible_Shader; + IGUICheckBox* Visible_Fog; + IGUICheckBox* Visible_Unresolved; + IGUICheckBox* Visible_Skydome; + IGUIButton* Respawn; + + IGUITable* ArchiveList; + IGUIButton* ArchiveAdd; + IGUIButton* ArchiveRemove; + IGUIFileOpenDialog* ArchiveFileOpen; + IGUIButton* ArchiveUp; + IGUIButton* ArchiveDown; + + IGUIListBox* MapList; + IGUITreeView* SceneTree; + IGUIStaticText* StatusLine; + IGUIImage* Logo; + IGUIWindow* Window; +}; + + +/* + CQuake3EventHandler controls the game +*/ +class CQuake3EventHandler : public IEventReceiver +{ +public: + + CQuake3EventHandler( GameData *gameData ); + virtual ~CQuake3EventHandler (); + + void Animate(); + void Render(); + + void AddArchive ( const path& archiveName ); + void LoadMap ( const stringw& mapName, s32 collision ); + void CreatePlayers(); + void AddSky( u32 dome, const c8 *texture ); + Q3Player *GetPlayer ( u32 index ) { return &Player[index]; } + + void CreateGUI(); + void SetGUIActive( s32 command); + + bool OnEvent(const SEvent& eve); + + +private: + + GameData *Game; + + IQ3LevelMesh* Mesh; + ISceneNode* MapParent; + ISceneNode* ShaderParent; + ISceneNode* ItemParent; + ISceneNode* UnresolvedParent; + ISceneNode* BulletParent; + ISceneNode* FogParent; + ISceneNode * SkyNode; + IMetaTriangleSelector *Meta; + + c8 buf[256]; + + Q3Player Player[2]; + + struct SParticleImpact + { + u32 when; + vector3df pos; + vector3df outVector; + }; + array Impacts; + void useItem( Q3Player * player); + void createParticleImpacts( u32 now ); + + void createTextures (); + void addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent); + + GUI gui; + void dropMap (); +}; + +/* Constructor +*/ +CQuake3EventHandler::CQuake3EventHandler( GameData *game ) +: Game(game), Mesh(0), MapParent(0), ShaderParent(0), ItemParent(0), UnresolvedParent(0), + BulletParent(0), FogParent(0), SkyNode(0), Meta(0) +{ + buf[0]=0; + // Also use 16 Bit Textures for 16 Bit RenderDevice + if ( Game->deviceParam.Bits == 16 ) + { + game->Device->getVideoDriver()->setTextureCreationFlag(ETCF_ALWAYS_16_BIT, true); + } + + // Quake3 Shader controls Z-Writing + game->Device->getSceneManager()->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); + + // create internal textures + createTextures (); + + sound_init ( game->Device ); + + Game->Device->setEventReceiver ( this ); +} + + +// destructor +CQuake3EventHandler::~CQuake3EventHandler () +{ + Player[0].shutdown (); + sound_shutdown (); + + Game->save( "explorer.cfg" ); + + Game->Device->drop(); +} + + +// create runtime textures smog, fog +void CQuake3EventHandler::createTextures() +{ + IVideoDriver * driver = Game->Device->getVideoDriver(); + + dimension2du dim(64, 64); + + video::IImage* image; + u32 i; + u32 x; + u32 y; + u32 * data; + for ( i = 0; i != 8; ++i ) + { + image = driver->createImage ( video::ECF_A8R8G8B8, dim); + data = (u32*) image->lock (); + for ( y = 0; y != dim.Height; ++y ) + { + for ( x = 0; x != dim.Width; ++x ) + { + data [x] = 0xFFFFFFFF; + } + data = (u32*) ( (u8*) data + image->getPitch() ); + } + image->unlock(); + snprintf ( buf, 64, "smoke_%02d", i ); + driver->addTexture( buf, image ); + image->drop (); + } + + // fog + for ( i = 0; i != 1; ++i ) + { + image = driver->createImage ( video::ECF_A8R8G8B8, dim); + data = (u32*) image->lock (); + for ( y = 0; y != dim.Height; ++y ) + { + for ( x = 0; x != dim.Width; ++x ) + { + data [x] = 0xFFFFFFFF; + } + data = (u32*) ( (u8*) data + image->getPitch() ); + } + image->unlock(); + snprintf ( buf, 64, "fog_%02d", i ); + driver->addTexture( buf, image ); + image->drop (); + } +} + + +/* + create the GUI +*/ +void CQuake3EventHandler::CreateGUI() +{ + + IGUIEnvironment *env = Game->Device->getGUIEnvironment(); + IVideoDriver * driver = Game->Device->getVideoDriver(); + + gui.drop(); + + // set skin font + IGUIFont* font = env->getFont("fontlucida.png"); + if (font) + env->getSkin()->setFont(font); + env->getSkin()->setColor ( EGDC_BUTTON_TEXT, video::SColor(240,0xAA,0xAA,0xAA) ); + env->getSkin()->setColor ( EGDC_3D_HIGH_LIGHT, video::SColor(240,0x22,0x22,0x22) ); + env->getSkin()->setColor ( EGDC_3D_FACE, video::SColor(240,0x44,0x44,0x44) ); + env->getSkin()->setColor ( EGDC_EDITABLE, video::SColor(240,0x44,0x44,0x44) ); + env->getSkin()->setColor ( EGDC_FOCUSED_EDITABLE, video::SColor(240,0x54,0x54,0x54) ); + env->getSkin()->setColor ( EGDC_WINDOW, video::SColor(240,0x66,0x66,0x66) ); + + // minimal gui size 800x600 + dimension2d dim ( 800, 600 ); + dimension2d vdim ( Game->Device->getVideoDriver()->getScreenSize() ); + + if ( vdim.Height >= dim.Height && vdim.Width >= dim.Width ) + { + //dim = vdim; + } + else + { + } + + gui.Window = env->addWindow ( rect ( 0, 0, dim.Width, dim.Height ), false, L"Quake3 Explorer" ); + gui.Window->setToolTipText ( L"Quake3Explorer. Loads and show various BSP File Format and Shaders." ); + gui.Window->getCloseButton()->setToolTipText ( L"Quit Quake3 Explorer" ); + + // add a status line help text + gui.StatusLine = env->addStaticText( 0, rect( 5,dim.Height - 30,dim.Width - 5,dim.Height - 10), + false, false, gui.Window, -1, true + ); + + + env->addStaticText ( L"VideoDriver:", rect( dim.Width - 400, 24, dim.Width - 310, 40 ),false, false, gui.Window, -1, false ); + gui.VideoDriver = env->addComboBox(rect( dim.Width - 300, 24, dim.Width - 10, 40 ),gui.Window); + gui.VideoDriver->addItem(L"Direct3D 9.0c", EDT_DIRECT3D9 ); + gui.VideoDriver->addItem(L"Direct3D 8.1", EDT_DIRECT3D8 ); + gui.VideoDriver->addItem(L"OpenGL 1.5", EDT_OPENGL); + gui.VideoDriver->addItem(L"Software Renderer", EDT_SOFTWARE); + gui.VideoDriver->addItem(L"Burning's Video (TM) Thomas Alten", EDT_BURNINGSVIDEO); + gui.VideoDriver->setSelected ( gui.VideoDriver->getIndexForItemData ( Game->deviceParam.DriverType ) ); + gui.VideoDriver->setToolTipText ( L"Use a VideoDriver" ); + + env->addStaticText ( L"VideoMode:", rect( dim.Width - 400, 44, dim.Width - 310, 60 ),false, false, gui.Window, -1, false ); + gui.VideoMode = env->addComboBox(rect( dim.Width - 300, 44, dim.Width - 10, 60 ),gui.Window); + gui.VideoMode->setToolTipText ( L"Supported Screenmodes" ); + IVideoModeList *modeList = Game->Device->getVideoModeList(); + if ( modeList ) + { + s32 i; + for ( i = 0; i != modeList->getVideoModeCount (); ++i ) + { + u16 d = modeList->getVideoModeDepth ( i ); + if ( d < 16 ) + continue; + + u16 w = modeList->getVideoModeResolution ( i ).Width; + u16 h = modeList->getVideoModeResolution ( i ).Height; + u32 val = w << 16 | h; + + if ( gui.VideoMode->getIndexForItemData ( val ) >= 0 ) + continue; + + f32 aspect = (f32) w / (f32) h; + const c8 *a = ""; + if ( core::equals ( aspect, 1.3333333333f ) ) a = "4:3"; + else if ( core::equals ( aspect, 1.6666666f ) ) a = "15:9 widescreen"; + else if ( core::equals ( aspect, 1.7777777f ) ) a = "16:9 widescreen"; + else if ( core::equals ( aspect, 1.6f ) ) a = "16:10 widescreen"; + else if ( core::equals ( aspect, 2.133333f ) ) a = "20:9 widescreen"; + + snprintf ( buf, sizeof ( buf ), "%d x %d, %s",w, h, a ); + gui.VideoMode->addItem ( stringw ( buf ).c_str(), val ); + } + } + gui.VideoMode->setSelected ( gui.VideoMode->getIndexForItemData ( + Game->deviceParam.WindowSize.Width << 16 | + Game->deviceParam.WindowSize.Height ) ); + + gui.FullScreen = env->addCheckBox ( Game->deviceParam.Fullscreen, rect( dim.Width - 400, 64, dim.Width - 300, 80 ), gui.Window,-1, L"Fullscreen" ); + gui.FullScreen->setToolTipText ( L"Set Fullscreen or Window Mode" ); + + gui.Bit32 = env->addCheckBox ( Game->deviceParam.Bits == 32, rect( dim.Width - 300, 64, dim.Width - 240, 80 ), gui.Window,-1, L"32Bit" ); + gui.Bit32->setToolTipText ( L"Use 16 or 32 Bit" ); + + env->addStaticText ( L"MultiSample:", rect( dim.Width - 235, 64, dim.Width - 150, 80 ),false, false, gui.Window, -1, false ); + gui.MultiSample = env->addScrollBar( true, rect( dim.Width - 150, 64, dim.Width - 70, 80 ), gui.Window,-1 ); + gui.MultiSample->setMin ( 0 ); + gui.MultiSample->setMax ( 8 ); + gui.MultiSample->setSmallStep ( 1 ); + gui.MultiSample->setLargeStep ( 1 ); + gui.MultiSample->setPos ( Game->deviceParam.AntiAlias ); + gui.MultiSample->setToolTipText ( L"Set the MultiSample (disable, 1x, 2x, 4x, 8x )" ); + + gui.SetVideoMode = env->addButton (rect( dim.Width - 60, 64, dim.Width - 10, 80 ), gui.Window, -1,L"set" ); + gui.SetVideoMode->setToolTipText ( L"Set Video Mode with current values" ); + + env->addStaticText ( L"Gamma:", rect( dim.Width - 400, 104, dim.Width - 310, 120 ),false, false, gui.Window, -1, false ); + gui.Gamma = env->addScrollBar( true, rect( dim.Width - 300, 104, dim.Width - 10, 120 ), gui.Window,-1 ); + gui.Gamma->setMin ( 50 ); + gui.Gamma->setMax ( 350 ); + gui.Gamma->setSmallStep ( 1 ); + gui.Gamma->setLargeStep ( 10 ); + gui.Gamma->setPos ( core::floor32 ( Game->GammaValue * 100.f ) ); + gui.Gamma->setToolTipText ( L"Adjust Gamma Ramp ( 0.5 - 3.5)" ); + Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); + + + env->addStaticText ( L"Tesselation:", rect( dim.Width - 400, 124, dim.Width - 310, 140 ),false, false, gui.Window, -1, false ); + gui.Tesselation = env->addScrollBar( true, rect( dim.Width - 300, 124, dim.Width - 10, 140 ), gui.Window,-1 ); + gui.Tesselation->setMin ( 2 ); + gui.Tesselation->setMax ( 12 ); + gui.Tesselation->setSmallStep ( 1 ); + gui.Tesselation->setLargeStep ( 1 ); + gui.Tesselation->setPos ( Game->loadParam.patchTesselation ); + gui.Tesselation->setToolTipText ( L"How smooth should curved surfaces be rendered" ); + + gui.Collision = env->addCheckBox ( true, rect( dim.Width - 400, 150, dim.Width - 300, 166 ), gui.Window,-1, L"Collision" ); + gui.Collision->setToolTipText ( L"Set collision on or off ( flythrough ). \nPress F7 on your Keyboard" ); + gui.Visible_Map = env->addCheckBox ( true, rect( dim.Width - 300, 150, dim.Width - 240, 166 ), gui.Window,-1, L"Map" ); + gui.Visible_Map->setToolTipText ( L"Show or not show the static part the Level. \nPress F3 on your Keyboard" ); + gui.Visible_Shader = env->addCheckBox ( true, rect( dim.Width - 240, 150, dim.Width - 170, 166 ), gui.Window,-1, L"Shader" ); + gui.Visible_Shader->setToolTipText ( L"Show or not show the Shader Nodes. \nPress F4 on your Keyboard" ); + gui.Visible_Fog = env->addCheckBox ( true, rect( dim.Width - 170, 150, dim.Width - 110, 166 ), gui.Window,-1, L"Fog" ); + gui.Visible_Fog->setToolTipText ( L"Show or not show the Fog Nodes. \nPress F5 on your Keyboard" ); + gui.Visible_Unresolved = env->addCheckBox ( true, rect( dim.Width - 110, 150, dim.Width - 10, 166 ), gui.Window,-1, L"Unresolved" ); + gui.Visible_Unresolved->setToolTipText ( L"Show the or not show the Nodes the Engine can't handle. \nPress F6 on your Keyboard" ); + gui.Visible_Skydome = env->addCheckBox ( true, rect( dim.Width - 110, 180, dim.Width - 10, 196 ), gui.Window,-1, L"Skydome" ); + gui.Visible_Skydome->setToolTipText ( L"Show the or not show the Skydome." ); + + //Respawn = env->addButton ( rect( dim.Width - 260, 90, dim.Width - 10, 106 ), 0,-1, L"Respawn" ); + + env->addStaticText ( L"Archives:", rect( 5, dim.Height - 530, dim.Width - 600,dim.Height - 514 ),false, false, gui.Window, -1, false ); + + gui.ArchiveAdd = env->addButton ( rect( dim.Width - 725, dim.Height - 530, dim.Width - 665, dim.Height - 514 ), gui.Window,-1, L"add" ); + gui.ArchiveAdd->setToolTipText ( L"Add an archive, usually packed zip-archives (*.pk3) to the Filesystem" ); + gui.ArchiveRemove = env->addButton ( rect( dim.Width - 660, dim.Height - 530, dim.Width - 600, dim.Height - 514 ), gui.Window,-1, L"del" ); + gui.ArchiveRemove->setToolTipText ( L"Remove the selected archive from the FileSystem." ); + gui.ArchiveUp = env->addButton ( rect( dim.Width - 575, dim.Height - 530, dim.Width - 515, dim.Height - 514 ), gui.Window,-1, L"up" ); + gui.ArchiveUp->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive up" ); + gui.ArchiveDown = env->addButton ( rect( dim.Width - 510, dim.Height - 530, dim.Width - 440, dim.Height - 514 ), gui.Window,-1, L"down" ); + gui.ArchiveDown->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive down" ); + + + gui.ArchiveList = env->addTable ( rect( 5,dim.Height - 510, dim.Width - 450,dim.Height - 410 ), gui.Window ); + gui.ArchiveList->addColumn ( L"Type", 0 ); + gui.ArchiveList->addColumn ( L"Real File Path", 1 ); + gui.ArchiveList->setColumnWidth ( 0, 60 ); + gui.ArchiveList->setColumnWidth ( 1, 284 ); + gui.ArchiveList->setToolTipText ( L"Show the attached Archives" ); + + + env->addStaticText ( L"Maps:", rect( 5, dim.Height - 400, dim.Width - 450,dim.Height - 380 ),false, false, gui.Window, -1, false ); + gui.MapList = env->addListBox ( rect( 5,dim.Height - 380, dim.Width - 450,dim.Height - 40 ), gui.Window, -1, true ); + gui.MapList->setToolTipText ( L"Show the current Maps in all Archives.\n Double-Click the Map to start the level" ); + + + // create a visible Scene Tree + env->addStaticText ( L"Scenegraph:", rect( dim.Width - 400, dim.Height - 400, dim.Width - 5,dim.Height - 380 ),false, false, gui.Window, -1, false ); + gui.SceneTree = env->addTreeView( rect( dim.Width - 400, dim.Height - 380, dim.Width - 5, dim.Height - 40 ), + gui.Window, -1, true, true, false ); + gui.SceneTree->setToolTipText ( L"Show the current Scenegraph" ); + gui.SceneTree->getRoot()->clearChildren(); + addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); + + + IGUIImageList* imageList = env->createImageList( driver->getTexture ( "iconlist.png" ), + dimension2di( 32, 32 ), true ); + + if ( imageList ) + { + gui.SceneTree->setImageList( imageList ); + imageList->drop (); + } + + + // load the engine logo + gui.Logo = env->addImage( driver->getTexture("irrlichtlogo3.png"), position2d(5, 16 ), true, 0 ); + gui.Logo->setToolTipText ( L"The great Irrlicht Engine" ); + + AddArchive ( "" ); +} + + +/* + Add an Archive to the FileSystems and updates the GUI +*/ +void CQuake3EventHandler::AddArchive ( const path& archiveName ) +{ + IFileSystem *fs = Game->Device->getFileSystem(); + u32 i; + + if ( archiveName.size () ) + { + bool exists = false; + for ( i = 0; i != fs->getFileArchiveCount(); ++i ) + { + if ( fs->getFileArchive(i)->getFileList()->getPath() == archiveName ) + { + exists = true; + break; + } + } + + if (!exists) + { + fs->addFileArchive(archiveName, true, false); + } + } + + // store the current archives in game data + // show the attached Archive in proper order + if ( gui.ArchiveList ) + { + gui.ArchiveList->clearRows(); + + for ( i = 0; i != fs->getFileArchiveCount(); ++i ) + { + IFileArchive * archive = fs->getFileArchive ( i ); + + u32 index = gui.ArchiveList->addRow(i); + + core::stringw typeName; + switch(archive->getType()) + { + case io::EFAT_ZIP: + typeName = "ZIP"; + break; + case io::EFAT_GZIP: + typeName = "gzip"; + break; + case io::EFAT_FOLDER: + typeName = "Mount"; + break; + case io::EFAT_PAK: + typeName = "PAK"; + break; + case io::EFAT_TAR: + typeName = "TAR"; + break; + default: + typeName = "archive"; + } + + gui.ArchiveList->setCellText ( index, 0, typeName ); + gui.ArchiveList->setCellText ( index, 1, archive->getFileList()->getPath() ); + } + } + + + // browse the archives for maps + if ( gui.MapList ) + { + gui.MapList->clear(); + + IGUISpriteBank *bank = Game->Device->getGUIEnvironment()->getSpriteBank("sprite_q3map"); + if ( 0 == bank ) + bank = Game->Device->getGUIEnvironment()->addEmptySpriteBank("sprite_q3map"); + + SGUISprite sprite; + SGUISpriteFrame frame; + core::rect r; + + bank->getSprites().clear(); + bank->getPositions().clear (); + gui.MapList->setSpriteBank ( bank ); + + u32 g = 0; + core::stringw s; + + // browse the attached file system + fs->setFileListSystem ( FILESYSTEM_VIRTUAL ); + fs->changeWorkingDirectoryTo ( "/maps/" ); + IFileList *fileList = fs->createFileList (); + fs->setFileListSystem ( FILESYSTEM_NATIVE ); + + for ( i=0; i< fileList->getFileCount(); ++i) + { + s = fileList->getFullFileName(i); + if ( s.find ( ".bsp" ) >= 0 ) + { + // get level screenshot. reformat texture to 128x128 + path c ( s ); + deletePathFromFilename ( c ); + cutFilenameExtension ( c, c ); + c = path ( "levelshots/" ) + c; + + dimension2du dim ( 128, 128 ); + IVideoDriver * driver = Game->Device->getVideoDriver(); + IImage* image = 0; + ITexture *tex = 0; + path filename; + + filename = c + ".jpg"; + if ( fs->existFile ( filename ) ) + image = driver->createImageFromFile( filename ); + if ( 0 == image ) + { + filename = c + ".tga"; + if ( fs->existFile ( filename ) ) + image = driver->createImageFromFile( filename ); + } + + if ( image ) + { + IImage* filter = driver->createImage ( video::ECF_R8G8B8, dim ); + image->copyToScalingBoxFilter ( filter, 0 ); + image->drop (); + image = filter; + } + + if ( image ) + { + tex = driver->addTexture ( filename, image ); + image->drop (); + } + + + bank->setTexture ( g, tex ); + + r.LowerRightCorner.X = dim.Width; + r.LowerRightCorner.Y = dim.Height; + gui.MapList->setItemHeight ( r.LowerRightCorner.Y + 4 ); + frame.rectNumber = bank->getPositions().size(); + frame.textureNumber = g; + + bank->getPositions().push_back(r); + + sprite.Frames.set_used ( 0 ); + sprite.Frames.push_back(frame); + sprite.frameTime = 0; + bank->getSprites().push_back(sprite); + + gui.MapList->addItem ( s.c_str (), g ); + g += 1; + } + } + fileList->drop (); + + gui.MapList->setSelected ( -1 ); + IGUIScrollBar * bar = (IGUIScrollBar*)gui.MapList->getElementFromId( 0 ); + if ( bar ) + bar->setPos ( 0 ); + + } + +} + +/* + clears the Map in Memory +*/ +void CQuake3EventHandler::dropMap () +{ + IVideoDriver * driver = Game->Device->getVideoDriver(); + + driver->removeAllHardwareBuffers (); + driver->removeAllTextures (); + + Player[0].shutdown (); + + + dropElement ( ItemParent ); + dropElement ( ShaderParent ); + dropElement ( UnresolvedParent ); + dropElement ( FogParent ); + dropElement ( BulletParent ); + + + Impacts.clear(); + + if ( Meta ) + { + Meta = 0; + } + + dropElement ( MapParent ); + dropElement ( SkyNode ); + + // clean out meshes, because textures are invalid + // TODO: better texture handling;-) + IMeshCache *cache = Game->Device->getSceneManager ()->getMeshCache(); + cache->clear (); + Mesh = 0; +} + +/* Load new map +*/ +void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision ) +{ + if ( 0 == mapName.size() ) + return; + + dropMap (); + + IFileSystem *fs = Game->Device->getFileSystem(); + ISceneManager *smgr = Game->Device->getSceneManager (); + + IReadFile* file = fs->createMemoryReadFile(&Game->loadParam, + sizeof(Game->loadParam), L"levelparameter.cfg", false); + + // load cfg file + smgr->getMesh( file ); + file->drop (); + + // load the actual map + Mesh = (IQ3LevelMesh*) smgr->getMesh(mapName); + if ( 0 == Mesh ) + return; + + /* + add the geometry mesh to the Scene ( polygon & patches ) + The Geometry mesh is optimised for faster drawing + */ + + IMesh *geometry = Mesh->getMesh(E_Q3_MESH_GEOMETRY); + if ( 0 == geometry || geometry->getMeshBufferCount() == 0) + return; + + Game->CurrentMapName = mapName; + + //create a collision list + Meta = 0; + + ITriangleSelector * selector = 0; + if (collision) + Meta = smgr->createMetaTriangleSelector(); + + //IMeshBuffer *b0 = geometry->getMeshBuffer(0); + //s32 minimalNodes = b0 ? core::s32_max ( 2048, b0->getVertexCount() / 32 ) : 2048; + s32 minimalNodes = 2048; + + MapParent = smgr->addOctreeSceneNode(geometry, 0, -1, minimalNodes); + MapParent->setName ( mapName ); + if ( Meta ) + { + selector = smgr->createOctreeTriangleSelector( geometry,MapParent, minimalNodes); + //selector = smgr->createTriangleSelector ( geometry, MapParent ); + Meta->addTriangleSelector( selector); + selector->drop (); + } + + // logical parent for the items + ItemParent = smgr->addEmptySceneNode(); + if ( ItemParent ) + ItemParent->setName ( "Item Container" ); + + ShaderParent = smgr->addEmptySceneNode(); + if ( ShaderParent ) + ShaderParent->setName ( "Shader Container" ); + + UnresolvedParent = smgr->addEmptySceneNode(); + if ( UnresolvedParent ) + UnresolvedParent->setName ( "Unresolved Container" ); + + FogParent = smgr->addEmptySceneNode(); + if ( FogParent ) + FogParent->setName ( "Fog Container" ); + + // logical parent for the bullets + BulletParent = smgr->addEmptySceneNode(); + if ( BulletParent ) + BulletParent->setName ( "Bullet Container" ); + + /* + now construct SceneNodes for each Shader + The Objects are stored in the quake mesh E_Q3_MESH_ITEMS + and the Shader ID is stored in the MaterialParameters + mostly dark looking skulls and moving lava.. or green flashing tubes? + */ + Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_ITEMS,ShaderParent, Meta, false ); + Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_FOG,FogParent, 0, false ); + Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_UNRESOLVED,UnresolvedParent, Meta, true ); + + /* + Now construct Models from Entity List + */ + Q3ModelFactory ( Game->loadParam, Game->Device, Mesh, ItemParent, false ); +} + +/* + Adds a SceneNode with an icon to the Scene Tree +*/ +void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent) +{ + IGUITreeViewNode* node; + wchar_t msg[128]; + + s32 imageIndex; + list::ConstIterator it = parent->getChildren().begin(); + for (; it != parent->getChildren().end(); ++it) + { + switch ( (*it)->getType () ) + { + case ESNT_Q3SHADER_SCENE_NODE: imageIndex = 0; break; + case ESNT_CAMERA: imageIndex = 1; break; + case ESNT_EMPTY: imageIndex = 2; break; + case ESNT_MESH: imageIndex = 3; break; + case ESNT_OCTREE: imageIndex = 3; break; + case ESNT_ANIMATED_MESH: imageIndex = 4; break; + case ESNT_SKY_BOX: imageIndex = 5; break; + case ESNT_BILLBOARD: imageIndex = 6; break; + case ESNT_PARTICLE_SYSTEM: imageIndex = 7; break; + case ESNT_TEXT: imageIndex = 8; break; + default:imageIndex = -1; break; + } + + if ( imageIndex < 0 ) + { + swprintf ( msg, 128, L"%hs,%hs", + Game->Device->getSceneManager ()->getSceneNodeTypeName ( (*it)->getType () ), + (*it)->getName() + ); + } + else + { + swprintf ( msg, 128, L"%hs",(*it)->getName() ); + } + + node = nodeParent->addChildBack( msg, 0, imageIndex ); + + // Add all Animators + list::ConstIterator ait = (*it)->getAnimators().begin(); + for (; ait != (*it)->getAnimators().end(); ++ait) + { + imageIndex = -1; + swprintf ( msg, 128, L"%hs", + Game->Device->getSceneManager ()->getAnimatorTypeName ( (*ait)->getType () ) + ); + + switch ( (*ait)->getType () ) + { + case ESNAT_FLY_CIRCLE: + case ESNAT_FLY_STRAIGHT: + case ESNAT_FOLLOW_SPLINE: + case ESNAT_ROTATION: + case ESNAT_TEXTURE: + case ESNAT_DELETION: + case ESNAT_COLLISION_RESPONSE: + case ESNAT_CAMERA_FPS: + case ESNAT_CAMERA_MAYA: + default: + break; + } + node->addChildBack( msg, 0, imageIndex ); + } + + addSceneTreeItem ( *it, node ); + } +} + + +// Adds life! +void CQuake3EventHandler::CreatePlayers() +{ + Player[0].create ( Game->Device, Mesh, MapParent, Meta ); +} + + +// Adds a skydome to the scene +void CQuake3EventHandler::AddSky( u32 dome, const c8 *texture) +{ + ISceneManager *smgr = Game->Device->getSceneManager (); + IVideoDriver * driver = Game->Device->getVideoDriver(); + + bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + if ( 0 == dome ) + { + // irrlicht order + //static const c8*p[] = { "ft", "lf", "bk", "rt", "up", "dn" }; + // quake3 order + static const c8*p[] = { "ft", "rt", "bk", "lf", "up", "dn" }; + + u32 i = 0; + snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); + SkyNode = smgr->addSkyBoxSceneNode( driver->getTexture ( buf ), 0, 0, 0, 0, 0 ); + + if (SkyNode) + { + for ( i = 0; i < 6; ++i ) + { + snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); + SkyNode->getMaterial(i).setTexture ( 0, driver->getTexture ( buf ) ); + } + } + } + else + if ( 1 == dome ) + { + snprintf ( buf, 64, "%s.jpg", texture ); + SkyNode = smgr->addSkyDomeSceneNode( + driver->getTexture( buf ), 32,32, + 1.f, 1.f, 1000.f, 0, 11); + } + else + if ( 2 == dome ) + { + snprintf ( buf, 64, "%s.jpg", texture ); + SkyNode = smgr->addSkyDomeSceneNode( + driver->getTexture( buf ), 16,8, + 0.95f, 2.f, 1000.f, 0, 11); + } + + if (SkyNode) + SkyNode->setName("Skydome"); + //SkyNode->getMaterial(0).ZBuffer = video::EMDF_DEPTH_LESS_EQUAL; + + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); +} + + +// enable GUI elements +void CQuake3EventHandler::SetGUIActive( s32 command) +{ + bool inputState = false; + + ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); + + switch ( command ) + { + case 0: Game->guiActive = 0; inputState = !Game->guiActive; break; + case 1: Game->guiActive = 1; inputState = !Game->guiActive;;break; + case 2: Game->guiActive ^= 1; inputState = !Game->guiActive;break; + case 3: + if ( camera ) + inputState = !camera->isInputReceiverEnabled(); + break; + } + + if ( camera ) + { + camera->setInputReceiverEnabled ( inputState ); + Game->Device->getCursorControl()->setVisible( !inputState ); + } + + if ( gui.Window ) + { + gui.Window->setVisible ( Game->guiActive != 0 ); + } + + if ( Game->guiActive && + gui.SceneTree && Game->Device->getGUIEnvironment()->getFocus() != gui.SceneTree + ) + { + gui.SceneTree->getRoot()->clearChildren(); + addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); + } + + Game->Device->getGUIEnvironment()->setFocus ( Game->guiActive ? gui.Window: 0 ); +} + + +/* + Handle game input +*/ +bool CQuake3EventHandler::OnEvent(const SEvent& eve) +{ + if ( eve.EventType == EET_LOG_TEXT_EVENT ) + { + return false; + } + + if ( Game->guiActive && eve.EventType == EET_GUI_EVENT ) + { + if ( eve.GUIEvent.Caller == gui.MapList && eve.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN ) + { + s32 selected = gui.MapList->getSelected(); + if ( selected >= 0 ) + { + stringw loadMap = gui.MapList->getListItem ( selected ); + if ( 0 == MapParent || loadMap != Game->CurrentMapName ) + { + printf ( "Loading map %ls\n", loadMap.c_str() ); + LoadMap ( loadMap , 1 ); + if ( 0 == Game->loadParam.loadSkyShader ) + { + AddSky ( 1, "skydome2" ); + } + CreatePlayers (); + CreateGUI (); + SetGUIActive ( 0 ); + return true; + } + } + } + else + if ( eve.GUIEvent.Caller == gui.ArchiveRemove && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + Game->Device->getFileSystem()->removeFileArchive( gui.ArchiveList->getSelected() ); + Game->CurrentMapName = ""; + AddArchive ( "" ); + } + else + if ( eve.GUIEvent.Caller == gui.ArchiveAdd && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + if ( 0 == gui.ArchiveFileOpen ) + { + Game->Device->getFileSystem()->setFileListSystem ( FILESYSTEM_NATIVE ); + gui.ArchiveFileOpen = Game->Device->getGUIEnvironment()->addFileOpenDialog ( L"Add Game Archive" , false,gui.Window ); + } + } + else + if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_SELECTED ) + { + AddArchive ( gui.ArchiveFileOpen->getFileName() ); + gui.ArchiveFileOpen = 0; + } + else + if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_DIRECTORY_SELECTED ) + { + AddArchive ( gui.ArchiveFileOpen->getDirectoryName() ); + } + else + if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED ) + { + gui.ArchiveFileOpen = 0; + } + else + if ( ( eve.GUIEvent.Caller == gui.ArchiveUp || eve.GUIEvent.Caller == gui.ArchiveDown ) && + eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + s32 rel = eve.GUIEvent.Caller == gui.ArchiveUp ? -1 : 1; + if ( Game->Device->getFileSystem()->moveFileArchive ( gui.ArchiveList->getSelected (), rel ) ) + { + s32 newIndex = core::s32_clamp ( gui.ArchiveList->getSelected() + rel, 0, gui.ArchiveList->getRowCount() - 1 ); + AddArchive ( "" ); + gui.ArchiveList->setSelected ( newIndex ); + Game->CurrentMapName = ""; + } + } + else + if ( eve.GUIEvent.Caller == gui.VideoDriver && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) + { + Game->deviceParam.DriverType = (E_DRIVER_TYPE) gui.VideoDriver->getItemData ( gui.VideoDriver->getSelected() ); + } + else + if ( eve.GUIEvent.Caller == gui.VideoMode && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) + { + u32 val = gui.VideoMode->getItemData ( gui.VideoMode->getSelected() ); + Game->deviceParam.WindowSize.Width = val >> 16; + Game->deviceParam.WindowSize.Height = val & 0xFFFF; + } + else + if ( eve.GUIEvent.Caller == gui.FullScreen && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + Game->deviceParam.Fullscreen = gui.FullScreen->isChecked(); + } + else + if ( eve.GUIEvent.Caller == gui.Bit32 && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + Game->deviceParam.Bits = gui.Bit32->isChecked() ? 32 : 16; + } + else + if ( eve.GUIEvent.Caller == gui.MultiSample && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) + { + Game->deviceParam.AntiAlias = gui.MultiSample->getPos(); + } + else + if ( eve.GUIEvent.Caller == gui.Tesselation && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) + { + Game->loadParam.patchTesselation = gui.Tesselation->getPos (); + } + else + if ( eve.GUIEvent.Caller == gui.Gamma && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) + { + Game->GammaValue = gui.Gamma->getPos () * 0.01f; + Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); + } + else + if ( eve.GUIEvent.Caller == gui.SetVideoMode && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + Game->retVal = 2; + Game->Device->closeDevice(); + } + else + if ( eve.GUIEvent.Caller == gui.Window && eve.GUIEvent.EventType == gui::EGET_ELEMENT_CLOSED ) + { + Game->Device->closeDevice(); + } + else + if ( eve.GUIEvent.Caller == gui.Collision && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + // set fly through active + Game->flyTroughState ^= 1; + Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); + + printf ( "collision %d\n", Game->flyTroughState == 0 ); + } + else + if ( eve.GUIEvent.Caller == gui.Visible_Map && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + bool v = gui.Visible_Map->isChecked(); + + if ( MapParent ) + { + printf ( "static node set visible %d\n",v ); + MapParent->setVisible ( v ); + } + } + else + if ( eve.GUIEvent.Caller == gui.Visible_Shader && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + bool v = gui.Visible_Shader->isChecked(); + + if ( ShaderParent ) + { + printf ( "shader node set visible %d\n",v ); + ShaderParent->setVisible ( v ); + } + } + else + if ( eve.GUIEvent.Caller == gui.Visible_Skydome && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + if ( SkyNode ) + { + bool v = !SkyNode->isVisible(); + printf ( "skynode set visible %d\n",v ); + SkyNode->setVisible ( v ); + } + } + else + if ( eve.GUIEvent.Caller == gui.Respawn && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + Player[0].respawn (); + } + + return false; + } + + // fire + if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_SPACE && + eve.KeyInput.PressedDown == false) || + (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + ) + { + ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); + if ( camera && camera->isInputReceiverEnabled () ) + { + useItem( Player + 0 ); + } + } + + // gui active + if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_F1 && + eve.KeyInput.PressedDown == false) || + (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) + ) + { + SetGUIActive ( 2 ); + } + + // check if user presses the key + if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.PressedDown == false) + { + // Escape toggles camera Input + if ( eve.KeyInput.Key == irr::KEY_ESCAPE ) + { + SetGUIActive ( 3 ); + } + else + if (eve.KeyInput.Key == KEY_F11) + { + // screenshot are taken without gamma! + IImage* image = Game->Device->getVideoDriver()->createScreenShot(); + if (image) + { + core::vector3df pos; + core::vector3df rot; + ICameraSceneNode * cam = Game->Device->getSceneManager()->getActiveCamera (); + if ( cam ) + { + pos = cam->getPosition (); + rot = cam->getRotation (); + } + + static const c8 *dName[] = { "null", "software", "burning", + "d3d8", "d3d9", "opengl" }; + + snprintf(buf, 256, "%s_%ls_%.0f_%.0f_%.0f_%.0f_%.0f_%.0f.jpg", + dName[Game->Device->getVideoDriver()->getDriverType()], + Game->CurrentMapName.c_str(), + pos.X, pos.Y, pos.Z, + rot.X, rot.Y, rot.Z + ); + path filename ( buf ); + filename.replace ( '/', '_' ); + printf ( "screenshot : %s\n", filename.c_str() ); + Game->Device->getVideoDriver()->writeImageToFile(image, filename, 100 ); + image->drop(); + } + } + else + if (eve.KeyInput.Key == KEY_F9) + { + s32 value = EDS_OFF; + + Game->debugState = ( Game->debugState + 1 ) & 3; + + switch ( Game->debugState ) + { + case 1: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL; break; + case 2: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_SKELETON; break; + } +/* + // set debug map data on/off + debugState = debugState == EDS_OFF ? + EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL: + EDS_OFF; +*/ + if ( ItemParent ) + { + list::ConstIterator it = ItemParent->getChildren().begin(); + for (; it != ItemParent->getChildren().end(); ++it) + { + (*it)->setDebugDataVisible ( value ); + } + } + + if ( ShaderParent ) + { + list::ConstIterator it = ShaderParent->getChildren().begin(); + for (; it != ShaderParent->getChildren().end(); ++it) + { + (*it)->setDebugDataVisible ( value ); + } + } + + if ( UnresolvedParent ) + { + list::ConstIterator it = UnresolvedParent->getChildren().begin(); + for (; it != UnresolvedParent->getChildren().end(); ++it) + { + (*it)->setDebugDataVisible ( value ); + } + } + + if ( FogParent ) + { + list::ConstIterator it = FogParent->getChildren().begin(); + for (; it != FogParent->getChildren().end(); ++it) + { + (*it)->setDebugDataVisible ( value ); + } + } + + if ( SkyNode ) + { + SkyNode->setDebugDataVisible ( value ); + } + + } + else + if (eve.KeyInput.Key == KEY_F8) + { + // set gravity on/off + Game->gravityState ^= 1; + Player[0].cam()->setGravity ( getGravity ( Game->gravityState ? "earth" : "none" ) ); + printf ( "gravity %s\n", Game->gravityState ? "earth" : "none" ); + } + else + if (eve.KeyInput.Key == KEY_F7) + { + // set fly through active + Game->flyTroughState ^= 1; + Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); + if ( gui.Collision ) + gui.Collision->setChecked ( Game->flyTroughState == 0 ); + + printf ( "collision %d\n", Game->flyTroughState == 0 ); + } + else + if (eve.KeyInput.Key == KEY_F2) + { + Player[0].respawn (); + } + else + if (eve.KeyInput.Key == KEY_F3) + { + if ( MapParent ) + { + bool v = !MapParent->isVisible (); + printf ( "static node set visible %d\n",v ); + MapParent->setVisible ( v ); + if ( gui.Visible_Map ) + gui.Visible_Map->setChecked ( v ); + } + } + else + if (eve.KeyInput.Key == KEY_F4) + { + if ( ShaderParent ) + { + bool v = !ShaderParent->isVisible (); + printf ( "shader node set visible %d\n",v ); + ShaderParent->setVisible ( v ); + if ( gui.Visible_Shader ) + gui.Visible_Shader->setChecked ( v ); + } + } + else + if (eve.KeyInput.Key == KEY_F5) + { + if ( FogParent ) + { + bool v = !FogParent->isVisible (); + printf ( "fog node set visible %d\n",v ); + FogParent->setVisible ( v ); + if ( gui.Visible_Fog ) + gui.Visible_Fog->setChecked ( v ); + } + + } + else + if (eve.KeyInput.Key == KEY_F6) + { + if ( UnresolvedParent ) + { + bool v = !UnresolvedParent->isVisible (); + printf ( "unresolved node set visible %d\n",v ); + UnresolvedParent->setVisible ( v ); + if ( gui.Visible_Unresolved ) + gui.Visible_Unresolved->setChecked ( v ); + } + } + } + + // check if user presses the key C ( for crouch) + if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_KEY_C ) + { + // crouch + ISceneNodeAnimatorCollisionResponse *anim = Player[0].cam (); + if ( anim && 0 == Game->flyTroughState ) + { + if ( false == eve.KeyInput.PressedDown ) + { + // stand up + anim->setEllipsoidRadius ( vector3df(30,45,30) ); + anim->setEllipsoidTranslation ( vector3df(0,40,0)); + + } + else + { + // on your knees + anim->setEllipsoidRadius ( vector3df(30,20,30) ); + anim->setEllipsoidTranslation ( vector3df(0,20,0)); + } + return true; + } + } + return false; +} + + + +/* + useItem +*/ +void CQuake3EventHandler::useItem( Q3Player * player) +{ + ISceneManager* smgr = Game->Device->getSceneManager(); + ICameraSceneNode* camera = smgr->getActiveCamera(); + + if (!camera) + return; + + SParticleImpact imp; + imp.when = 0; + + // get line of camera + + vector3df start = camera->getPosition(); + + if ( player->WeaponNode ) + { + start.X += 0.f; + start.Y += 0.f; + start.Z += 0.f; + } + + vector3df end = (camera->getTarget() - start); + end.normalize(); + start += end*20.0f; + + end = start + (end * camera->getFarValue()); + + triangle3df triangle; + line3d line(start, end); + + // get intersection point with map + scene::ISceneNode* hitNode; + if (smgr->getSceneCollisionManager()->getCollisionPoint( + line, Meta, end, triangle,hitNode)) + { + // collides with wall + vector3df out = triangle.getNormal(); + out.setLength(0.03f); + + imp.when = 1; + imp.outVector = out; + imp.pos = end; + + player->setAnim ( "pow" ); + player->Anim[1].next += player->Anim[1].delta; + } + else + { + // doesnt collide with wall + vector3df start = camera->getPosition(); + if ( player->WeaponNode ) + { + //start.X += 10.f; + //start.Y += -5.f; + //start.Z += 1.f; + } + + vector3df end = (camera->getTarget() - start); + end.normalize(); + start += end*20.0f; + end = start + (end * camera->getFarValue()); + } + + // create fire ball + ISceneNode* node = 0; + node = smgr->addBillboardSceneNode( BulletParent,dimension2d(10,10), start); + + node->setMaterialFlag(EMF_LIGHTING, false); + node->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture("fireball.bmp")); + node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); + node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR); + + f32 length = (f32)(end - start).getLength(); + const f32 speed = 5.8f; + u32 time = (u32)(length / speed); + + ISceneNodeAnimator* anim = 0; + + // set flight line + + anim = smgr->createFlyStraightAnimator(start, end, time); + node->addAnimator(anim); + anim->drop(); + + snprintf ( buf, 64, "bullet: %s on %.1f,%1.f,%1.f", + imp.when ? "hit" : "nohit", end.X, end.Y, end.Z ); + node->setName ( buf ); + + + anim = smgr->createDeleteAnimator(time); + node->addAnimator(anim); + anim->drop(); + + if (imp.when) + { + // create impact note + imp.when = Game->Device->getTimer()->getTime() + + (time + (s32) ( ( 1.f + Noiser::get() ) * 250.f )); + Impacts.push_back(imp); + } + + // play sound +} + +// rendered when bullets hit something +void CQuake3EventHandler::createParticleImpacts( u32 now ) +{ + ISceneManager* sm = Game->Device->getSceneManager(); + + struct smokeLayer + { + const c8 * texture; + f32 scale; + f32 minparticleSize; + f32 maxparticleSize; + f32 boxSize; + u32 minParticle; + u32 maxParticle; + u32 fadeout; + u32 lifetime; + }; + + smokeLayer smoke[] = + { + { "smoke2.jpg", 0.4f, 1.5f, 18.f, 20.f, 20, 50, 2000, 10000 }, + { "smoke3.jpg", 0.2f, 1.2f, 15.f, 20.f, 10, 30, 1000, 12000 } + }; + + + u32 i; + u32 g; + s32 factor = 1; + for ( g = 0; g != 2; ++g ) + { + smoke[g].minParticle *= factor; + smoke[g].maxParticle *= factor; + smoke[g].lifetime *= factor; + smoke[g].boxSize *= Noiser::get() * 0.5f; + } + + for ( i=0; i < Impacts.size(); ++i) + { + if (now < Impacts[i].when) + continue; + + // create smoke particle system + IParticleSystemSceneNode* pas = 0; + + for ( g = 0; g != 2; ++g ) + { + pas = sm->addParticleSystemSceneNode(false, BulletParent, -1, Impacts[i].pos); + + snprintf ( buf, 64, "bullet impact smoke at %.1f,%.1f,%1.f", + Impacts[i].pos.X,Impacts[i].pos.Y,Impacts[i].pos.Z); + pas->setName ( buf ); + + // create a flat smoke + vector3df direction = Impacts[i].outVector; + direction *= smoke[g].scale; + IParticleEmitter* em = pas->createBoxEmitter( + aabbox3d(-4.f,0.f,-4.f,20.f,smoke[g].minparticleSize,20.f), + direction,smoke[g].minParticle, smoke[g].maxParticle, + video::SColor(0,0,0,0),video::SColor(0,128,128,128), + 250,4000, 60); + + em->setMinStartSize (dimension2d( smoke[g].minparticleSize, smoke[g].minparticleSize)); + em->setMaxStartSize (dimension2d( smoke[g].maxparticleSize, smoke[g].maxparticleSize)); + + pas->setEmitter(em); + em->drop(); + + // particles get invisible + IParticleAffector* paf = pas->createFadeOutParticleAffector( + video::SColor ( 0, 0, 0, 0 ), smoke[g].fadeout); + pas->addAffector(paf); + paf->drop(); + + // particle system life time + ISceneNodeAnimator* anim = sm->createDeleteAnimator( smoke[g].lifetime); + pas->addAnimator(anim); + anim->drop(); + + pas->setMaterialFlag(video::EMF_LIGHTING, false); + pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); + pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); + pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture )); + } + + + // play impact sound + #ifdef USE_IRRKLANG +/* + if (irrKlang) + { + audio::ISound* sound = + irrKlang->play3D(impactSound, Impacts[i].pos, false, false, true); + + if (sound) + { + // adjust max value a bit to make to sound of an impact louder + sound->setMinDistance(400); + sound->drop(); + } + } +*/ + #endif + + + // delete entry + Impacts.erase(i); + i--; + } +} + +/* + render +*/ +void CQuake3EventHandler::Render() +{ + IVideoDriver * driver = Game->Device->getVideoDriver(); + if ( 0 == driver ) + return; + + // TODO: This does not work, yet. + const bool anaglyph=false; + if (anaglyph) + { + scene::ICameraSceneNode* cameraOld = Game->Device->getSceneManager()->getActiveCamera(); + driver->beginScene(true, true, SColor(0,0,0,0)); + driver->getOverrideMaterial().Material.ColorMask = ECP_NONE; + driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; + driver->getOverrideMaterial().EnablePasses = ESNRP_SKY_BOX + + ESNRP_SOLID + + ESNRP_TRANSPARENT + + ESNRP_TRANSPARENT_EFFECT + + ESNRP_SHADOW; + Game->Device->getSceneManager()->drawAll(); + driver->clearZBuffer(); + + const vector3df oldPosition = cameraOld->getPosition(); + const vector3df oldTarget = cameraOld->getTarget(); + const matrix4 startMatrix = cameraOld->getAbsoluteTransformation(); + const vector3df focusPoint = (oldTarget - + cameraOld->getAbsolutePosition()).setLength(10000) + + cameraOld->getAbsolutePosition() ; + + scene::ICameraSceneNode* camera = cameraOld;//Game->Device->getSceneManager()->addCameraSceneNode(); + + //Left eye... + vector3df pos; + matrix4 move; + + move.setTranslation( vector3df(-1.5f,0.0f,0.0f) ); + pos=(startMatrix*move).getTranslation(); + + driver->getOverrideMaterial().Material.ColorMask = ECP_RED; + driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; + driver->getOverrideMaterial().EnablePasses = + ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| + ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; + + camera->setPosition(pos); + camera->setTarget(focusPoint); + + Game->Device->getSceneManager()->drawAll(); + driver->clearZBuffer(); + + //Right eye... + move.setTranslation( vector3df(1.5f,0.0f,0.0f) ); + pos=(startMatrix*move).getTranslation(); + + driver->getOverrideMaterial().Material.ColorMask = ECP_GREEN + ECP_BLUE; + driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; + driver->getOverrideMaterial().EnablePasses = + ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| + ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; + + camera->setPosition(pos); + camera->setTarget(focusPoint); + + Game->Device->getSceneManager()->drawAll(); + + driver->getOverrideMaterial().Material.ColorMask=ECP_ALL; + driver->getOverrideMaterial().EnableFlags=0; + driver->getOverrideMaterial().EnablePasses=0; + + if (camera != cameraOld) + { + Game->Device->getSceneManager()->setActiveCamera(cameraOld); + camera->remove(); + } + else + { + camera->setPosition(oldPosition); + camera->setTarget(oldTarget); + } + } + else + { + driver->beginScene(true, true, SColor(0,0,0,0)); + Game->Device->getSceneManager()->drawAll(); + } + Game->Device->getGUIEnvironment()->drawAll(); + driver->endScene(); +} + +/* + update the generic scene node +*/ +void CQuake3EventHandler::Animate() +{ + u32 now = Game->Device->getTimer()->getTime(); + + Q3Player * player = Player + 0; + + checkTimeFire ( player->Anim, 4, now ); + + // Query Scene Manager attributes + if ( player->Anim[0].flags & FIRED ) + { + ISceneManager *smgr = Game->Device->getSceneManager (); + wchar_t msg[128]; + IVideoDriver * driver = Game->Device->getVideoDriver(); + + IAttributes * attr = smgr->getParameters(); + swprintf ( msg, 128, + L"Q3 %s [%ls], FPS:%03d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)", + Game->CurrentMapName.c_str(), + driver->getName(), + driver->getFPS (), + (f32) driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ), + attr->getAttributeAsInt ( "culled" ), + attr->getAttributeAsInt ( "calls" ), + attr->getAttributeAsInt ( "drawn_solid" ), + attr->getAttributeAsInt ( "drawn_transparent" ), + attr->getAttributeAsInt ( "drawn_transparent_effect" ) + ); + Game->Device->setWindowCaption( msg ); + + swprintf ( msg, 128, + L"%03d fps, F1 GUI on/off, F2 respawn, F3-F6 toggle Nodes, F7 Collision on/off" + L", F8 Gravity on/off, Right Mouse Toggle GUI", + Game->Device->getVideoDriver()->getFPS () + ); + if ( gui.StatusLine ) + gui.StatusLine->setText ( msg ); + player->Anim[0].flags &= ~FIRED; + } + + // idle.. + if ( player->Anim[1].flags & FIRED ) + { + if ( strcmp ( player->animation, "idle" ) ) + player->setAnim ( "idle" ); + + player->Anim[1].flags &= ~FIRED; + } + + createParticleImpacts ( now ); + +} + + +/* The main game states +*/ +void runGame ( GameData *game ) +{ + if ( game->retVal >= 3 ) + return; + + game->Device = (*game->createExDevice) ( game->deviceParam ); + if ( 0 == game->Device) + { + // could not create selected driver. + game->retVal = 0; + return; + } + + // create an event receiver based on current game data + CQuake3EventHandler *eventHandler = new CQuake3EventHandler( game ); + + // load stored config + game->load ( "explorer.cfg" ); + + // add our media directory and archive to the file system + for ( u32 i = 0; i < game->CurrentArchiveList.size(); ++i ) + { + eventHandler->AddArchive ( game->CurrentArchiveList[i] ); + } + + // Load a Map or startup to the GUI + if ( game->CurrentMapName.size () ) + { + eventHandler->LoadMap ( game->CurrentMapName, 1 ); + if ( 0 == game->loadParam.loadSkyShader ) + eventHandler->AddSky ( 1, "skydome2" ); + eventHandler->CreatePlayers (); + eventHandler->CreateGUI (); + eventHandler->SetGUIActive ( 0 ); + + // set player to last position on restart + if ( game->retVal == 2 ) + { + eventHandler->GetPlayer( 0 )->setpos ( game->PlayerPosition, game->PlayerRotation ); + } + } + else + { + // start up empty + eventHandler->AddSky ( 1, "skydome2" ); + eventHandler->CreatePlayers (); + eventHandler->CreateGUI (); + eventHandler->SetGUIActive ( 1 ); + background_music ( "IrrlichtTheme.ogg" ); + } + + + game->retVal = 3; + while( game->Device->run() ) + { + eventHandler->Animate (); + eventHandler->Render (); + //if ( !game->Device->isWindowActive() ) + game->Device->yield(); + } + + game->Device->setGammaRamp ( 1.f, 1.f, 1.f, 0.f, 0.f ); + delete eventHandler; +} + +#if defined (_IRR_WINDOWS_) && 0 + #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") +#endif + + +/* The main routine, doing all setup +*/ +int IRRCALLCONV main(int argc, char* argv[]) +{ + path prgname(argv[0]); + GameData game ( deletePathFromPath ( prgname, 1 ) ); + + // dynamically load irrlicht + const c8 * dllName = argc > 1 ? argv[1] : "irrlicht.dll"; + game.createExDevice = load_createDeviceEx ( dllName ); + if ( 0 == game.createExDevice ) + { + game.retVal = 3; + printf ( "Could not load %s.\n", dllName ); + return game.retVal; // could not load dll + } + + // start without asking for driver + game.retVal = 1; + do + { + // if driver could not created, ask for another driver + if ( game.retVal == 0 ) + { + game.setDefault (); + // ask user for driver + game.deviceParam.DriverType=driverChoiceConsole(); + if (game.deviceParam.DriverType==video::EDT_COUNT) + game.retVal = 3; + } + runGame ( &game ); + } while ( game.retVal < 3 ); + + return game.retVal; +} + +/* +**/ diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.cpp b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.cpp index d0f09b2..fc95a1d 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.cpp +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.cpp @@ -1,824 +1,824 @@ -/*! - Model Factory. - create the additional scenenodes for ( bullets, health... ) - - Defines the Entities for Quake3 -*/ - -#include -#include "q3factory.h" -#include "sound.h" - -using namespace irr; -using namespace scene; -using namespace gui; -using namespace video; -using namespace core; -using namespace quake3; - -//! This list is based on the original quake3. -static const SItemElement Quake3ItemElement [] = { -{ "item_health", - {"models/powerups/health/medium_cross.md3", - "models/powerups/health/medium_sphere.md3"}, - "sound/items/n_health.wav", - "icons/iconh_yellow", - "25 Health", - 25, - HEALTH, - SUB_NONE, - SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 -}, -{ "item_health_large", - "models/powerups/health/large_cross.md3", - "models/powerups/health/large_sphere.md3", - "sound/items/l_health.wav", - "icons/iconh_red", - "50 Health", - 50, - HEALTH, - SUB_NONE, - SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 -}, -{ - "item_health_mega", - "models/powerups/health/mega_cross.md3", - "models/powerups/health/mega_sphere.md3", - "sound/items/m_health.wav", - "icons/iconh_mega", - "Mega Health", - 100, - HEALTH, - SUB_NONE, - SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 -}, -{ - "item_health_small", - "models/powerups/health/small_cross.md3", - "models/powerups/health/small_sphere.md3", - "sound/items/s_health.wav", - "icons/iconh_green", - "5 Health", - 5, - HEALTH, - SUB_NONE, - SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 -}, -{ "ammo_bullets", - "models/powerups/ammo/machinegunam.md3", - "", - "sound/misc/am_pkup.wav", - "icons/icona_machinegun", - "Bullets", - 50, - AMMO, - MACHINEGUN, - SPECIAL_SFX_BOUNCE, -}, -{ - "ammo_cells", - "models/powerups/ammo/plasmaam.md3", - "", - "sound/misc/am_pkup.wav", - "icons/icona_plasma", - "Cells", - 30, - AMMO, - PLASMAGUN, - SPECIAL_SFX_BOUNCE -}, -{ "ammo_rockets", - "models/powerups/ammo/rocketam.md3", - "", - "", - "icons/icona_rocket", - "Rockets", - 5, - AMMO, - ROCKET_LAUNCHER, - SPECIAL_SFX_ROTATE -}, -{ - "ammo_shells", - "models/powerups/ammo/shotgunam.md3", - "", - "sound/misc/am_pkup.wav", - "icons/icona_shotgun", - "Shells", - 10, - AMMO, - SHOTGUN, - SPECIAL_SFX_ROTATE -}, -{ - "ammo_slugs", - "models/powerups/ammo/railgunam.md3", - "", - "sound/misc/am_pkup.wav", - "icons/icona_railgun", - "Slugs", - 10, - AMMO, - RAILGUN, - SPECIAL_SFX_ROTATE -}, -{ - "item_armor_body", - "models/powerups/armor/armor_red.md3", - "", - "sound/misc/ar2_pkup.wav", - "icons/iconr_red", - "Heavy Armor", - 100, - ARMOR, - SUB_NONE, - SPECIAL_SFX_ROTATE -}, -{ - "item_armor_combat", - "models/powerups/armor/armor_yel.md3", - "", - "sound/misc/ar2_pkup.wav", - "icons/iconr_yellow", - "Armor", - 50, - ARMOR, - SUB_NONE, - SPECIAL_SFX_ROTATE -}, -{ - "item_armor_shard", - "models/powerups/armor/shard.md3", - "", - "sound/misc/ar1_pkup.wav", - "icons/iconr_shard", - "Armor Shared", - 5, - ARMOR, - SUB_NONE, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_gauntlet", - "models/weapons2/gauntlet/gauntlet.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_gauntlet", - "Gauntlet", - 0, - WEAPON, - GAUNTLET, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_shotgun", - "models/weapons2/shotgun/shotgun.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_shotgun", - "Shotgun", - 10, - WEAPON, - SHOTGUN, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_machinegun", - "models/weapons2/machinegun/machinegun.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_machinegun", - "Machinegun", - 40, - WEAPON, - MACHINEGUN, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_grenadelauncher", - "models/weapons2/grenadel/grenadel.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_grenade", - "Grenade Launcher", - 10, - WEAPON, - GRENADE_LAUNCHER, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_rocketlauncher", - "models/weapons2/rocketl/rocketl.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_rocket", - "Rocket Launcher", - 10, - WEAPON, - ROCKET_LAUNCHER, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_lightning", - "models/weapons2/lightning/lightning.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_lightning", - "Lightning Gun", - 100, - WEAPON, - LIGHTNING, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_railgun", - "models/weapons2/railgun/railgun.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_railgun", - "Railgun", - 10, - WEAPON, - RAILGUN, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_plasmagun", - "models/weapons2/plasma/plasma.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_plasma", - "Plasma Gun", - 50, - WEAPON, - PLASMAGUN, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_bfg", - "models/weapons2/bfg/bfg.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_bfg", - "BFG10K", - 20, - WEAPON, - BFG, - SPECIAL_SFX_ROTATE -}, -{ - "weapon_grapplinghook", - "models/weapons2/grapple/grapple.md3", - "", - "sound/misc/w_pkup.wav", - "icons/iconw_grapple", - "Grappling Hook", - 0, - WEAPON, - GRAPPLING_HOOK, - SPECIAL_SFX_ROTATE -}, -{ - 0 -} - -}; - - -/*! -*/ -const SItemElement * getItemElement ( const stringc& key ) -{ - const SItemElement *item = Quake3ItemElement; - - while ( item->key ) - { - if ( 0 == strcmp ( key.c_str(), item->key ) ) - return item; - item += 1; - } - return 0; -} - -/*! - Quake3 Model Factory. - Takes the mesh buffers and creates scenenodes for their associated shaders -*/ -void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, - IrrlichtDevice *device, - IQ3LevelMesh* mesh, - eQ3MeshIndex meshIndex, - ISceneNode *parent, - IMetaTriangleSelector *meta, - bool showShaderName ) -{ - if ( 0 == mesh || 0 == device ) - return; - - IMeshSceneNode* node = 0; - ISceneManager* smgr = device->getSceneManager(); - ITriangleSelector * selector = 0; - - // the additional mesh can be quite huge and is unoptimized - // Save to cast to SMesh - SMesh * additional_mesh = (SMesh*) mesh->getMesh ( meshIndex ); - if ( 0 == additional_mesh || additional_mesh->getMeshBufferCount() == 0) - return; - - char buf[128]; - if ( loadParam.verbose > 0 ) - { - loadParam.startTime = device->getTimer()->getRealTime(); - if ( loadParam.verbose > 1 ) - { - snprintf(buf, 128, "q3shaderfactory start" ); - device->getLogger()->log( buf, ELL_INFORMATION); - } - } - - IGUIFont *font = 0; - if ( showShaderName ) - font = device->getGUIEnvironment()->getFont("fontlucida.png"); - - IVideoDriver *driver = device->getVideoDriver(); - - // create helper textures - if ( 1 ) - { - tTexArray tex; - u32 pos = 0; - getTextures ( tex, "$redimage $blueimage $whiteimage $checkerimage", pos, - device->getFileSystem(), driver ); - } - - s32 sceneNodeID = 0; - for ( u32 i = 0; i!= additional_mesh->getMeshBufferCount (); ++i ) - { - IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i ); - const SMaterial &material = meshBuffer->getMaterial(); - - //! The ShaderIndex is stored in the second material parameter - s32 shaderIndex = (s32) material.MaterialTypeParam2; - - // the meshbuffer can be rendered without additional support, or it has no shader - IShader *shader = (IShader *) mesh->getShader ( shaderIndex ); - - // no shader, or mapped to existing material - if ( 0 == shader ) - { - -#if 1 - // clone mesh - SMesh * m = new SMesh (); - m->addMeshBuffer ( meshBuffer ); - SMaterial &mat = m->getMeshBuffer( 0 )->getMaterial(); - if ( mat.getTexture( 0 ) == 0 ) - mat.setTexture ( 0, driver->getTexture ( "$blueimage" ) ); - if ( mat.getTexture( 1 ) == 0 ) - mat.setTexture ( 1, driver->getTexture ( "$redimage" ) ); - - IMesh * store = smgr->getMeshManipulator ()->createMeshWith2TCoords ( m ); - m->drop(); - - node = smgr->addMeshSceneNode ( store, parent, sceneNodeID ); - node->setAutomaticCulling ( scene::EAC_OFF ); - store->drop (); - sceneNodeID += 1; -#endif - } - else if ( 1 ) - { -/* - stringc s; - dumpShader ( s, shader ); - printf ( s.c_str () ); -*/ - // create sceneNode - node = smgr->addQuake3SceneNode ( meshBuffer, shader, parent, sceneNodeID ); - node->setAutomaticCulling ( scene::EAC_FRUSTUM_BOX ); - sceneNodeID += 1; - } - - // show Debug Shader Name - if ( showShaderName && node ) - { - swprintf ( (wchar_t*) buf, 64, L"%hs:%d", node->getName(),node->getID() ); - smgr->addBillboardTextSceneNode( - font, - (wchar_t*) buf, - node, - dimension2d(80.0f, 8.0f), - vector3df(0, 10, 0), - sceneNodeID); - sceneNodeID += 1; - } - - // create Portal Rendertargets - if ( shader ) - { - const SVarGroup *group = shader->getGroup(1); - if ( group->isDefined( "surfaceparm", "portal" ) ) - { - } - - } - - - // add collision - // find out if shader is marked as nonsolid - u8 doCreate = meta !=0 ; - - if ( shader ) - { - const SVarGroup *group = shader->getGroup(1); - if ( group->isDefined( "surfaceparm", "trans" ) - // || group->isDefined( "surfaceparm", "sky" ) - // || group->isDefined( "surfaceparm", "nonsolid" ) - ) - { - if ( !group->isDefined( "surfaceparm", "metalsteps" ) ) - { - doCreate = 0; - } - } - } - - if ( doCreate ) - { - IMesh *m = 0; - - //! controls if triangles are modified by the scenenode during runtime - bool takeOriginal = true; - - if ( takeOriginal ) - { - m = new SMesh (); - ((SMesh*) m )->addMeshBuffer (meshBuffer); - } - else - { - m = node->getMesh(); - } - - //selector = smgr->createOctreeTriangleSelector ( m, 0, 128 ); - selector = smgr->createTriangleSelector ( m, 0 ); - meta->addTriangleSelector ( selector ); - selector->drop (); - - if ( takeOriginal ) - { - delete m; - } - } - - } - -#if 0 - if ( meta ) - { - selector = smgr->createOctreeTriangleSelector ( additional_mesh, 0 ); - meta->addTriangleSelector ( selector ); - selector->drop (); - } -#endif - - if ( loadParam.verbose > 0 ) - { - loadParam.endTime = device->getTimer()->getRealTime (); - snprintf(buf, 128, "q3shaderfactory needed %04d ms to create %d shader nodes", - loadParam.endTime - loadParam.startTime, - sceneNodeID - ); - device->getLogger()->log(buf, ELL_INFORMATION); - } - -} - - -/*! - create Items from Entity -*/ -void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, - IrrlichtDevice *device, - IQ3LevelMesh* masterMesh, - ISceneNode *parent, - bool showShaderName - ) -{ - if ( 0 == masterMesh ) - return; - - tQ3EntityList &entity = masterMesh->getEntityList (); - ISceneManager* smgr = device->getSceneManager(); - - - char buf[128]; - const SVarGroup *group; - IEntity search; - s32 index; - s32 lastIndex; - -/* - stringc s; - FILE *f = 0; - f = fopen ( "entity.txt", "wb" ); - for ( index = 0; (u32) index < entityList.size (); ++index ) - { - const IEntity *entity = &entityList[ index ]; - s = entity->name; - dumpShader ( s, entity ); - fwrite ( s.c_str(), 1, s.size(), f ); - } - fclose ( f ); -*/ - IAnimatedMeshMD3* model; - SMD3Mesh * mesh; - const SMD3MeshBuffer *meshBuffer; - IMeshSceneNode* node; - ISceneNodeAnimator* anim; - const IShader *shader; - u32 pos; - vector3df p; - u32 nodeCount = 0; - tTexArray textureArray; - - IGUIFont *font = 0; - if ( showShaderName ) - font = device->getGUIEnvironment()->getFont("fontlucida.png"); - - const SItemElement *itemElement; - - // walk list - for ( index = 0; (u32) index < entity.size(); ++index ) - { - itemElement = getItemElement ( entity[index].name ); - if ( 0 == itemElement ) - continue; - - pos = 0; - p = getAsVector3df ( entity[index].getGroup(1)->get ( "origin" ), pos ); - - nodeCount += 1; - for ( u32 g = 0; g < 2; ++g ) - { - if ( 0 == itemElement->model[g] || itemElement->model[g][0] == 0 ) - continue; - model = (IAnimatedMeshMD3*) smgr->getMesh( itemElement->model[g] ); - if ( 0 == model ) - continue; - - mesh = model->getOriginalMesh(); - for ( u32 j = 0; j != mesh->Buffer.size (); ++j ) - { - meshBuffer = mesh->Buffer[j]; - if ( 0 == meshBuffer ) - continue; - - shader = masterMesh->getShader ( meshBuffer->Shader.c_str(), false ); - IMeshBuffer *final = model->getMesh(0)->getMeshBuffer(j); - if ( shader ) - { - //!TODO: Hack don't modify the vertexbuffer. make it better;-) - final->getMaterial().ColorMask = 0; - node = smgr->addQuake3SceneNode ( final, shader, parent ); - final->getMaterial().ColorMask = 15; - } - else - { - // clone mesh - SMesh * m = new SMesh (); - m->addMeshBuffer ( final ); - node = smgr->addMeshSceneNode ( m, parent ); - m->drop(); - } - - if ( 0 == node ) - { - snprintf ( buf, 128, "q3ModelFactory shader %s failed", meshBuffer->Shader.c_str() ); - device->getLogger()->log ( buf ); - continue; - } - - // node was maybe centered by shaderscenenode - node->setPosition ( p ); - node->setName ( meshBuffer->Shader ); - node->setAutomaticCulling ( scene::EAC_BOX ); - - // add special effects to node - if ( itemElement->special & SPECIAL_SFX_ROTATE || - (g == 0 && itemElement->special & SPECIAL_SFX_ROTATE_1) - ) - { - anim = smgr->createRotationAnimator ( vector3df ( 0.f, - 2.f, 0.f ) ); - node->addAnimator ( anim ); - anim->drop (); - } - - if ( itemElement->special & SPECIAL_SFX_BOUNCE ) - { - //anim = smgr->createFlyStraightAnimator ( - // p, p + vector3df ( 0.f, 60.f, 0.f ), 1000, true, true ); - anim = smgr->createFlyCircleAnimator ( - p + vector3df( 0.f, 20.f, 0.f ), - 20.f, - 0.005f, - vector3df ( 1.f, 0.f, 0.f ), - core::fract ( nodeCount * 0.05f ), - 1.f - ); - node->addAnimator ( anim ); - anim->drop (); - } - } - } - // show name - if ( showShaderName ) - { - swprintf ( (wchar_t*) buf, sizeof(buf) / 2, L"%hs", itemElement->key ); - smgr->addBillboardTextSceneNode( - font, - (wchar_t*) buf, - parent, - dimension2d(80.0f, 8.0f), - p + vector3df(0, 30, 0), - 0); - } - } - - // music - search.name = "worldspawn"; - index = entity.binary_search_multi ( search, lastIndex ); - - if ( index >= 0 ) - { - group = entity[ index ].getGroup(1); - background_music ( group->get ( "music" ).c_str () ); - } - - // music - search.name = "worldspawn"; - index = entity.binary_search_multi ( search, lastIndex ); - - if ( index >= 0 ) - { - group = entity[ index ].getGroup(1); - background_music ( group->get ( "music" ).c_str () ); - } - - //IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2"); - //IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); - -} - -/*! - so we need a good starting Position in the level. - we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" -*/ -s32 Q3StartPosition ( IQ3LevelMesh* mesh, - ICameraSceneNode* camera, - s32 startposIndex, - const vector3df &translation - ) -{ - if ( 0 == mesh ) - return 0; - - tQ3EntityList &entityList = mesh->getEntityList (); - - IEntity search; - search.name = "info_player_start"; // "info_player_deathmatch"; - - // find all entities in the multi-list - s32 lastIndex; - s32 index = entityList.binary_search_multi ( search, lastIndex ); - - if ( index < 0 ) - { - search.name = "info_player_deathmatch"; - index = entityList.binary_search_multi ( search, lastIndex ); - } - - if ( index < 0 ) - return 0; - - index += core::clamp ( startposIndex, 0, lastIndex - index ); - - u32 parsepos; - - const SVarGroup *group; - group = entityList[ index ].getGroup(1); - - parsepos = 0; - vector3df pos = getAsVector3df ( group->get ( "origin" ), parsepos ); - pos += translation; - - parsepos = 0; - f32 angle = getAsFloat ( group->get ( "angle"), parsepos ); - - vector3df target ( 0.f, 0.f, 1.f ); - target.rotateXZBy ( angle - 90.f, vector3df () ); - - if ( camera ) - { - camera->setPosition ( pos ); - camera->setTarget ( pos + target ); - //! New. FPSCamera and animators catches reset on animate 0 - camera->OnAnimate ( 0 ); - } - return lastIndex - index + 1; -} - - -/*! - gets a accumulated force on a given surface -*/ -vector3df getGravity ( const c8 * surface ) -{ - if ( 0 == strcmp ( surface, "earth" ) ) return vector3df ( 0.f, -90.f, 0.f ); - if ( 0 == strcmp ( surface, "moon" ) ) return vector3df ( 0.f, -6.f / 100.f, 0.f ); - if ( 0 == strcmp ( surface, "water" ) ) return vector3df ( 0.1f / 100.f, -2.f / 100.f, 0.f ); - if ( 0 == strcmp ( surface, "ice" ) ) return vector3df ( 0.2f / 100.f, -9.f / 100.f, 0.3f / 100.f ); - - return vector3df ( 0.f, 0.f, 0.f ); -} - - - -/* - Dynamically load the Irrlicht Library -*/ - -#if defined(_IRR_WINDOWS_API_) -#ifdef _MSC_VER -#pragma comment(lib, "Irrlicht.lib") -#endif - -#include - -funcptr_createDevice load_createDevice ( const c8 * filename) -{ - return (funcptr_createDevice) GetProcAddress ( LoadLibrary ( filename ), "createDevice" ); -} - -funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename) -{ - return (funcptr_createDeviceEx) GetProcAddress ( LoadLibrary ( filename ), "createDeviceEx" ); -} - -#else - -// TODO: Dynamic Loading for other os -funcptr_createDevice load_createDevice ( const c8 * filename) -{ - return createDevice; -} - -funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename) -{ - return createDeviceEx; -} - -#endif - -/* - get the current collision response camera animator -*/ -ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * device ) -{ - ICameraSceneNode *camera = device->getSceneManager()->getActiveCamera(); - ISceneNodeAnimatorCollisionResponse *a = 0; - - list::ConstIterator it = camera->getAnimators().begin(); - for (; it != camera->getAnimators().end(); ++it) - { - a = (ISceneNodeAnimatorCollisionResponse*) (*it); - if ( a->getType() == ESNAT_COLLISION_RESPONSE ) - return a; - } - - return 0; -} - - -//! internal Animation -void setTimeFire ( TimeFire *t, u32 delta, u32 flags ) -{ - t->flags = flags; - t->next = 0; - t->delta = delta; -} - - -void checkTimeFire ( TimeFire *t, u32 listSize, u32 now ) -{ - u32 i; - for ( i = 0; i < listSize; ++i ) - { - if ( now < t[i].next ) - continue; - - t[i].next = core::max_ ( now + t[i].delta, t[i].next + t[i].delta ); - t[i].flags |= FIRED; - } -} +/*! + Model Factory. + create the additional scenenodes for ( bullets, health... ) + + Defines the Entities for Quake3 +*/ + +#include +#include "q3factory.h" +#include "sound.h" + +using namespace irr; +using namespace scene; +using namespace gui; +using namespace video; +using namespace core; +using namespace quake3; + +//! This list is based on the original quake3. +static const SItemElement Quake3ItemElement [] = { +{ "item_health", + {"models/powerups/health/medium_cross.md3", + "models/powerups/health/medium_sphere.md3"}, + "sound/items/n_health.wav", + "icons/iconh_yellow", + "25 Health", + 25, + HEALTH, + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 +}, +{ "item_health_large", + "models/powerups/health/large_cross.md3", + "models/powerups/health/large_sphere.md3", + "sound/items/l_health.wav", + "icons/iconh_red", + "50 Health", + 50, + HEALTH, + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 +}, +{ + "item_health_mega", + "models/powerups/health/mega_cross.md3", + "models/powerups/health/mega_sphere.md3", + "sound/items/m_health.wav", + "icons/iconh_mega", + "Mega Health", + 100, + HEALTH, + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 +}, +{ + "item_health_small", + "models/powerups/health/small_cross.md3", + "models/powerups/health/small_sphere.md3", + "sound/items/s_health.wav", + "icons/iconh_green", + "5 Health", + 5, + HEALTH, + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 +}, +{ "ammo_bullets", + "models/powerups/ammo/machinegunam.md3", + "", + "sound/misc/am_pkup.wav", + "icons/icona_machinegun", + "Bullets", + 50, + AMMO, + MACHINEGUN, + SPECIAL_SFX_BOUNCE, +}, +{ + "ammo_cells", + "models/powerups/ammo/plasmaam.md3", + "", + "sound/misc/am_pkup.wav", + "icons/icona_plasma", + "Cells", + 30, + AMMO, + PLASMAGUN, + SPECIAL_SFX_BOUNCE +}, +{ "ammo_rockets", + "models/powerups/ammo/rocketam.md3", + "", + "", + "icons/icona_rocket", + "Rockets", + 5, + AMMO, + ROCKET_LAUNCHER, + SPECIAL_SFX_ROTATE +}, +{ + "ammo_shells", + "models/powerups/ammo/shotgunam.md3", + "", + "sound/misc/am_pkup.wav", + "icons/icona_shotgun", + "Shells", + 10, + AMMO, + SHOTGUN, + SPECIAL_SFX_ROTATE +}, +{ + "ammo_slugs", + "models/powerups/ammo/railgunam.md3", + "", + "sound/misc/am_pkup.wav", + "icons/icona_railgun", + "Slugs", + 10, + AMMO, + RAILGUN, + SPECIAL_SFX_ROTATE +}, +{ + "item_armor_body", + "models/powerups/armor/armor_red.md3", + "", + "sound/misc/ar2_pkup.wav", + "icons/iconr_red", + "Heavy Armor", + 100, + ARMOR, + SUB_NONE, + SPECIAL_SFX_ROTATE +}, +{ + "item_armor_combat", + "models/powerups/armor/armor_yel.md3", + "", + "sound/misc/ar2_pkup.wav", + "icons/iconr_yellow", + "Armor", + 50, + ARMOR, + SUB_NONE, + SPECIAL_SFX_ROTATE +}, +{ + "item_armor_shard", + "models/powerups/armor/shard.md3", + "", + "sound/misc/ar1_pkup.wav", + "icons/iconr_shard", + "Armor Shared", + 5, + ARMOR, + SUB_NONE, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_gauntlet", + "models/weapons2/gauntlet/gauntlet.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_gauntlet", + "Gauntlet", + 0, + WEAPON, + GAUNTLET, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_shotgun", + "models/weapons2/shotgun/shotgun.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_shotgun", + "Shotgun", + 10, + WEAPON, + SHOTGUN, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_machinegun", + "models/weapons2/machinegun/machinegun.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_machinegun", + "Machinegun", + 40, + WEAPON, + MACHINEGUN, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_grenadelauncher", + "models/weapons2/grenadel/grenadel.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_grenade", + "Grenade Launcher", + 10, + WEAPON, + GRENADE_LAUNCHER, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_rocketlauncher", + "models/weapons2/rocketl/rocketl.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_rocket", + "Rocket Launcher", + 10, + WEAPON, + ROCKET_LAUNCHER, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_lightning", + "models/weapons2/lightning/lightning.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_lightning", + "Lightning Gun", + 100, + WEAPON, + LIGHTNING, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_railgun", + "models/weapons2/railgun/railgun.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_railgun", + "Railgun", + 10, + WEAPON, + RAILGUN, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_plasmagun", + "models/weapons2/plasma/plasma.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_plasma", + "Plasma Gun", + 50, + WEAPON, + PLASMAGUN, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_bfg", + "models/weapons2/bfg/bfg.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_bfg", + "BFG10K", + 20, + WEAPON, + BFG, + SPECIAL_SFX_ROTATE +}, +{ + "weapon_grapplinghook", + "models/weapons2/grapple/grapple.md3", + "", + "sound/misc/w_pkup.wav", + "icons/iconw_grapple", + "Grappling Hook", + 0, + WEAPON, + GRAPPLING_HOOK, + SPECIAL_SFX_ROTATE +}, +{ + 0 +} + +}; + + +/*! +*/ +const SItemElement * getItemElement ( const stringc& key ) +{ + const SItemElement *item = Quake3ItemElement; + + while ( item->key ) + { + if ( 0 == strcmp ( key.c_str(), item->key ) ) + return item; + item += 1; + } + return 0; +} + +/*! + Quake3 Model Factory. + Takes the mesh buffers and creates scenenodes for their associated shaders +*/ +void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, + IrrlichtDevice *device, + IQ3LevelMesh* mesh, + eQ3MeshIndex meshIndex, + ISceneNode *parent, + IMetaTriangleSelector *meta, + bool showShaderName ) +{ + if ( 0 == mesh || 0 == device ) + return; + + IMeshSceneNode* node = 0; + ISceneManager* smgr = device->getSceneManager(); + ITriangleSelector * selector = 0; + + // the additional mesh can be quite huge and is unoptimized + // Save to cast to SMesh + SMesh * additional_mesh = (SMesh*) mesh->getMesh ( meshIndex ); + if ( 0 == additional_mesh || additional_mesh->getMeshBufferCount() == 0) + return; + + char buf[128]; + if ( loadParam.verbose > 0 ) + { + loadParam.startTime = device->getTimer()->getRealTime(); + if ( loadParam.verbose > 1 ) + { + snprintf(buf, 128, "q3shaderfactory start" ); + device->getLogger()->log( buf, ELL_INFORMATION); + } + } + + IGUIFont *font = 0; + if ( showShaderName ) + font = device->getGUIEnvironment()->getFont("fontlucida.png"); + + IVideoDriver *driver = device->getVideoDriver(); + + // create helper textures + if ( 1 ) + { + tTexArray tex; + u32 pos = 0; + getTextures ( tex, "$redimage $blueimage $whiteimage $checkerimage", pos, + device->getFileSystem(), driver ); + } + + s32 sceneNodeID = 0; + for ( u32 i = 0; i!= additional_mesh->getMeshBufferCount (); ++i ) + { + IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i ); + const SMaterial &material = meshBuffer->getMaterial(); + + //! The ShaderIndex is stored in the second material parameter + s32 shaderIndex = (s32) material.MaterialTypeParam2; + + // the meshbuffer can be rendered without additional support, or it has no shader + IShader *shader = (IShader *) mesh->getShader ( shaderIndex ); + + // no shader, or mapped to existing material + if ( 0 == shader ) + { + +#if 1 + // clone mesh + SMesh * m = new SMesh (); + m->addMeshBuffer ( meshBuffer ); + SMaterial &mat = m->getMeshBuffer( 0 )->getMaterial(); + if ( mat.getTexture( 0 ) == 0 ) + mat.setTexture ( 0, driver->getTexture ( "$blueimage" ) ); + if ( mat.getTexture( 1 ) == 0 ) + mat.setTexture ( 1, driver->getTexture ( "$redimage" ) ); + + IMesh * store = smgr->getMeshManipulator ()->createMeshWith2TCoords ( m ); + m->drop(); + + node = smgr->addMeshSceneNode ( store, parent, sceneNodeID ); + node->setAutomaticCulling ( scene::EAC_OFF ); + store->drop (); + sceneNodeID += 1; +#endif + } + else if ( 1 ) + { +/* + stringc s; + dumpShader ( s, shader ); + printf ( s.c_str () ); +*/ + // create sceneNode + node = smgr->addQuake3SceneNode ( meshBuffer, shader, parent, sceneNodeID ); + node->setAutomaticCulling ( scene::EAC_FRUSTUM_BOX ); + sceneNodeID += 1; + } + + // show Debug Shader Name + if ( showShaderName && node ) + { + swprintf ( (wchar_t*) buf, 64, L"%hs:%d", node->getName(),node->getID() ); + smgr->addBillboardTextSceneNode( + font, + (wchar_t*) buf, + node, + dimension2d(80.0f, 8.0f), + vector3df(0, 10, 0), + sceneNodeID); + sceneNodeID += 1; + } + + // create Portal Rendertargets + if ( shader ) + { + const SVarGroup *group = shader->getGroup(1); + if ( group->isDefined( "surfaceparm", "portal" ) ) + { + } + + } + + + // add collision + // find out if shader is marked as nonsolid + u8 doCreate = meta !=0 ; + + if ( shader ) + { + const SVarGroup *group = shader->getGroup(1); + if ( group->isDefined( "surfaceparm", "trans" ) + // || group->isDefined( "surfaceparm", "sky" ) + // || group->isDefined( "surfaceparm", "nonsolid" ) + ) + { + if ( !group->isDefined( "surfaceparm", "metalsteps" ) ) + { + doCreate = 0; + } + } + } + + if ( doCreate ) + { + IMesh *m = 0; + + //! controls if triangles are modified by the scenenode during runtime + bool takeOriginal = true; + + if ( takeOriginal ) + { + m = new SMesh (); + ((SMesh*) m )->addMeshBuffer (meshBuffer); + } + else + { + m = node->getMesh(); + } + + //selector = smgr->createOctreeTriangleSelector ( m, 0, 128 ); + selector = smgr->createTriangleSelector ( m, 0 ); + meta->addTriangleSelector ( selector ); + selector->drop (); + + if ( takeOriginal ) + { + delete m; + } + } + + } + +#if 0 + if ( meta ) + { + selector = smgr->createOctreeTriangleSelector ( additional_mesh, 0 ); + meta->addTriangleSelector ( selector ); + selector->drop (); + } +#endif + + if ( loadParam.verbose > 0 ) + { + loadParam.endTime = device->getTimer()->getRealTime (); + snprintf(buf, 128, "q3shaderfactory needed %04d ms to create %d shader nodes", + loadParam.endTime - loadParam.startTime, + sceneNodeID + ); + device->getLogger()->log(buf, ELL_INFORMATION); + } + +} + + +/*! + create Items from Entity +*/ +void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, + IrrlichtDevice *device, + IQ3LevelMesh* masterMesh, + ISceneNode *parent, + bool showShaderName + ) +{ + if ( 0 == masterMesh ) + return; + + tQ3EntityList &entity = masterMesh->getEntityList (); + ISceneManager* smgr = device->getSceneManager(); + + + char buf[128]; + const SVarGroup *group; + IEntity search; + s32 index; + s32 lastIndex; + +/* + stringc s; + FILE *f = 0; + f = fopen ( "entity.txt", "wb" ); + for ( index = 0; (u32) index < entityList.size (); ++index ) + { + const IEntity *entity = &entityList[ index ]; + s = entity->name; + dumpShader ( s, entity ); + fwrite ( s.c_str(), 1, s.size(), f ); + } + fclose ( f ); +*/ + IAnimatedMeshMD3* model; + SMD3Mesh * mesh; + const SMD3MeshBuffer *meshBuffer; + IMeshSceneNode* node; + ISceneNodeAnimator* anim; + const IShader *shader; + u32 pos; + vector3df p; + u32 nodeCount = 0; + tTexArray textureArray; + + IGUIFont *font = 0; + if ( showShaderName ) + font = device->getGUIEnvironment()->getFont("fontlucida.png"); + + const SItemElement *itemElement; + + // walk list + for ( index = 0; (u32) index < entity.size(); ++index ) + { + itemElement = getItemElement ( entity[index].name ); + if ( 0 == itemElement ) + continue; + + pos = 0; + p = getAsVector3df ( entity[index].getGroup(1)->get ( "origin" ), pos ); + + nodeCount += 1; + for ( u32 g = 0; g < 2; ++g ) + { + if ( 0 == itemElement->model[g] || itemElement->model[g][0] == 0 ) + continue; + model = (IAnimatedMeshMD3*) smgr->getMesh( itemElement->model[g] ); + if ( 0 == model ) + continue; + + mesh = model->getOriginalMesh(); + for ( u32 j = 0; j != mesh->Buffer.size (); ++j ) + { + meshBuffer = mesh->Buffer[j]; + if ( 0 == meshBuffer ) + continue; + + shader = masterMesh->getShader ( meshBuffer->Shader.c_str(), false ); + IMeshBuffer *final = model->getMesh(0)->getMeshBuffer(j); + if ( shader ) + { + //!TODO: Hack don't modify the vertexbuffer. make it better;-) + final->getMaterial().ColorMask = 0; + node = smgr->addQuake3SceneNode ( final, shader, parent ); + final->getMaterial().ColorMask = 15; + } + else + { + // clone mesh + SMesh * m = new SMesh (); + m->addMeshBuffer ( final ); + node = smgr->addMeshSceneNode ( m, parent ); + m->drop(); + } + + if ( 0 == node ) + { + snprintf ( buf, 128, "q3ModelFactory shader %s failed", meshBuffer->Shader.c_str() ); + device->getLogger()->log ( buf ); + continue; + } + + // node was maybe centered by shaderscenenode + node->setPosition ( p ); + node->setName ( meshBuffer->Shader ); + node->setAutomaticCulling ( scene::EAC_BOX ); + + // add special effects to node + if ( itemElement->special & SPECIAL_SFX_ROTATE || + (g == 0 && itemElement->special & SPECIAL_SFX_ROTATE_1) + ) + { + anim = smgr->createRotationAnimator ( vector3df ( 0.f, + 2.f, 0.f ) ); + node->addAnimator ( anim ); + anim->drop (); + } + + if ( itemElement->special & SPECIAL_SFX_BOUNCE ) + { + //anim = smgr->createFlyStraightAnimator ( + // p, p + vector3df ( 0.f, 60.f, 0.f ), 1000, true, true ); + anim = smgr->createFlyCircleAnimator ( + p + vector3df( 0.f, 20.f, 0.f ), + 20.f, + 0.005f, + vector3df ( 1.f, 0.f, 0.f ), + core::fract ( nodeCount * 0.05f ), + 1.f + ); + node->addAnimator ( anim ); + anim->drop (); + } + } + } + // show name + if ( showShaderName ) + { + swprintf ( (wchar_t*) buf, sizeof(buf) / 2, L"%hs", itemElement->key ); + smgr->addBillboardTextSceneNode( + font, + (wchar_t*) buf, + parent, + dimension2d(80.0f, 8.0f), + p + vector3df(0, 30, 0), + 0); + } + } + + // music + search.name = "worldspawn"; + index = entity.binary_search_multi ( search, lastIndex ); + + if ( index >= 0 ) + { + group = entity[ index ].getGroup(1); + background_music ( group->get ( "music" ).c_str () ); + } + + // music + search.name = "worldspawn"; + index = entity.binary_search_multi ( search, lastIndex ); + + if ( index >= 0 ) + { + group = entity[ index ].getGroup(1); + background_music ( group->get ( "music" ).c_str () ); + } + + //IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2"); + //IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); + +} + +/*! + so we need a good starting Position in the level. + we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" +*/ +s32 Q3StartPosition ( IQ3LevelMesh* mesh, + ICameraSceneNode* camera, + s32 startposIndex, + const vector3df &translation + ) +{ + if ( 0 == mesh ) + return 0; + + tQ3EntityList &entityList = mesh->getEntityList (); + + IEntity search; + search.name = "info_player_start"; // "info_player_deathmatch"; + + // find all entities in the multi-list + s32 lastIndex; + s32 index = entityList.binary_search_multi ( search, lastIndex ); + + if ( index < 0 ) + { + search.name = "info_player_deathmatch"; + index = entityList.binary_search_multi ( search, lastIndex ); + } + + if ( index < 0 ) + return 0; + + index += core::clamp ( startposIndex, 0, lastIndex - index ); + + u32 parsepos; + + const SVarGroup *group; + group = entityList[ index ].getGroup(1); + + parsepos = 0; + vector3df pos = getAsVector3df ( group->get ( "origin" ), parsepos ); + pos += translation; + + parsepos = 0; + f32 angle = getAsFloat ( group->get ( "angle"), parsepos ); + + vector3df target ( 0.f, 0.f, 1.f ); + target.rotateXZBy ( angle - 90.f, vector3df () ); + + if ( camera ) + { + camera->setPosition ( pos ); + camera->setTarget ( pos + target ); + //! New. FPSCamera and animators catches reset on animate 0 + camera->OnAnimate ( 0 ); + } + return lastIndex - index + 1; +} + + +/*! + gets a accumulated force on a given surface +*/ +vector3df getGravity ( const c8 * surface ) +{ + if ( 0 == strcmp ( surface, "earth" ) ) return vector3df ( 0.f, -90.f, 0.f ); + if ( 0 == strcmp ( surface, "moon" ) ) return vector3df ( 0.f, -6.f / 100.f, 0.f ); + if ( 0 == strcmp ( surface, "water" ) ) return vector3df ( 0.1f / 100.f, -2.f / 100.f, 0.f ); + if ( 0 == strcmp ( surface, "ice" ) ) return vector3df ( 0.2f / 100.f, -9.f / 100.f, 0.3f / 100.f ); + + return vector3df ( 0.f, 0.f, 0.f ); +} + + + +/* + Dynamically load the Irrlicht Library +*/ + +#if defined(_IRR_WINDOWS_API_) +#ifdef _MSC_VER +#pragma comment(lib, "Irrlicht.lib") +#endif + +#include + +funcptr_createDevice load_createDevice ( const c8 * filename) +{ + return (funcptr_createDevice) GetProcAddress ( LoadLibrary ( filename ), "createDevice" ); +} + +funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename) +{ + return (funcptr_createDeviceEx) GetProcAddress ( LoadLibrary ( filename ), "createDeviceEx" ); +} + +#else + +// TODO: Dynamic Loading for other os +funcptr_createDevice load_createDevice ( const c8 * filename) +{ + return createDevice; +} + +funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename) +{ + return createDeviceEx; +} + +#endif + +/* + get the current collision response camera animator +*/ +ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * device ) +{ + ICameraSceneNode *camera = device->getSceneManager()->getActiveCamera(); + ISceneNodeAnimatorCollisionResponse *a = 0; + + list::ConstIterator it = camera->getAnimators().begin(); + for (; it != camera->getAnimators().end(); ++it) + { + a = (ISceneNodeAnimatorCollisionResponse*) (*it); + if ( a->getType() == ESNAT_COLLISION_RESPONSE ) + return a; + } + + return 0; +} + + +//! internal Animation +void setTimeFire ( TimeFire *t, u32 delta, u32 flags ) +{ + t->flags = flags; + t->next = 0; + t->delta = delta; +} + + +void checkTimeFire ( TimeFire *t, u32 listSize, u32 now ) +{ + u32 i; + for ( i = 0; i < listSize; ++i ) + { + if ( now < t[i].next ) + continue; + + t[i].next = core::max_ ( now + t[i].delta, t[i].next + t[i].delta ); + t[i].flags |= FIRED; + } +} diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.h b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.h index d9606ed..d3c9561 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.h +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/q3factory.h @@ -1,149 +1,149 @@ -/*! - Model Factory. - create the additional scenenodes for ( bullets, health... ) - - Defines the Entities for Quake3 -*/ -#ifndef __QUAKE3_FACTORY__H_INCLUDED__ -#define __QUAKE3_FACTORY__H_INCLUDED__ - -using namespace irr; -using namespace scene; -using namespace gui; -using namespace video; -using namespace core; -using namespace quake3; -using namespace io; - - - -//! Defines to which group the entities belong -enum eItemGroup -{ - WEAPON, - AMMO, - ARMOR, - HEALTH, - POWERUP -}; - -//! define a supgroup for the item. for e.q the Weapons -enum eItemSubGroup -{ - SUB_NONE = 0, - GAUNTLET, - MACHINEGUN, - SHOTGUN, - GRENADE_LAUNCHER, - ROCKET_LAUNCHER, - LIGHTNING, - RAILGUN, - PLASMAGUN, - BFG, - GRAPPLING_HOOK, - NAILGUN, - PROX_LAUNCHER, - CHAINGUN, -}; - -//! aplly a special effect to the shader -enum eItemSpecialEffect -{ - SPECIAL_SFX_NONE = 0, - SPECIAL_SFX_ROTATE = 1, - SPECIAL_SFX_BOUNCE = 2, - SPECIAL_SFX_ROTATE_1 = 4, -}; - -// a List for defining a model -struct SItemElement -{ - const c8 *key; - const c8 *model[2]; - const c8 *sound; - const c8 *icon; - const c8 *pickup; - s32 value; - eItemGroup group; - eItemSubGroup sub; - u32 special; -}; - - -//! Get's an entity based on it's key -const SItemElement * getItemElement ( const stringc& key ); - -/*! - Quake3 Model Factory. - Takes the mesh buffers and creates scenenodes for their associated shaders -*/ -void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, - IrrlichtDevice *device, - IQ3LevelMesh* mesh, - eQ3MeshIndex meshIndex, - ISceneNode *parent, - IMetaTriangleSelector *meta, - bool showShaderName - ); - - -/*! - Creates Model based on the entity list -*/ -void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, - IrrlichtDevice *device, - IQ3LevelMesh* masterMesh, - ISceneNode *parent, - bool showShaderName - ); - -/*! - so we need a good starting Position in the level. - we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" -*/ -s32 Q3StartPosition ( IQ3LevelMesh* mesh, - ICameraSceneNode* camera, - s32 startposIndex, - const vector3df &translation - ); -/*! - gets a accumulated force on a given surface -*/ -vector3df getGravity ( const c8 * surface ); - - -/* - Dynamically load the Irrlicht Library -*/ -funcptr_createDevice load_createDevice ( const c8 * filename); -funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename); - - -//! Macro for save Dropping an Element -#define dropElement(x) if (x) { x->remove(); x = 0; } - - -/* - get the current collision respone camera animator -*/ -ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * device ); - -//! internal Animation -enum eTimeFireFlag -{ - FIRED = 1, -}; - -struct TimeFire -{ - u32 flags; - u32 next; - u32 delta; -}; - -void setTimeFire ( TimeFire *t, u32 delta, u32 flags = 0 ); -void checkTimeFire ( TimeFire *t, u32 listSize, u32 now ); - -#endif // __QUAKE3_FACTORY__H_INCLUDED__ - - +/*! + Model Factory. + create the additional scenenodes for ( bullets, health... ) + + Defines the Entities for Quake3 +*/ +#ifndef __QUAKE3_FACTORY__H_INCLUDED__ +#define __QUAKE3_FACTORY__H_INCLUDED__ + +using namespace irr; +using namespace scene; +using namespace gui; +using namespace video; +using namespace core; +using namespace quake3; +using namespace io; + + + +//! Defines to which group the entities belong +enum eItemGroup +{ + WEAPON, + AMMO, + ARMOR, + HEALTH, + POWERUP +}; + +//! define a supgroup for the item. for e.q the Weapons +enum eItemSubGroup +{ + SUB_NONE = 0, + GAUNTLET, + MACHINEGUN, + SHOTGUN, + GRENADE_LAUNCHER, + ROCKET_LAUNCHER, + LIGHTNING, + RAILGUN, + PLASMAGUN, + BFG, + GRAPPLING_HOOK, + NAILGUN, + PROX_LAUNCHER, + CHAINGUN, +}; + +//! aplly a special effect to the shader +enum eItemSpecialEffect +{ + SPECIAL_SFX_NONE = 0, + SPECIAL_SFX_ROTATE = 1, + SPECIAL_SFX_BOUNCE = 2, + SPECIAL_SFX_ROTATE_1 = 4, +}; + +// a List for defining a model +struct SItemElement +{ + const c8 *key; + const c8 *model[2]; + const c8 *sound; + const c8 *icon; + const c8 *pickup; + s32 value; + eItemGroup group; + eItemSubGroup sub; + u32 special; +}; + + +//! Get's an entity based on it's key +const SItemElement * getItemElement ( const stringc& key ); + +/*! + Quake3 Model Factory. + Takes the mesh buffers and creates scenenodes for their associated shaders +*/ +void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, + IrrlichtDevice *device, + IQ3LevelMesh* mesh, + eQ3MeshIndex meshIndex, + ISceneNode *parent, + IMetaTriangleSelector *meta, + bool showShaderName + ); + + +/*! + Creates Model based on the entity list +*/ +void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, + IrrlichtDevice *device, + IQ3LevelMesh* masterMesh, + ISceneNode *parent, + bool showShaderName + ); + +/*! + so we need a good starting Position in the level. + we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" +*/ +s32 Q3StartPosition ( IQ3LevelMesh* mesh, + ICameraSceneNode* camera, + s32 startposIndex, + const vector3df &translation + ); +/*! + gets a accumulated force on a given surface +*/ +vector3df getGravity ( const c8 * surface ); + + +/* + Dynamically load the Irrlicht Library +*/ +funcptr_createDevice load_createDevice ( const c8 * filename); +funcptr_createDeviceEx load_createDeviceEx ( const c8 * filename); + + +//! Macro for save Dropping an Element +#define dropElement(x) if (x) { x->remove(); x = 0; } + + +/* + get the current collision respone camera animator +*/ +ISceneNodeAnimatorCollisionResponse* camCollisionResponse( IrrlichtDevice * device ); + +//! internal Animation +enum eTimeFireFlag +{ + FIRED = 1, +}; + +struct TimeFire +{ + u32 flags; + u32 next; + u32 delta; +}; + +void setTimeFire ( TimeFire *t, u32 delta, u32 flags = 0 ); +void checkTimeFire ( TimeFire *t, u32 listSize, u32 now ); + +#endif // __QUAKE3_FACTORY__H_INCLUDED__ + + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.cpp b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.cpp index 75615c1..876c498 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.cpp +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.cpp @@ -1,98 +1,98 @@ -/*! - Sound Factory. - provides a sound interface - -*/ - -#include "sound.h" - - -//#define USE_IRRKLANG - -#ifdef USE_IRRKLANG - -#include -#ifdef _IRR_WINDOWS_ - #pragma comment (lib, "irrKlang.lib") -#endif - -using namespace irrklang; - -struct soundfile: public IFileReader -{ - soundfile ( io::IReadFile* f ): file (f ) {} - virtual ~soundfile () { file->drop (); } - - virtual ik_s32 read(void* buffer, ik_u32 sizeToRead) { return file->read ( buffer, sizeToRead ); } - virtual bool seek(ik_s32 finalPos, bool relativeMovement = false) { return file->seek ( finalPos, relativeMovement ); } - virtual ik_s32 getSize(){ return file->getSize (); } - virtual ik_s32 getPos() {return file->getPos (); } - virtual const ik_c8* getFileName() { return file->getFileName (); } - io::IReadFile* file; -}; - -struct klangFactory : public irrklang::IFileFactory -{ - klangFactory ( IrrlichtDevice *device ) { Device = device; } - - virtual irrklang::IFileReader* createFileReader(const ik_c8* filename) - { - io::IReadFile* file = Device->getFileSystem()->createAndOpenFile(filename); - if ( 0 == file ) - return 0; - - return new soundfile ( file ); - } - - IrrlichtDevice *Device; -}; - -ISoundEngine *engine = 0; -ISound *backMusic = 0; - -void sound_init ( IrrlichtDevice *device ) -{ - engine = createIrrKlangDevice (); - if ( 0 == engine ) - return; - - klangFactory *f = new klangFactory ( device ); - engine->addFileFactory ( f ); -} - -void sound_shutdown () -{ - if ( backMusic ) - backMusic->drop (); - - if ( engine ) - engine->drop (); -} - -void background_music ( const c8 * file ) -{ - if ( 0 == engine ) - return; - - if ( backMusic ) - { - backMusic->stop (); - backMusic->drop (); - } - - backMusic = engine->play2D ( file, true, false, true ); - - if ( backMusic ) - { - backMusic->setVolume ( 0.5f ); - } -} - -#else - -void sound_init ( IrrlichtDevice *device ) {} -void sound_shutdown () {} -void background_music ( const c8 * file ) {} - -#endif - +/*! + Sound Factory. + provides a sound interface + +*/ + +#include "sound.h" + + +//#define USE_IRRKLANG + +#ifdef USE_IRRKLANG + +#include +#ifdef _IRR_WINDOWS_ + #pragma comment (lib, "irrKlang.lib") +#endif + +using namespace irrklang; + +struct soundfile: public IFileReader +{ + soundfile ( io::IReadFile* f ): file (f ) {} + virtual ~soundfile () { file->drop (); } + + virtual ik_s32 read(void* buffer, ik_u32 sizeToRead) { return file->read ( buffer, sizeToRead ); } + virtual bool seek(ik_s32 finalPos, bool relativeMovement = false) { return file->seek ( finalPos, relativeMovement ); } + virtual ik_s32 getSize(){ return file->getSize (); } + virtual ik_s32 getPos() {return file->getPos (); } + virtual const ik_c8* getFileName() { return file->getFileName (); } + io::IReadFile* file; +}; + +struct klangFactory : public irrklang::IFileFactory +{ + klangFactory ( IrrlichtDevice *device ) { Device = device; } + + virtual irrklang::IFileReader* createFileReader(const ik_c8* filename) + { + io::IReadFile* file = Device->getFileSystem()->createAndOpenFile(filename); + if ( 0 == file ) + return 0; + + return new soundfile ( file ); + } + + IrrlichtDevice *Device; +}; + +ISoundEngine *engine = 0; +ISound *backMusic = 0; + +void sound_init ( IrrlichtDevice *device ) +{ + engine = createIrrKlangDevice (); + if ( 0 == engine ) + return; + + klangFactory *f = new klangFactory ( device ); + engine->addFileFactory ( f ); +} + +void sound_shutdown () +{ + if ( backMusic ) + backMusic->drop (); + + if ( engine ) + engine->drop (); +} + +void background_music ( const c8 * file ) +{ + if ( 0 == engine ) + return; + + if ( backMusic ) + { + backMusic->stop (); + backMusic->drop (); + } + + backMusic = engine->play2D ( file, true, false, true ); + + if ( backMusic ) + { + backMusic->setVolume ( 0.5f ); + } +} + +#else + +void sound_init ( IrrlichtDevice *device ) {} +void sound_shutdown () {} +void background_music ( const c8 * file ) {} + +#endif + diff --git a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.h b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.h index 033e9bb..fab4555 100644 --- a/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.h +++ b/libraries/irrlicht-1.8/examples/21.Quake3Explorer/sound.h @@ -1,18 +1,18 @@ -/*! - Sound Factory. - provides a sound interface - -*/ -#ifndef __QUAKE3_SOUND__H_INCLUDED__ -#define __QUAKE3_SOUND__H_INCLUDED__ - -#include - -using namespace irr; - -void sound_init ( IrrlichtDevice *device ); -void sound_shutdown (); -void background_music ( const c8 * file ); - - -#endif // __QUAKE3_SOUND__H_INCLUDED__ +/*! + Sound Factory. + provides a sound interface + +*/ +#ifndef __QUAKE3_SOUND__H_INCLUDED__ +#define __QUAKE3_SOUND__H_INCLUDED__ + +#include + +using namespace irr; + +void sound_init ( IrrlichtDevice *device ); +void sound_shutdown (); +void background_music ( const c8 * file ); + + +#endif // __QUAKE3_SOUND__H_INCLUDED__ -- cgit v1.1