diff --git a/assets/gfx/2d/crosshaira.tga b/assets/gfx/2d/crosshaira.tga
new file mode 100644
index 00000000..c8a83ece
Binary files /dev/null and b/assets/gfx/2d/crosshaira.tga differ
diff --git a/assets/gfx/2d/crosshairb.tga b/assets/gfx/2d/crosshairb.tga
new file mode 100644
index 00000000..07e69663
Binary files /dev/null and b/assets/gfx/2d/crosshairb.tga differ
diff --git a/assets/gfx/2d/crosshairc.tga b/assets/gfx/2d/crosshairc.tga
new file mode 100644
index 00000000..d17290ea
Binary files /dev/null and b/assets/gfx/2d/crosshairc.tga differ
diff --git a/assets/gfx/2d/crosshaird.tga b/assets/gfx/2d/crosshaird.tga
new file mode 100644
index 00000000..11177a64
Binary files /dev/null and b/assets/gfx/2d/crosshaird.tga differ
diff --git a/assets/gfx/2d/crosshaire.tga b/assets/gfx/2d/crosshaire.tga
new file mode 100644
index 00000000..06e17602
Binary files /dev/null and b/assets/gfx/2d/crosshaire.tga differ
diff --git a/assets/gfx/2d/crosshairf.tga b/assets/gfx/2d/crosshairf.tga
new file mode 100644
index 00000000..46515b17
Binary files /dev/null and b/assets/gfx/2d/crosshairf.tga differ
diff --git a/assets/gfx/2d/crosshairg.tga b/assets/gfx/2d/crosshairg.tga
new file mode 100644
index 00000000..1213d180
Binary files /dev/null and b/assets/gfx/2d/crosshairg.tga differ
diff --git a/assets/gfx/2d/crosshairh.tga b/assets/gfx/2d/crosshairh.tga
new file mode 100644
index 00000000..bead78b2
Binary files /dev/null and b/assets/gfx/2d/crosshairh.tga differ
diff --git a/assets/gfx/2d/crosshairi.tga b/assets/gfx/2d/crosshairi.tga
new file mode 100644
index 00000000..faa45f6f
Binary files /dev/null and b/assets/gfx/2d/crosshairi.tga differ
diff --git a/assets/gfx/2d/crosshairj.tga b/assets/gfx/2d/crosshairj.tga
new file mode 100644
index 00000000..a17f9903
Binary files /dev/null and b/assets/gfx/2d/crosshairj.tga differ
diff --git a/assets/scripts/crosshair.shader b/assets/scripts/crosshair.shader
new file mode 100644
index 00000000..975f362e
--- /dev/null
+++ b/assets/scripts/crosshair.shader
@@ -0,0 +1,90 @@
+gfx/2d/crosshaira
+{
+ nopicmip
+ {
+ map gfx/2d/crosshaira.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairb
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairb.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairc
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairc.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshaird
+{
+ nopicmip
+ {
+ map gfx/2d/crosshaird.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshaire
+{
+ nopicmip
+ {
+ map gfx/2d/crosshaire.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairf
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairf.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairg
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairg.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairh
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairh.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairi
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairi.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
+gfx/2d/crosshairj
+{
+ nopicmip
+ {
+ map gfx/2d/crosshairj.tga
+ blendFunc BLEND
+ rgbGen exactVertex
+ }
+}
diff --git a/build/linux-qvm/tools/q3asm b/build/linux-qvm/tools/q3asm
old mode 100644
new mode 100755
diff --git a/build/linux-qvm/tools/q3cpp b/build/linux-qvm/tools/q3cpp
old mode 100644
new mode 100755
diff --git a/build/linux-qvm/tools/q3lcc b/build/linux-qvm/tools/q3lcc
old mode 100644
new mode 100755
diff --git a/build/linux-qvm/tools/q3rcc b/build/linux-qvm/tools/q3rcc
old mode 100644
new mode 100755
diff --git a/build/win32-msvc/baseq3e.sln b/build/win32-msvc/baseq3e.sln
index 3daacb61..f552308b 100644
--- a/build/win32-msvc/baseq3e.sln
+++ b/build/win32-msvc/baseq3e.sln
@@ -1,11 +1,13 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgame", "cgame.vcproj", "{FF0DC79F-C1D1-4DE3-BBD0-91B6146FD69C}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34622.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgame", "cgame.vcxproj", "{FF0DC79F-C1D1-4DE3-BBD0-91B6146FD69C}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game", "game.vcproj", "{25F3B624-E060-4DAD-93D6-479AB6CD782F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game", "game.vcxproj", "{25F3B624-E060-4DAD-93D6-479AB6CD782F}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "q3_ui", "q3_ui.vcproj", "{96D17D51-0760-4732-89C1-26DFD5B581BF}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "q3_ui", "q3_ui.vcxproj", "{96D17D51-0760-4732-89C1-26DFD5B581BF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -43,4 +45,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1C55EC9F-CEA6-492E-8CBD-D086B4777FAF}
+ EndGlobalSection
EndGlobal
diff --git a/build/win32-msvc/cgame.vcxproj b/build/win32-msvc/cgame.vcxproj
new file mode 100644
index 00000000..cc85498d
--- /dev/null
+++ b/build/win32-msvc/cgame.vcxproj
@@ -0,0 +1,205 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ {FF0DC79F-C1D1-4DE3-BBD0-91B6146FD69C}
+ cgame
+ Win32Proj
+ 10.0
+
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>17.0.34511.75
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ true
+ $(ProjectName)$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+
+
+ $(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ true
+ $(ProjectName)$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ $(OutDir)cgamex86.dll
+ true
+ Windows
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+
+
+ $(OutDir)cgamex86.dll
+ Windows
+ true
+ true
+
+
+
+
+ X64
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)cgamex86_64.dll
+ true
+ Windows
+ MachineX64
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ X64
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+
+
+ $(OutDir)cgamex86_64.dll
+ Windows
+ true
+ true
+ MachineX64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/win32-msvc/cgame.vcxproj.filters b/build/win32-msvc/cgame.vcxproj.filters
new file mode 100644
index 00000000..a485ed52
--- /dev/null
+++ b/build/win32-msvc/cgame.vcxproj.filters
@@ -0,0 +1,121 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ c;def
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;inc
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/build/win32-msvc/game.vcxproj b/build/win32-msvc/game.vcxproj
new file mode 100644
index 00000000..ce1c97ea
--- /dev/null
+++ b/build/win32-msvc/game.vcxproj
@@ -0,0 +1,239 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ {25F3B624-E060-4DAD-93D6-479AB6CD782F}
+ game
+ Win32Proj
+ 10.0
+
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>17.0.34511.75
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ true
+ qagame$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ true
+ qagame$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ $(OutDir)qagamex86.dll
+ true
+ Windows
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+
+
+ $(OutDir)qagamex86.dll
+ Windows
+ true
+ true
+
+
+
+
+ X64
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)qagamex86_64.dll
+ true
+ Windows
+ MachineX64
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ X64
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+
+
+ $(OutDir)qagamex86_64.dll
+ Windows
+ true
+ true
+ MachineX64
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/win32-msvc/game.vcxproj.filters b/build/win32-msvc/game.vcxproj.filters
new file mode 100644
index 00000000..40b87cf7
--- /dev/null
+++ b/build/win32-msvc/game.vcxproj.filters
@@ -0,0 +1,212 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ c;def
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;inc
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/build/win32-msvc/q3_ui.vcxproj b/build/win32-msvc/q3_ui.vcxproj
new file mode 100644
index 00000000..da2ac137
--- /dev/null
+++ b/build/win32-msvc/q3_ui.vcxproj
@@ -0,0 +1,227 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ {96D17D51-0760-4732-89C1-26DFD5B581BF}
+ q3_ui
+ Win32Proj
+ 10.0
+
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ v143
+ Unicode
+ true
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>17.0.34511.75
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ true
+ ui$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ true
+ ui$(ARCHL)
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ false
+
+
+ .\$(Platform)\$(Configuration)\
+ .\$(Platform)\$(Configuration)_$(ProjectName)\
+ false
+
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ $(OutDir)uix86.dll
+ true
+ Windows
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ X64
+
+
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)uix86_64.dll
+ true
+ Windows
+ MachineX64
+
+
+ copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName)$(TargetExt) "$(QUAKE3DIR)\$(MODDIR)"
+copy $(ProjectDir)$(ARCH)\$(Configuration)\$(TargetName).pdb "$(QUAKE3DIR)\$(MODDIR)"
+
+
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)uix86.dll
+ true
+ Windows
+ true
+ true
+ MachineX86
+
+
+
+
+ X64
+
+
+ _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)uix86_64.dll
+ true
+ Windows
+ true
+ true
+ MachineX64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/win32-msvc/q3_ui.vcxproj.filters b/build/win32-msvc/q3_ui.vcxproj.filters
new file mode 100644
index 00000000..bb09275d
--- /dev/null
+++ b/build/win32-msvc/q3_ui.vcxproj.filters
@@ -0,0 +1,170 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ c;def
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;inc
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/code/cgame/cg_cvar.h b/code/cgame/cg_cvar.h
index 46811af9..1019c490 100644
--- a/code/cgame/cg_cvar.h
+++ b/code/cgame/cg_cvar.h
@@ -30,6 +30,7 @@ CG_CVAR( cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE )
CG_CVAR( cg_drawSpeed, "cg_drawSpeed", "0", CVAR_ARCHIVE )
CG_CVAR( cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE )
CG_CVAR( cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE )
+CG_CVAR( cg_crosshairColor, "cg_crosshairColor", "7", CVAR_ARCHIVE )
CG_CVAR( cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE )
CG_CVAR( cg_drawWeaponSelect, "cg_drawWeaponSelect", "1", CVAR_ARCHIVE )
CG_CVAR( cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE )
diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c
index 366c6d00..7260acf0 100644
--- a/code/cgame/cg_draw.c
+++ b/code/cgame/cg_draw.c
@@ -1995,6 +1995,33 @@ CROSSHAIR
================================================================================
*/
+/*
+=================
+CG_SetCrosshairColor
+=================
+*/
+static void CG_SetCrosshairColor( void ) {
+ static int colorNum;
+ static float *colors[] = {
+ colorBlack, //0
+ colorRed, //1
+ colorGreen, //2
+ colorYellow, //3
+ colorBlue, //4
+ colorCyan, //5
+ colorMagenta, //6
+ colorWhite, //7
+ };
+
+ colorNum = cg_crosshairColor.integer;
+ if ( colorNum > 7 || colorNum < 0 ) { // if it's larger than 7 or less than 0, set it to white
+ colorNum = 7;
+ }
+ colorNum = colorNum % ARRAY_LEN( colors );
+
+ trap_R_SetColor( colors[colorNum] );
+}
+
/*
=================
@@ -2027,7 +2054,7 @@ static void CG_DrawCrosshair( void ) {
CG_ColorForHealth( hcolor );
trap_R_SetColor( hcolor );
} else {
- trap_R_SetColor( NULL );
+ CG_SetCrosshairColor();
}
w = h = cg_crosshairSize.value;
diff --git a/code/q3_ui/ui_preferences.c b/code/q3_ui/ui_preferences.c
index 8cb17256..1d928f00 100644
--- a/code/q3_ui/ui_preferences.c
+++ b/code/q3_ui/ui_preferences.c
@@ -17,6 +17,15 @@ GAME OPTIONS MENU
#define ART_BACK0 "menu/art/back_0"
#define ART_BACK1 "menu/art/back_1"
+#define ART_FX_BASE "menu/art/fx_base"
+#define ART_FX_BLUE "menu/art/fx_blue"
+#define ART_FX_CYAN "menu/art/fx_cyan"
+#define ART_FX_GREEN "menu/art/fx_grn"
+#define ART_FX_RED "menu/art/fx_red"
+#define ART_FX_TEAL "menu/art/fx_teal"
+#define ART_FX_WHITE "menu/art/fx_white"
+#define ART_FX_YELLOW "menu/art/fx_yel"
+
#define PREFERENCES_X_POS 360
#define ID_CROSSHAIR 127
@@ -29,8 +38,9 @@ GAME OPTIONS MENU
#define ID_SYNCEVERYFRAME 134
#define ID_FORCEMODEL 135
#define ID_DRAWTEAMOVERLAY 136
-#define ID_ALLOWDOWNLOAD 137
+#define ID_ALLOWDOWNLOAD 137
#define ID_BACK 138
+#define ID_CROSSHAIRCOLOR 139
#define NUM_CROSSHAIRS 10
@@ -42,7 +52,8 @@ typedef struct {
menubitmap_s framel;
menubitmap_s framer;
- menulist_s crosshair;
+ menulist_s crosshair;
+ menulist_s crosshaircolor;
menuradiobutton_s simpleitems;
menuradiobutton_s brass;
menuradiobutton_s wallmarks;
@@ -51,15 +62,45 @@ typedef struct {
menuradiobutton_s highqualitysky;
menuradiobutton_s synceveryframe;
menuradiobutton_s forcemodel;
- menulist_s drawteamoverlay;
+ menulist_s drawteamoverlay;
menuradiobutton_s allowdownload;
menubitmap_s back;
- qhandle_t crosshairShader[NUM_CROSSHAIRS];
+ qhandle_t crosshairShader[NUM_CROSSHAIRS];
+
+ qhandle_t fxBasePic;
+ qhandle_t fxPic[8];
} preferences_t;
static preferences_t s_preferences;
+/*===================================================
+ INDEX - UI SLIDER BAR COLOR VALUE > CGAME VALUE
+ 0 - RED 7 > 1
+ 1 - GREEN 0 > 2
+ 2 - YELLOW 1 > 3
+ 3 - BLUE 2 > 4
+ 4 - TEAL (CYAN) 3 > 5
+ 5 - MAGENTA 5 > 6
+ 6 - WHITE 4 > 7
+ 7 - BLACK 6 > 0
+=====================================================
+If any number isn't in the UI table to assign, it will always map to WHITE
+*/
+static int gamecodetoui[] = {7,0,1,2,3,5,4,6};
+static int uitogamecode[] = {1,2,3,4,6,5,7,0};
+static float *uiSliderColors[] = {
+ colorRed,
+ colorGreen,
+ colorYellow,
+ colorBlue,
+ colorMagenta,
+ colorCyan,
+ colorWhite,
+ colorBlack
+};
+static int uiSliderColorIndex;
+
static const char *teamoverlay_names[] =
{
"off",
@@ -70,15 +111,25 @@ static const char *teamoverlay_names[] =
};
static void Preferences_SetMenuItems( void ) {
+ int c;
+
s_preferences.crosshair.curvalue = (int)trap_Cvar_VariableValue( "cg_drawCrosshair" ) % NUM_CROSSHAIRS;
- s_preferences.simpleitems.curvalue = trap_Cvar_VariableValue( "cg_simpleItems" ) != 0;
- s_preferences.brass.curvalue = trap_Cvar_VariableValue( "cg_brassTime" ) != 0;
- s_preferences.wallmarks.curvalue = trap_Cvar_VariableValue( "cg_marks" ) != 0;
+
+ c = (int)trap_Cvar_VariableValue( "cg_crosshairColor" );
+ if ( c < 0 || c > 7 ) { // if cvar is invalid, set to white
+ c = 7;
+ }
+
+ uiSliderColorIndex = s_preferences.crosshaircolor.curvalue = gamecodetoui[c];
+
+ s_preferences.simpleitems.curvalue = trap_Cvar_VariableValue( "cg_simpleItems" ) != 0;
+ s_preferences.brass.curvalue = trap_Cvar_VariableValue( "cg_brassTime" ) != 0;
+ s_preferences.wallmarks.curvalue = trap_Cvar_VariableValue( "cg_marks" ) != 0;
s_preferences.identifytarget.curvalue = trap_Cvar_VariableValue( "cg_drawCrosshairNames" ) != 0;
s_preferences.dynamiclights.curvalue = trap_Cvar_VariableValue( "r_dynamiclight" ) != 0;
s_preferences.highqualitysky.curvalue = trap_Cvar_VariableValue ( "r_fastsky" ) == 0;
s_preferences.synceveryframe.curvalue = trap_Cvar_VariableValue( "r_swapinterval" ) != 0;
- s_preferences.forcemodel.curvalue = trap_Cvar_VariableValue( "cg_forcemodel" ) != 0;
+ s_preferences.forcemodel.curvalue = trap_Cvar_VariableValue( "cg_forcemodel" ) != 0;
s_preferences.drawteamoverlay.curvalue = Com_Clamp( 0, 3, trap_Cvar_VariableValue( "cg_drawTeamOverlay" ) );
s_preferences.allowdownload.curvalue = trap_Cvar_VariableValue( "cl_allowDownload" ) != 0;
}
@@ -98,6 +149,14 @@ static void Preferences_Event( void* ptr, int notification ) {
trap_Cvar_SetValue( "cg_drawCrosshair", s_preferences.crosshair.curvalue );
break;
+ case ID_CROSSHAIRCOLOR:
+ uiSliderColorIndex++;
+ if( uiSliderColorIndex > ( ARRAY_LEN( uiSliderColors ) - 1 ) ) {
+ uiSliderColorIndex = 0;
+ }
+ trap_Cvar_SetValue( "cg_crosshairColor", uitogamecode[s_preferences.crosshaircolor.curvalue] );
+ break;
+
case ID_SIMPLEITEMS:
trap_Cvar_SetValue( "cg_simpleItems", s_preferences.simpleitems.curvalue );
break;
@@ -157,8 +216,8 @@ Crosshair_Draw
static void Crosshair_Draw( void *self ) {
menulist_s *s;
float *color;
- int x, y;
- int style;
+ int x, y;
+ int style;
qboolean focus;
s = (menulist_s *)self;
@@ -194,10 +253,38 @@ static void Crosshair_Draw( void *self ) {
if( !s->curvalue ) {
return;
}
+ trap_R_SetColor( uiSliderColors[uiSliderColorIndex] ); // Draw color to the crosshair
UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y - 4, 24, 24, s_preferences.crosshairShader[s->curvalue] );
}
+/*
+=================
+CrosshairColor_Draw
+=================
+*/
+static void CrosshairColor_Draw( void *self ) {
+ menulist_s *item;
+ float *color;
+ int style;
+ qboolean focus;
+
+ item = (menulist_s *)self;
+ focus = (item->generic.parent->cursor == item->generic.menuPosition);
+
+ style = UI_LEFT|UI_SMALLFONT;
+ color = text_color_normal;
+ if( focus ) {
+ style |= UI_PULSE;
+ color = text_color_highlight;
+ }
+ UI_DrawString( item->generic.x - SMALLCHAR_WIDTH, item->generic.y, item->generic.name, style|UI_RIGHT, color );
+
+ UI_DrawHandlePic( item->generic.x + BIGCHAR_HEIGHT+4 - 20, item->generic.y + 8, 128, 8, s_preferences.fxBasePic );
+ UI_DrawHandlePic( item->generic.x + BIGCHAR_HEIGHT+4 + item->curvalue * 16 + 8 - 20, item->generic.y + 6, 16, 12, s_preferences.fxPic[item->curvalue] );
+}
+
+
static void Preferences_MenuInit( void ) {
int y;
@@ -234,18 +321,33 @@ static void Preferences_MenuInit( void ) {
y = 144;
s_preferences.crosshair.generic.type = MTYPE_TEXT;
s_preferences.crosshair.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT|QMF_NODEFAULTINIT|QMF_OWNERDRAW;
- s_preferences.crosshair.generic.x = PREFERENCES_X_POS;
- s_preferences.crosshair.generic.y = y;
+ s_preferences.crosshair.generic.x = PREFERENCES_X_POS;
+ s_preferences.crosshair.generic.y = y;
s_preferences.crosshair.generic.name = "Crosshair:";
s_preferences.crosshair.generic.callback = Preferences_Event;
s_preferences.crosshair.generic.ownerdraw = Crosshair_Draw;
- s_preferences.crosshair.generic.id = ID_CROSSHAIR;
- s_preferences.crosshair.generic.top = y - 4;
+ s_preferences.crosshair.generic.id = ID_CROSSHAIR;
+ s_preferences.crosshair.generic.top = y - 4;
s_preferences.crosshair.generic.bottom = y + 20;
s_preferences.crosshair.generic.left = PREFERENCES_X_POS - ( ( strlen(s_preferences.crosshair.generic.name) + 1 ) * SMALLCHAR_WIDTH );
s_preferences.crosshair.generic.right = PREFERENCES_X_POS + 48;
y += BIGCHAR_HEIGHT+2+4;
+ s_preferences.crosshaircolor.generic.type = MTYPE_SPINCONTROL;
+ s_preferences.crosshaircolor.generic.flags = QMF_NODEFAULTINIT;
+ s_preferences.crosshaircolor.generic.x = PREFERENCES_X_POS - 24;
+ s_preferences.crosshaircolor.generic.y = y;
+ s_preferences.crosshaircolor.generic.name = "Crosshair Color:";
+ s_preferences.crosshaircolor.generic.callback = Preferences_Event;
+ s_preferences.crosshaircolor.generic.ownerdraw = CrosshairColor_Draw;
+ s_preferences.crosshaircolor.generic.id = ID_CROSSHAIRCOLOR;
+ s_preferences.crosshaircolor.generic.top = y - 4;
+ s_preferences.crosshaircolor.generic.bottom = y + 20;
+ s_preferences.crosshaircolor.generic.left = PREFERENCES_X_POS - ( ( (int)strlen(s_preferences.crosshaircolor.generic.name) + 1 ) * SMALLCHAR_WIDTH );
+ s_preferences.crosshaircolor.generic.right = PREFERENCES_X_POS + 48;
+ s_preferences.crosshaircolor.numitems = 8;
+
+ y += BIGCHAR_HEIGHT+24;
s_preferences.simpleitems.generic.type = MTYPE_RADIOBUTTON;
s_preferences.simpleitems.generic.name = "Simple Items:";
s_preferences.simpleitems.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
@@ -353,6 +455,7 @@ static void Preferences_MenuInit( void ) {
Menu_AddItem( &s_preferences.menu, &s_preferences.framer );
Menu_AddItem( &s_preferences.menu, &s_preferences.crosshair );
+ Menu_AddItem( &s_preferences.menu, &s_preferences.crosshaircolor );
Menu_AddItem( &s_preferences.menu, &s_preferences.simpleitems );
Menu_AddItem( &s_preferences.menu, &s_preferences.wallmarks );
Menu_AddItem( &s_preferences.menu, &s_preferences.brass );
@@ -385,6 +488,15 @@ void Preferences_Cache( void ) {
for( n = 0; n < NUM_CROSSHAIRS; n++ ) {
s_preferences.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
}
+
+ s_preferences.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
+ s_preferences.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
+ s_preferences.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );
+ s_preferences.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
+ s_preferences.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
+ s_preferences.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_CYAN );
+ s_preferences.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_TEAL );
+ s_preferences.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
}