Skip to content

Commit

Permalink
Mostly complete support of Worldcraft/VHE3 configuration files
Browse files Browse the repository at this point in the history
  • Loading branch information
LogicAndTrick committed Dec 30, 2024
1 parent fe515c8 commit 52d008d
Show file tree
Hide file tree
Showing 16 changed files with 509 additions and 53 deletions.
3 changes: 1 addition & 2 deletions Sledge.Formats.Configuration.Tests/RegistryUtil.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics;
using Microsoft.Win32;
using Microsoft.Win32;
using Sledge.Formats.Configuration.Registry;

namespace Sledge.Formats.Configuration.Tests;
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
<UseVSTest>true</UseVSTest>
</PropertyGroup>

<ItemGroup>
<None Remove="Resources\Worldcraft\GameCfg-wc20.wc" />
<None Remove="Resources\Worldcraft\GameCfg-wc33.wc" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Resources\Worldcraft\GameCfg-wc20.wc" />
<EmbeddedResource Include="Resources\Worldcraft\GameCfg-wc33.wc" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sledge.Formats.Configuration\Sledge.Formats.Configuration.csproj" />
</ItemGroup>
Expand Down
220 changes: 207 additions & 13 deletions Sledge.Formats.Configuration.Tests/TestWorldcraftConfiguration.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sledge.Formats\Sledge.Formats.csproj" />
</ItemGroup>

</Project>
8 changes: 4 additions & 4 deletions Sledge.Formats.Configuration/Worldcraft/MapType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace Sledge.Formats.Configuration.Worldcraft
{
public enum MapType
{
HalfLife,
[Obsolete] Quake,
[Obsolete] Quake2,
[Obsolete] Hexen2,
HalfLife = 3,
[Obsolete] Quake = 0,
[Obsolete] Quake2 = 2,
[Obsolete] Hexen2 = 1,
}
}
6 changes: 3 additions & 3 deletions Sledge.Formats.Configuration/Worldcraft/TextureFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Sledge.Formats.Configuration.Worldcraft
{
public enum TextureFormat
{
Wad3,
[Obsolete] Wad2,
[Obsolete] Wal,
Wad3 = 2,
[Obsolete] Wad2 = 0,
[Obsolete] Wal = 1,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ public class Worldcraft2DViewsConfiguration
/// <summary>
/// Grid configuration
/// </summary>
public WorldcraftGridOptions Grid { get; set; }
public WorldcraftGridOptions Grid { get; } = new WorldcraftGridOptions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class Worldcraft3DViewsConfiguration
/// <summary>
/// Time to top speed (0-10 seconds)
/// </summary>
public float TimeToTopSpeed { get; set; }
public decimal TimeToTopSpeed { get; set; }

/// <summary>
/// Reverse selection order
Expand All @@ -52,6 +52,6 @@ public class Worldcraft3DViewsConfiguration
/// <summary>
/// Background color
/// </summary>
public Color BackgroundColor { get; set; }
public Color BackgroundColor { get; set; } = Color.Black;
}
}
80 changes: 76 additions & 4 deletions Sledge.Formats.Configuration/Worldcraft/WorldcraftConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using Sledge.Formats.Configuration.Registry;
Expand All @@ -17,7 +18,7 @@ public static WorldcraftConfiguration LoadFromRegistry(WorldcraftConfigurationLo
{
settings = settings ?? WorldcraftConfigurationLoadSettings.Default;
var key = settings.RegistryLocation;
if (settings.AutodetectRegistryLocation)
if (settings.AutodetectRegistryLocation && key == null)
{
var reg = new WindowsRegistry();
var baseKey = reg.OpenBaseKey(settings.RegistryHive, settings.RegistryView);
Expand All @@ -27,9 +28,28 @@ public static WorldcraftConfiguration LoadFromRegistry(WorldcraftConfigurationLo

var config = new WorldcraftConfiguration();
(config.General, config.TextureDirectories) = LoadGeneralRegistry(key.OpenSubKey(WorldcraftRegistryInfo.KeyGeneral));
config.Views2D = null;
config.Views3D = null;
config.GameConfigurations = null;
config.Views2D = LoadViews2DRegistry(key.OpenSubKey(WorldcraftRegistryInfo.Key2DViews));
config.Views3D = LoadViews3DRegistry(key.OpenSubKey(WorldcraftRegistryInfo.Key3DViews));

var installDir = settings.InstallDirectory;
if (settings.AutodetectInstallDirectory && installDir == null)
{
installDir = config.General.InstallDirectory;
}

if (settings.LoadGameConfigurations && Directory.Exists(installDir))
{
var configFile = Path.Combine(installDir, "GameCfg.wc");
if (File.Exists(configFile))
{
using (var fs = File.OpenRead(configFile))
{
var cfg = new WorldcraftGameConfigurationFile(fs);
config.GameConfigurations = cfg.Configurations;
}
}
}

return config;
}

Expand Down Expand Up @@ -59,6 +79,58 @@ private static (WorldcraftGeneralConfiguration, List<string>) LoadGeneralRegistr
return (config, textures);
}

private static Worldcraft2DViewsConfiguration LoadViews2DRegistry(IRegistryKey key)
{
var config = new Worldcraft2DViewsConfiguration();
if (key != null)
{
config.CrosshairCursor = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsCrosshairs);
config.DefaultTo15DegreeRotations = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsRotateConstrain);
config.DisplayScrollbars = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsScrollbars);
config.DrawVertices = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsDrawVertices);
config.WhiteOnBlackColorScheme = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsWhiteOnBlack);
config.KeepGroupWhenCloneDragging = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsKeepCloneGroup);
config.CenterOnCameraAfterMovement = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsCenterOnCamera);
config.UseVisgroupColorsForObjectLines = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsUseGroupColors);
config.ArrowKeysNudgeSelectedObject = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsNudge);
config.ReorientPrimitivesOnCreation = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsOrientPrimitives);
config.AutomaticInfiniteSelection = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsAutoSelect);
config.SelectionBoxSelectsByCenterHandlesOnly = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsSelectByHandles);

config.Grid.Size = key.GetIntValue(WorldcraftRegistryInfo.Key2DViewsDefaultGrid);
config.Grid.Intensity = key.GetIntValue(WorldcraftRegistryInfo.Key2DViewsGridIntensity);
config.Grid.HighlightEvery64Units = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsGridHigh64);
var nLines = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsGridHigh10);
config.Grid.HighlightEveryNGridLines = nLines ? key.GetIntValue(WorldcraftRegistryInfo.Key2DViewsGridHighSpec) : 0;
config.Grid.HideGridSmallerThan4Pixels = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsHideSmallGrid);
config.Grid.HighlightEvery1024Units = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsGridHigh1024);
config.Grid.DottedGrid = key.GetBoolValue(WorldcraftRegistryInfo.Key2DViewsGridDots);

}
return config;
}

private static Worldcraft3DViewsConfiguration LoadViews3DRegistry(IRegistryKey key)
{
var config = new Worldcraft3DViewsConfiguration();
if (key != null)
{
//load 3d view settings into config of type Worldcraft3DViewsConfiguration:
config.BackClippingPlane = key.GetIntValue(WorldcraftRegistryInfo.Key3DViewsBackPlane);
config.FilterTextures = key.GetBoolValue(WorldcraftRegistryInfo.Key3DViewsFilterTextures);
config.AnimateModels = key.GetBoolValue(WorldcraftRegistryInfo.Key3DViewsAnimateModels);
config.ModelRenderDistance = key.GetIntValue(WorldcraftRegistryInfo.Key3DViewsModelDistance);
config.UseMouselookNavigation = key.GetBoolValue(WorldcraftRegistryInfo.Key3DViewsUseMouseLook);
config.ReverseMouseYAxis = key.GetBoolValue(WorldcraftRegistryInfo.Key3DViewsReverseY);
config.ForwardSpeed = key.GetIntValue(WorldcraftRegistryInfo.Key3DViewsForwardSpeedMax);
config.TimeToTopSpeed = key.GetIntValue(WorldcraftRegistryInfo.Key3DViewsTimeToMaxSpeed) / 1000m;
config.ReverseSelectionOrder = key.GetBoolValue(WorldcraftRegistryInfo.Key3DViewsReverseSelection);
config.BackgroundColor = Color.FromArgb(255, Color.FromArgb(key.GetIntValue(WorldcraftRegistryInfo.Key3DViewsClearColor)));
}
return config;
}


private static IRegistryKey FindDefaultRegistryKey(IRegistryKey baseKey)
{
foreach (var path in WorldcraftRegistryInfo.DefaultRegistryPaths)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System.IO;
using System.Linq;
using Microsoft.Win32;
using Microsoft.Win32;
using Sledge.Formats.Configuration.Registry;

namespace Sledge.Formats.Configuration.Worldcraft
{
public class WorldcraftConfigurationLoadSettings
{
/// <summary>
/// True to attempt to autodetect the registry location from the known default registry locations
/// True to attempt to autodetect the registry location from the known default registry locations.
/// Ignored if <see cref="RegistryLocation">RegistryLocation</see> is not null.
/// </summary>
public bool AutodetectRegistryLocation { get; set; } = true;

Expand All @@ -23,7 +22,7 @@ public class WorldcraftConfigurationLoadSettings
public RegistryView RegistryView { get; set; } = RegistryView.Default;

/// <summary>
/// Set to a non-null value and set <see cref="AutodetectRegistryLocation">AutodetectRegistryLocation</see> to false to specify the registry location.
/// Set to a non-null value to specify the registry location.
/// The registry location will usually be called "Worldcraft" or "Valve Hammer Editor" and contain subkeys called "General", "2D Views", "3D Views", etc.
/// </summary>
public IRegistryKey RegistryLocation { get; set; }
Expand All @@ -36,11 +35,12 @@ public class WorldcraftConfigurationLoadSettings
/// <summary>
/// True to attempt to autodetect the install directory from the registry ([Worldcraft/General/Directory] registry key).
/// All worldcraft versions store the install directory in the registry except for version 1.0.
/// Ignored if <see cref="InstallDirectory">InstallDirectory</see> is not null.
/// </summary>
public bool AutodetectInstallDirectory { get; set; } = true;

/// <summary>
/// Set to a non-null value and set <see cref="AutodetectInstallDirectory">AutodetectInstallDirectory</see> to false to specify the install directory
/// Set to a non-null value to specify the install directory
/// </summary>
public string InstallDirectory { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,61 @@ public class WorldcraftGameConfiguration
/// <summary>
/// Configuration name
/// </summary>
public string Name { get; set; }
public string Name { get; set; } = "";

/// <summary>
/// List of game data files (.fgd)
/// </summary>
public List<string> GameDataFiles { get; set; }
public List<string> GameDataFiles { get; set; } = new List<string>();

/// <summary>
/// Texture Format
/// </summary>
public TextureFormat TextureFormat { get; set; }
public TextureFormat TextureFormat { get; set; } = TextureFormat.Wad3;

/// <summary>
/// Map Type
/// </summary>
public MapType MapType { get; set; }
public MapType MapType { get; set; } = MapType.HalfLife;

/// <summary>
/// Default PointEntity class
/// </summary>
public string DefaultPointEntityClass { get; set; }
public string DefaultPointEntityClass { get; set; } = "";

/// <summary>
/// Default SolidEntity class
/// </summary>
public string DefaultSolidEntityClass { get; set; }
public string DefaultSolidEntityClass { get; set; } = "";

/// <summary>
/// Game executable directory (ex: C:\HalfLife)
/// </summary>
public string GameExecutableDirectory { get; set; }
public string GameExecutableDirectory { get; set; } = "";

/// <summary>
/// Mod directory (ex: C:\HalfLife\tfc)
/// </summary>
public string ModDirectory { get; set; }
public string ModDirectory { get; set; } = "";

/// <summary>
/// Game directory (ex: C:\HalfLife\valve)
/// </summary>
public string GameDirectory { get; set; }
public string GameDirectory { get; set; } = "";

/// <summary>
/// RMF directory
/// </summary>
public string RmfDirectory { get; set; }
public string RmfDirectory { get; set; } = "";

/// <summary>
/// Palette file
/// </summary>
[Obsolete] public string PaletteFile { get; set; }
[Obsolete] public string PaletteFile { get; set; } = "";

/// <summary>
/// Build programs for this configuration
/// </summary>
public WorldcraftGameConfigurationBuildPrograms BuildPrograms { get; set; }
public WorldcraftGameConfigurationBuildPrograms BuildPrograms { get; set; } = new WorldcraftGameConfigurationBuildPrograms();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@ public class WorldcraftGameConfigurationBuildPrograms
/// <summary>
/// Game executable
/// </summary>
public string GameExecutable { get; set; }
public string GameExecutable { get; set; } = "";

/// <summary>
/// CSG executable
/// </summary>
public string CsgExecutable { get; set; }
public string CsgExecutable { get; set; } = "";

/// <summary>
/// BSP executable
/// </summary>
public string BspExecutable { get; set; }
public string BspExecutable { get; set; } = "";

/// <summary>
/// VIS executable
/// </summary>
public string VisExecutable { get; set; }
public string VisExecutable { get; set; } = "";

/// <summary>
/// RAD executable
/// </summary>
public string RadExecutable { get; set; }
public string RadExecutable { get; set; } = "";

/// <summary>
/// Place compiled maps in this directory before running the game
/// </summary>
public string BspDirectory { get; set; }
public string BspDirectory { get; set; } = "";
}
}
Loading

0 comments on commit 52d008d

Please sign in to comment.