Doom 1.3 - Quest 3 Realtime Shadows

Credit to Lubos for Multi-view stencil fix.
New Quest 3 default
Shadow Optimisations
New Menu additions
This commit is contained in:
Grant Bagwell 2023-10-14 23:26:12 +02:00
parent 88c4f85455
commit e680ff2675
8 changed files with 397 additions and 12 deletions

View file

@ -42,6 +42,7 @@ android {
}
compileSdkVersion = 26
buildToolsVersion = '29.0.1'
ndkVersion '21.1.6352462'
/* buildTypes {
release {
debuggable true

View file

@ -82,7 +82,7 @@ PFNEGLGETSYNCATTRIBKHRPROC eglGetSyncAttribKHR;
//Let's go to the maximum!
const int CPU_LEVEL = 4;
const int GPU_LEVEL = 4;
const int GPU_LEVEL = 5;
//Passed in from the Java code
int NUM_MULTI_SAMPLES = -1;
@ -578,7 +578,7 @@ static bool ovrFramebuffer_Create(
// Create the depth buffer texture.
GL(glGenTextures(1, &frameBuffer->DepthBuffers[i]));
GL(glBindTexture(GL_TEXTURE_2D_ARRAY, frameBuffer->DepthBuffers[i]));
GL(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT24, width, height, 2));
GL(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH24_STENCIL8, width, height, 2));
GL(glBindTexture(GL_TEXTURE_2D_ARRAY, 0));
// Create the frame buffer.
@ -593,6 +593,14 @@ static bool ovrFramebuffer_Create(
multisamples /* samples */,
0 /* baseViewIndex */,
2 /* numViews */));
GL(glFramebufferTextureMultisampleMultiviewOVR(
GL_DRAW_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
frameBuffer->DepthBuffers[i],
0 /* level */,
multisamples /* samples */,
0 /* baseViewIndex */,
2 /* numViews */));
GL(glFramebufferTextureMultisampleMultiviewOVR(
GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
@ -609,6 +617,13 @@ static bool ovrFramebuffer_Create(
0 /* level */,
0 /* baseViewIndex */,
2 /* numViews */));
GL(glFramebufferTextureMultiviewOVR(
GL_DRAW_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
frameBuffer->DepthBuffers[i],
0 /* level */,
0 /* baseViewIndex */,
2 /* numViews */));
GL(glFramebufferTextureMultiviewOVR(
GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
@ -633,7 +648,7 @@ static bool ovrFramebuffer_Create(
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glRenderbufferStorageMultisampleEXT(
GL_RENDERBUFFER, multisamples, GL_DEPTH_COMPONENT24, width, height));
GL_RENDERBUFFER, multisamples, GL_DEPTH24_STENCIL8, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// Create the frame buffer.
@ -652,6 +667,11 @@ static bool ovrFramebuffer_Create(
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER));
GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
@ -675,6 +695,11 @@ static bool ovrFramebuffer_Create(
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(glFramebufferRenderbuffer(
GL_DRAW_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
@ -720,8 +745,8 @@ void ovrFramebuffer_SetNone()
void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer )
{
// Discard the depth buffer, so the tiler won't need to write it back out to memory.
const GLenum depthAttachment[1] = { GL_DEPTH_ATTACHMENT };
glInvalidateFramebuffer( GL_DRAW_FRAMEBUFFER, 1, depthAttachment );
const GLenum depthAttachment[2] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
glInvalidateFramebuffer( GL_DRAW_FRAMEBUFFER, 2, depthAttachment );
}
void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer )
@ -1612,9 +1637,30 @@ void * AppThreadFunction(void * parm ) {
NUM_MULTI_SAMPLES = 1;
}
}
else if (vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y) > 101)
{
questType = 3;
if (DISPLAY_REFRESH == -1)
{
DISPLAY_REFRESH = 72.0;
}
if (SS_MULTIPLIER == -1.0f)
{
SS_MULTIPLIER = 1.1f;
}
if (NUM_MULTI_SAMPLES == -1)
{
NUM_MULTI_SAMPLES = 1;
}
}
else if (vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_DEVICE_TYPE) == VRAPI_DEVICE_TYPE_OCULUSQUEST2)
{
questType = 2;
if (DISPLAY_REFRESH == -1)
{
DISPLAY_REFRESH = 60.0;
}
if (SS_MULTIPLIER == -1.0f)
{
SS_MULTIPLIER = 1.1f;
@ -1654,6 +1700,32 @@ void * AppThreadFunction(void * parm ) {
showLoadingIcon();
}
int maximumSupportRefresh = 0;
//AmmarkoV : Query Refresh rates and select maximum..!
//-----------------------------------------------------------------------------------------------------------
int numberOfRefreshRates = vrapi_GetSystemPropertyInt(&java,
VRAPI_SYS_PROP_NUM_SUPPORTED_DISPLAY_REFRESH_RATES);
float refreshRatesArray[16]; //Refresh rates are currently (12/2020) the following 4 : 60.0 / 72.0 / 80.0 / 90.0
if (numberOfRefreshRates > 16) { numberOfRefreshRates = 16; }
vrapi_GetSystemPropertyFloatArray(&java, VRAPI_SYS_PROP_SUPPORTED_DISPLAY_REFRESH_RATES,
&refreshRatesArray[0], numberOfRefreshRates);
for (int i = 0; i < numberOfRefreshRates; i++) {
ALOGV("Supported refresh rate : %d Hz", refreshRatesArray[i]);
if (maximumSupportRefresh < refreshRatesArray[i]) {
maximumSupportRefresh = refreshRatesArray[i];
}
}
if (maximumSupportRefresh > 90.0) {
ALOGV("Soft limiting to 90.0 Hz as per John carmack's request ( https://www.onlinepeeps.org/oculus-quest-2-according-to-carmack-in-the-future-also-at-120-hz/ );P");
maximumSupportRefresh = 90.0;
}
if (DISPLAY_REFRESH == 0 || DISPLAY_REFRESH > maximumSupportRefresh)
{
DISPLAY_REFRESH = 72.0;
}
//Should now be all set up and ready - start the Doom3 main loop
VR_Doom3Main(argc, argv);

View file

@ -64,7 +64,7 @@ idCVar r_useNodeCommonChildren( "r_useNodeCommonChildren", "1", CVAR_RENDERER |
idCVar r_useShadowProjectedCull( "r_useShadowProjectedCull", "1", CVAR_RENDERER | CVAR_BOOL, "discard triangles outside light volume before shadowing" );
idCVar r_useShadowSurfaceScissor( "r_useShadowSurfaceScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor shadows by the scissor rect of the interaction surfaces" );
idCVar r_useInteractionTable( "r_useInteractionTable", "1", CVAR_RENDERER | CVAR_BOOL, "create a full entityDefs * lightDefs table to make finding interactions faster" );
idCVar r_useTurboShadow( "r_useTurboShadow", "1", CVAR_RENDERER | CVAR_BOOL, "use the infinite projection with W technique for dynamic shadows" );
idCVar r_useTurboShadow( "r_useTurboShadow", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "use the infinite projection with W technique for dynamic shadows" );
idCVar r_useDeferredTangents( "r_useDeferredTangents", "1", CVAR_RENDERER | CVAR_BOOL, "defer tangents calculations after deform" );
idCVar r_useCachedDynamicModels( "r_useCachedDynamicModels", "1", CVAR_RENDERER | CVAR_BOOL, "cache snapshots of dynamic models" );
idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" );
@ -133,7 +133,7 @@ idCVar r_lightSourceRadius( "r_lightSourceRadius", "0", CVAR_RENDERER | CVAR_FLO
idCVar r_flareSize( "r_flareSize", "1", CVAR_RENDERER | CVAR_FLOAT, "scale the flare deforms from the material def" );
idCVar r_useExternalShadows( "r_useExternalShadows", "1", CVAR_RENDERER | CVAR_INTEGER, "1 = skip drawing caps when outside the light volume, 2 = force to no caps for testing", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
idCVar r_useOptimizedShadows( "r_useOptimizedShadows", "1", CVAR_RENDERER | CVAR_BOOL, "use the dmap generated static shadow volumes" );
idCVar r_useOptimizedShadows( "r_useOptimizedShadows", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "use the dmap generated static shadow volumes" );
idCVar r_useScissor( "r_useScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor clip as portals and lights are processed" );
idCVar r_screenFraction( "r_screenFraction", "100", CVAR_RENDERER | CVAR_INTEGER, "for testing fill rate, the resolution of the entire screen can be changed" );

Binary file not shown.

View file

@ -232,7 +232,7 @@ seta vr_crouchMode "0"
seta vr_moveThirdPerson "1"
seta vr_playerBodyMode "0"
seta vr_moveClick "0"
seta vr_movePoint "1"
seta vr_movePoint "2"
seta vr_comfortRepeat "100"
seta vr_pdaPitch "30"
seta vr_pdaPosZ "5.0"

View file

@ -162,7 +162,7 @@ seta g_password ""
seta g_showBrass "1"
seta g_showProjectilePct "0"
seta g_showHud "1"
seta g_showPlayerShadow "0"
seta g_showPlayerShadow "1"
seta g_showcamerainfo "0"
seta g_healthTakeLimit "25"
seta g_healthTakeAmt "5"
@ -193,7 +193,7 @@ seta si_gameType "singleplayer"
seta si_name "dhewm server"
seta g_spectatorChat "0"
seta net_clientLagOMeter "1"
seta g_weaponShadows "0"
seta g_weaponShadows "1"
seta g_useWeaponDepthHack "0"
seta g_xp_bind_run_once "0"
seta vr_weaponHand "0"
@ -232,7 +232,7 @@ seta vr_crouchMode "0"
seta vr_moveThirdPerson "1"
seta vr_playerBodyMode "0"
seta vr_moveClick "0"
seta vr_movePoint "1"
seta vr_movePoint "2"
seta vr_comfortRepeat "100"
seta vr_pdaPitch "30"
seta vr_pdaPosZ "5.0"

308
assets/quest3_default.cfg Normal file
View file

@ -0,0 +1,308 @@
unbindall
bind "TAB" "_impulse19"
bind "ENTER" "_button2"
bind "ESCAPE" "togglemenu"
bind "SPACE" "_moveup"
bind "/" "_impulse14"
bind "0" "_impulse10"
bind "1" "_impulse0"
bind "2" "_impulse1"
bind "3" "_impulse2"
bind "4" "_impulse3"
bind "5" "_impulse4"
bind "6" "_impulse5"
bind "7" "_impulse6"
bind "8" "_impulse7"
bind "9" "_impulse8"
bind "[" "_impulse15"
bind "\" "_mlook"
bind "]" "_impulse14"
bind "a" "_moveleft"
bind "c" "_movedown"
bind "d" "_moveright"
bind "f" "_impulse11"
bind "q" "_impulse9"
bind "r" "_impulse13"
bind "s" "_back"
bind "t" "clientMessageMode"
bind "w" "_forward"
bind "y" "clientMessageMode 1"
bind "z" "_zoom"
bind "BACKSPACE" "clientDropWeapon"
bind "PAUSE" "pause"
bind "UPARROW" "_forward"
bind "DOWNARROW" "_back"
bind "LEFTARROW" "_left"
bind "RIGHTARROW" "_right"
bind "ALT" "_strafe"
bind "CTRL" "_attack"
bind "SHIFT" "_speed"
bind "DEL" "_lookdown"
bind "PGDN" "_lookup"
bind "END" "_impulse18"
bind "F1" "_impulse28"
bind "F2" "_impulse29"
bind "F3" "_impulse17"
bind "F5" "savegame quick"
bind "F6" "_impulse20"
bind "F7" "_impulse22"
bind "F9" "loadgame quick"
bind "F12" "screenshot"
bind "MOUSE1" "_attack"
bind "MOUSE2" "_moveup"
bind "MOUSE3" "_zoom"
bind "MWHEELDOWN" "_impulse14"
bind "MWHEELUP" "_impulse15"
seta sys_lang "english"
seta in_kbd "english"
seta gui_mediumFontLimit "0.60"
seta gui_smallFontLimit "0.30"
seta s_decompressionLimit "6"
seta s_useEAXReverb "1"
seta s_numberOfSpeakers "2"
seta s_doorDistanceAdd "150"
seta s_globalFraction "0.8"
seta s_subFraction "0.75"
seta s_playDefaultSound "1"
seta s_volume_dB "0"
seta s_meterTopTime "2000"
seta s_reverse "0"
seta s_spatializationDecay "2"
seta s_maxSoundsPerShader "1"
seta s_device "default"
seta gui_filter_game "0"
seta gui_filter_idle "0"
seta gui_filter_gameType "0"
seta gui_filter_players "0"
seta gui_filter_password "0"
seta net_clientDownload "1"
seta net_master4 ""
seta net_master3 ""
seta net_master2 ""
seta net_master1 ""
seta net_clientMaxRate "16000"
seta net_serverMaxClientRate "16000"
seta com_guid ""
seta com_fixedTic "0"
seta com_skipTics "1"
seta gui_configServerRate "0"
seta m_strafeSmooth "4"
seta m_smooth "1"
seta m_strafeScale "6.25"
seta m_yaw "0.022"
seta m_pitch "0.022"
seta sensitivity "5"
seta in_toggleZoom "0"
seta in_toggleCrouch "1"
seta in_toggleRun "0"
seta in_alwaysRun "0"
seta in_freeLook "1"
seta in_anglespeedkey "1.5"
seta in_pitchspeed "140"
seta in_yawspeed "140"
seta com_preloadDemos "0"
seta com_compressDemos "1"
seta com_product_lang_ext "1"
seta com_showFPS "0"
seta com_purgeAll "1"
seta vr_msaa "2"
seta vr_supersampling "1.1"
seta vr_refresh "72"
seta r_scaleMenusTo43 "1"
seta r_debugArrowStep "120"
seta r_debugLineWidth "1"
seta r_debugLineDepthTest "0"
seta r_forceLoadImages "0"
seta r_shadows "1"
seta r_skipBump "0"
seta r_skipSpecular "0"
seta r_skipNewAmbient "1"
seta r_brightness "1.480604"
seta r_gamma "1"
seta r_swapInterval "1"
seta r_customHeight "486"
seta r_customWidth "720"
seta r_fullscreen "0"
seta r_mode "3"
seta r_multiSamples "0"
seta image_downSizeLimit "256"
seta image_downSizeBumpLimit "256"
seta image_downSizeSpecularLimit "64"
seta image_downSizeBump "0"
seta image_downSizeSpecular "0"
seta image_roundDown "1"
seta image_forceDownSize "0"
seta image_downSize "0"
seta image_preload "1"
seta image_anisotropy "0"
seta image_filter "GL_LINEAR_MIPMAP_LINEAR"
seta g_projectileLights "0"
seta g_hitEffect "0"
seta g_doubleVision "0"
seta g_decals "1"
seta g_muzzleFlash "1"
seta vr_hudmode "0"
seta vr_turnangle "45"
seta vr_turnmode "0"
seta vr_throwables "1"
seta vr_weaponsight "1"
seta vr_knockback "0"
seta vr_shakeamplitude "1.0"
seta vr_heightoffset "0.0"
seta vr_ipd "0.065"
seta net_serverDlTable ""
seta net_serverDlBaseURL ""
seta net_serverDownload "0"
seta mod_validSkins "skins/characters/player/marine_mp;skins/characters/player/marine_mp_green;skins/characters/player/marine_mp_blue;skins/characters/player/marine_mp_red;skins/characters/player/marine_mp_yellow"
seta g_mapCycle "mapcycle"
seta g_voteFlags "0"
seta g_gameReviewPause "10"
seta g_countDown "10"
seta g_password ""
seta g_showBrass "1"
seta g_showProjectilePct "0"
seta g_showHud "1"
seta g_showPlayerShadow "1"
seta g_showcamerainfo "0"
seta g_healthTakeLimit "25"
seta g_healthTakeAmt "5"
seta g_healthTakeTime "5"
seta g_useDynamicProtection "1"
seta g_armorProtectionMP "0.6"
seta g_armorProtection "0.3"
seta g_damageScale "1"
seta g_nightmare "0"
seta g_bloodEffects "1"
seta r_aspectRatio "-1"
seta ui_showGun "1"
seta ui_autoReload "1"
seta ui_autoSwitch "0"
seta ui_team "Red"
seta ui_skin "skins/characters/player/marine_mp"
seta ui_name "Player"
seta si_serverURL ""
seta si_spectators "1"
seta si_usePass "0"
seta si_warmup "0"
seta si_teamDamage "0"
seta si_timeLimit "10"
seta si_fragLimit "10"
seta si_maxPlayers "4"
seta si_map "game/mp/d3dm1"
seta si_gameType "singleplayer"
seta si_name "dhewm server"
seta g_spectatorChat "0"
seta net_clientLagOMeter "1"
seta g_weaponShadows "1"
seta g_useWeaponDepthHack "0"
seta g_xp_bind_run_once "0"
seta vr_weaponHand "0"
seta vr_throwPower "3.5"
seta vr_rumbleChainsaw "1"
seta vr_dualWield "2"
seta vr_contextSensitive "1"
seta vr_mustEmptyHands "0"
seta vr_gripMode "0"
seta vr_weaponCycleMode "0"
seta vr_headshotMultiplier "2.5"
seta vr_headshotMultiplierRecruit "1.8"
seta vr_headshotMultiplierNormal "1.5"
seta vr_headshotMultiplierHard "1.25"
seta vr_headshotMultiplierNightmare "1.1"
seta vr_shotgunChoke "90"
seta vr_instantAccel "1"
seta vr_cinematics "0"
seta vr_autoSwitchControllers "1"
seta vr_handSwapsAnalogs "0"
seta vr_strobeTime "500"
seta vr_motionSickness "0"
seta vr_teleportThroughDoors "0"
seta vr_teleportMaxTravel "950"
seta vr_teleportMode "0"
seta vr_teleport "2"
seta vr_useHandPoses "0"
seta vr_teleportHint "0"
seta vr_teleportButtonMode "0"
seta vr_teleportShowAimAssist "0"
seta vr_teleportSkipHandrails "0"
seta vr_frameCheck "1"
seta vr_crouchHideBody "1"
seta vr_crouchTriggerDist "7"
seta vr_crouchMode "0"
seta vr_moveThirdPerson "1"
seta vr_playerBodyMode "0"
seta vr_moveClick "0"
seta vr_movePoint "2"
seta vr_comfortRepeat "100"
seta vr_pdaPitch "30"
seta vr_pdaPosZ "5.0"
seta vr_pdaPosY "4.0"
seta vr_pdaPosX "6.0"
seta vr_headbbox "10.0"
seta vr_walkSpeedAdjust "20.0"
seta vr_stepSmooth "1"
seta vr_jumpBounce "0"
seta vr_3dgui "1"
seta vr_mountedWeaponController "0"
seta vr_mountz "0"
seta vr_mounty "0"
seta vr_mountx "0"
seta vr_vcz "0"
seta vr_vcy "0"
seta vr_vcx "0"
seta vr_controllerOffsetX "-1.4"
seta vr_controllerOffsetY "-1.32"
seta vr_controllerOffsetZ "-0.9"
seta vr_nodalZ "-6"
seta vr_nodalX "-3"
seta vr_motionFlashPitchAdj "0"
seta vr_motionWeaponPitchAdj "17.354475"
seta vr_weaponSightToSurface "1"
seta vr_deadzoneYaw "30"
seta vr_deadzonePitch "90"
seta vr_joystickMenuMapping "1"
seta vr_headKick "0"
seta vr_disableWeaponAnimation "1"
seta vr_wristStatMon "2"
seta vr_hudLowHealth "20"
seta vr_hudOcclusion "1"
seta vr_hudTransparency "1"
seta vr_hudRevealAngle "40"
seta vr_hudType "1"
seta vr_hudPosLock "1"
seta vr_hudPosAngle "30"
seta vr_hudPosDist "24"
seta vr_hudPosVert "4"
seta vr_hudPosHorz "0"
seta vr_hudScale "0.95"
seta vr_guiMode "2"
seta vr_guiSeparation ".01"
seta vr_guiScale "1"
seta vr_weaponPivotForearmLength "16"
seta vr_weaponPivotOffsetVertical "0"
seta vr_weaponPivotOffsetHorizontal "0"
seta vr_weaponPivotOffsetForward "3"
seta vr_PDAfixLocation "0"
seta vr_forward_keyhole "11.25"
seta vr_flashlightHelmetPosZ "-20"
seta vr_flashlightHelmetPosY "-6"
seta vr_flashlightHelmetPosX "6"
seta vr_flashlightBodyPosZ "0"
seta vr_flashlightBodyPosY "0"
seta vr_flashlightBodyPosX "0"
seta vr_flashlightStrict "0"
seta vr_flashlightMode "3"
seta vr_normalViewHeight "73"
seta vr_useFloorHeight "1"
seta vr_scale "1.0"
seta g_laserSightLength "1000"
seta g_laserSightWidth "0.3"
seta vr_slotDisable "0"
seta vr_slotDur "18"
seta vr_slotMag "0.1"
seta vr_laserSightUseOffset "1"
seta vr_guiFocusPitchAdj "7"
seta vr_wipScale "1.0"
seta vr_grabberBeamWidth "4"
seta vr_headScale "1.085"
seta vr_switchSticks "0"

View file

@ -226,6 +226,7 @@ import static android.system.Os.setenv;
//these so forcefully overwrite
copy_asset("/sdcard/Doom3Quest/config/base", "quest1_default.cfg", true);
copy_asset("/sdcard/Doom3Quest/config/base", "quest2_default.cfg", true);
copy_asset("/sdcard/Doom3Quest/config/base", "quest3_default.cfg", true);
if (exitAfterCopy)
{
@ -270,10 +271,13 @@ import static android.system.Os.setenv;
}
//GB Change per headset defaults
//Parse the config file for these values
long refresh = 60; // Default to 60
long refresh = -1; // Let the Surface View Default this
float ss = -1.0F;
long msaa = 1; // default for both HMDs
String configFileName = "/sdcard/Doom3Quest/config/base/doom3quest.cfg";
if(new File(configFileName).exists())
{