Compare commits

...

7 Commits

Author SHA1 Message Date
max
60b85960ff EditorGui setup 2024-07-12 19:09:59 +02:00
max
b003ffbaec Merge branch 'main' into ImGui 2024-07-12 18:08:28 +02:00
max
16b04ea22a Editor dummy code 2024-07-12 17:27:01 +02:00
dd3bbf1d5b - Re-added win libs 2024-07-11 23:48:45 +02:00
38080703ec - Deleted ignored folders 2024-07-11 23:47:43 +02:00
fe582c4fba - Added build configurations
- Configured csprojects
- CopyLibs functionality in builder
2024-07-11 23:46:32 +02:00
97c2b308f1 Added builder
Added shader importer
2024-07-06 23:33:04 +02:00
46 changed files with 833 additions and 86 deletions

9
.gitignore vendored
View File

@ -451,8 +451,13 @@ FodyWeavers.xsd
#------------------------- Nerfed ------------------------- #------------------------- Nerfed -------------------------
Bin/
Intermediate/
imgui.ini imgui.ini
# include libs # include libs
!/libs/lib64 !/Native/lib64
!/libs/x64 !/Native/x64

View File

@ -2,5 +2,10 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" /> <mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/Nerfed.Runtime/Libraries/FAudio" vcs="Git" />
<mapping directory="$PROJECT_DIR$/Nerfed.Runtime/Libraries/RefreshCS" vcs="Git" />
<mapping directory="$PROJECT_DIR$/Nerfed.Runtime/Libraries/SDL2CS" vcs="Git" />
<mapping directory="$PROJECT_DIR$/Nerfed.Runtime/Libraries/WellspringCS" vcs="Git" />
<mapping directory="$PROJECT_DIR$/Nerfed.Runtime/Libraries/dav1dfile" vcs="Git" />
</component> </component>
</project> </project>

7
Directory.Build.props Normal file
View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<OutDir>../Bin/$(MSBuildProjectName)</OutDir>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">../Intermediate/$(MSBuildProjectName)</BaseIntermediateOutputPath>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,129 @@
using System.Collections;
using System.ComponentModel;
using System.Reflection;
namespace Nerfed.Builder;
public class ArgsParser<TArgs> where TArgs : new()
{
private enum ArgType
{
None,
Key,
Value
}
public TArgs Arguments { get; }
private readonly string[] args;
private readonly Dictionary<string, PropertyInfo> argKeyPropertyMap = new Dictionary<string, PropertyInfo>();
public ArgsParser(string[] args)
{
this.args = args;
Arguments = new TArgs();
PropertyInfo[] properties = Arguments.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo property in properties)
{
ArgumentAttribute argAttribute = property.GetCustomAttribute<ArgumentAttribute>();
if (argAttribute == null || string.IsNullOrEmpty(argAttribute.ArgKey))
{
continue;
}
argKeyPropertyMap.Add(argAttribute.ArgKey, property);
}
}
public bool Parse()
{
PropertyInfo property = null;
ArgType lastArgType = ArgType.None;
for (int i = 0; i < args.Length; i++)
{
string arg = args[i];
if (arg[0] == '-')
{
if (!argKeyPropertyMap.TryGetValue(arg, out property))
{
Console.Error.WriteLine($"Invalid argument: {arg}, no such argument key exists");
return false;
}
// Boolean arguments require no value, set to true immidiately.
if (property.PropertyType == typeof(bool))
{
property.SetValue(Arguments, true);
lastArgType = ArgType.Value;
}
else
{
lastArgType = ArgType.Key;
}
}
else
{
if (lastArgType == ArgType.None)
{
Console.Error.WriteLine($"Invalid argument: {arg}, no argument key was provided");
return false;
}
Type propertyType = property.PropertyType;
if (propertyType.IsArray)
{
throw new InvalidOperationException("Arrays are not supported, use List<T> instead");
}
bool propertyTypeIsList = propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>);
if (propertyTypeIsList)
{
propertyType = propertyType.GenericTypeArguments[0];
}
TypeConverter typeConverter = TypeDescriptor.GetConverter(propertyType);
object value = typeConverter.ConvertFromString(arg);
if (value is string stringValue)
{
if (!string.IsNullOrEmpty(stringValue))
{
if (stringValue[0] == '"')
{
stringValue = stringValue.Substring(1, stringValue.Length - 1);
}
if (stringValue[^1] == '"')
{
stringValue = stringValue.Substring(0, stringValue.Length - 1);
}
value = stringValue;
}
}
if (propertyTypeIsList)
{
IList list = (IList)property.GetValue(Arguments);
if (list == null)
{
list = (IList)Activator.CreateInstance(property.PropertyType);
property.SetValue(Arguments, list);
}
list.Add(value);
}
else
{
property.SetValue(Arguments, value);
}
lastArgType = ArgType.Value;
}
}
return true;
}
}

View File

@ -0,0 +1,11 @@
namespace Nerfed.Builder;
public class ArgumentAttribute : Attribute
{
public string ArgKey { get; }
public ArgumentAttribute(string argKey)
{
ArgKey = argKey;
}
}

View File

@ -0,0 +1,16 @@
namespace Nerfed.Builder;
public class BuildArgs
{
[Argument("-build")]
public bool Build { get; set; }
[Argument("-projectPath")]
public string ProjectPath { get; set; }
[Argument("-platform")]
public string Platform { get; set; }
[Argument("-content")]
public List<string> ContentFiles { get; set; }
}

View File

@ -0,0 +1,149 @@
using System.Diagnostics;
namespace Nerfed.Builder;
public class Builder : IDisposable
{
private readonly Dictionary<string, IImporter> importers = new Dictionary<string, IImporter>();
private readonly RawFileImporter rawFileImporter;
public Builder()
{
rawFileImporter = new RawFileImporter();
ShaderImporter shaderImporter = new ShaderImporter();
importers.Add(".vert", shaderImporter); // Vertex shader
importers.Add(".frag", shaderImporter); // Fragment shader
importers.Add(".tesc", shaderImporter); // Tessellation control shader
importers.Add(".tese", shaderImporter); // Tessellation evaluation shader
importers.Add(".geom", shaderImporter); // Geometry shader
importers.Add(".comp", shaderImporter); // Compute shader
}
public void Run(BuildArgs args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
CopyLibs(args.ProjectPath);
List<string> contentFiles = args.ContentFiles;
string absContentPath = $"{args.ProjectPath}/{PathUtil.ContentFolderName}";
// If no files are provided, build all content.
if (args.ContentFiles == null)
{
contentFiles = [];
CollectAssetFiles(absContentPath, absContentPath, ref contentFiles);
}
string importPath = $"{args.ProjectPath}/{PathUtil.ImportFolderName}";
ParallelOptions parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = contentFiles.Count
};
Parallel.ForEach(contentFiles, parallelOptions, relativeFile =>
{
try
{
string inFile = $"{args.ProjectPath}/{PathUtil.ContentFolderName}/{relativeFile}";
if (!File.Exists(inFile))
{
Console.Error.WriteLine($"Asset file '{relativeFile}' not found");
return;
}
string outFile = $"{importPath}/{relativeFile}{PathUtil.ImportedFileExtension}";
FileInfo inFileInfo = new FileInfo(inFile);
FileInfo outFileInfo = new FileInfo(outFile);
if (!FileUtil.IsNewer(inFileInfo, outFileInfo))
{
// File has not changed since last build, no need to build this one.
return;
}
string outDir = Path.GetDirectoryName(outFile);
if (!Directory.Exists(outDir))
{
Directory.CreateDirectory(outDir);
}
string ext = Path.GetExtension(inFile).ToLower();
if (importers.TryGetValue(ext, out IImporter importer))
{
importer.Import(inFile, outFile);
}
else
{
rawFileImporter.Import(inFile, outFile);
}
Console.WriteLine(relativeFile);
}
catch (Exception e)
{
Console.Error.WriteLine($"Import error on asset '{relativeFile}': {e.Message}");
}
});
Console.WriteLine($"Build content completed in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
}
private void CopyLibs(string projectPath)
{
string libDir = $"{Directory.GetCurrentDirectory()}/../../Native/";
if (OperatingSystem.IsWindows())
{
libDir += "x64";
}
else if (OperatingSystem.IsLinux())
{
libDir += "lib64";
}
else if (OperatingSystem.IsMacOS())
{
libDir += "osx";
}
libDir = Path.GetFullPath(libDir);
foreach (string libFile in Directory.EnumerateFiles(libDir))
{
FileInfo srcFileInfo = new FileInfo(libFile);
FileInfo dstFileInfo = new FileInfo($"{projectPath}/{PathUtil.BuildFolderName}/{Path.GetFileName(libFile)}");
if (FileUtil.IsNewer(srcFileInfo, dstFileInfo))
{
FileUtil.Copy(srcFileInfo, dstFileInfo);
}
}
}
private void CollectAssetFiles(string assetDir, string dir, ref List<string> files)
{
foreach (string file in Directory.EnumerateFiles(dir))
{
if (Path.GetExtension(file).Equals(PathUtil.ImportFileExtension, StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
string relativeFile = file.Substring(assetDir.Length, file.Length - assetDir.Length);
if (relativeFile[0] == Path.DirectorySeparatorChar || relativeFile[0] == Path.AltDirectorySeparatorChar)
{
relativeFile = relativeFile.Substring(1, relativeFile.Length - 1);
}
files.Add(relativeFile);
}
foreach (string subDir in Directory.EnumerateDirectories(dir))
{
CollectAssetFiles(assetDir, subDir, ref files);
}
}
public void Dispose() { }
}

View File

@ -0,0 +1,49 @@
namespace Nerfed.Builder;
public static class FileUtil
{
public static void Copy(FileInfo srcFile, FileInfo dstFile)
{
Copy(srcFile.FullName, dstFile.FullName);
}
public static void Copy(string srcFile, string dstFile)
{
string dstDir = Path.GetDirectoryName(dstFile);
if (!Directory.Exists(dstDir))
{
Directory.CreateDirectory(dstDir);
}
File.Copy(srcFile, dstFile, true);
UpdateFileTimeAttributes(dstFile);
}
public static void WriteBytes(string dstFile, byte[] bytes)
{
File.WriteAllBytes(dstFile, bytes);
UpdateFileTimeAttributes(dstFile);
}
public static void UpdateFileTimeAttributes(string file)
{
// Copy over date time attributes so we can check if the file changed.
FileInfo dstFileInfo = new FileInfo(file);
DateTime now = DateTime.Now;
DateTime utcNow = DateTime.UtcNow;
dstFileInfo.CreationTime = now;
dstFileInfo.CreationTimeUtc = utcNow;
dstFileInfo.LastWriteTime = now;
dstFileInfo.LastWriteTimeUtc = utcNow;
dstFileInfo.LastAccessTime = now;
dstFileInfo.LastAccessTimeUtc = utcNow;
}
/// <summary>
/// True if the inFileInfo is newer than the outFileInfo.
/// </summary>
public static bool IsNewer(FileInfo inFileInfo, FileInfo outFileInfo)
{
return !outFileInfo.Exists || outFileInfo.LastWriteTime <= inFileInfo.LastWriteTime;
}
}

View File

@ -0,0 +1,6 @@
namespace Nerfed.Builder;
public interface IImporter
{
void Import(string inFile, string outFile);
}

View File

@ -0,0 +1,9 @@
namespace Nerfed.Builder;
public class RawFileImporter : IImporter
{
public void Import(string inFile, string outFile)
{
FileUtil.Copy(inFile, outFile);
}
}

View File

@ -0,0 +1,33 @@
using System.Diagnostics;
namespace Nerfed.Builder;
public class ShaderImporter : IImporter
{
public void Import(string inFile, string outFile)
{
using (Process proc = new Process())
{
string glslc;
if (OperatingSystem.IsWindows())
{
glslc = "Win64/glslc.exe";
}
else if (OperatingSystem.IsLinux())
{
glslc = "Linux/glslc";
}
else
{
throw new PlatformNotSupportedException("No shader compiler found for current platform");
}
proc.StartInfo.FileName = glslc;
proc.StartInfo.Arguments = @$"""{inFile}"" -o ""{outFile}"" -c";
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
}
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<IsPackable>false</IsPackable>
<Configurations>Debug;Test;Release</Configurations>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Test|x64' ">
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<Optimize>true</Optimize>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=builder/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=builder_005Cimporters/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=packager/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,6 @@
namespace Nerfed.Builder;
public class PackageArgs
{
}

View File

@ -0,0 +1,12 @@
namespace Nerfed.Builder;
public class Packager : IDisposable
{
public void Run(PackageArgs args)
{
}
public void Dispose()
{
}
}

View File

@ -0,0 +1,10 @@
namespace Nerfed.Builder;
public static class PathUtil
{
public const string ImportedFileExtension = ".bin";
public const string BuildFolderName = ".build";
public const string ImportFileExtension = ".import";
public const string ImportFolderName = $"{BuildFolderName}/Import";
public const string ContentFolderName = "Content";
}

70
Nerfed.Builder/Program.cs Normal file
View File

@ -0,0 +1,70 @@
using System.Diagnostics;
namespace Nerfed.Builder;
internal class Program
{
private static int Main(string[] args)
{
if (Debugger.IsAttached)
{
return Run(args);
}
else
{
try
{
return Run(args);
}
catch (Exception e)
{
Console.Error.WriteLine(e.Message);
return -1;
}
}
}
private static int Run(string[] rawArgs)
{
if (rawArgs.Length == 0)
{
Console.Error.WriteLine($"Invalid build type '{rawArgs[0]}' expected '-build' or '-package'");
return -1;
}
string buildType = rawArgs[0].ToLower();
if (buildType == "-build")
{
ArgsParser<BuildArgs> parser = new ArgsParser<BuildArgs>(rawArgs);
if (!parser.Parse())
{
Console.Error.Write("Failed to parse build arguments");
return -1;
}
using (Builder builder = new Builder())
{
builder.Run(parser.Arguments);
}
}
else if (buildType == "-package")
{
ArgsParser<PackageArgs> parser = new ArgsParser<PackageArgs>(rawArgs);
if (!parser.Parse())
{
Console.Error.Write("Failed to parse package arguments");
return -1;
}
using (Packager packager = new Packager())
{
packager.Run(parser.Arguments);
}
Console.Error.WriteLine("Packaging not yet implemented");
return -1;
}
return 0;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Runtime ID" AfterTargets="Build">
<Message Text="Runtime ID: $(RuntimeIdentifier)" Importance="high"/>
</Target>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))">
<Libs Include="..\Native\x64\**\*.*"/>
</ItemGroup>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))">
<Libs Include="..\Native\lib64\**\*.*"/>
</ItemGroup>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))">
<Libs Include="..\Native\osx\**\*.*"/>
</ItemGroup>
<Target Name="CopyLibs" AfterTargets="Build">
<Copy SourceFiles="@(Libs)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true"/>
</Target>
</Project>

View File

@ -0,0 +1,71 @@
using ImGuiNET;
using Nerfed.Runtime;
using Nerfed.Runtime.Graphics;
using Nerfed.Runtime.Gui;
namespace Nerfed.Editor
{
internal static class EditorGui
{
private static GuiController guiController;
internal static void Initialize()
{
// Create GuiController.
guiController = new GuiController(Engine.GraphicsDevice, Engine.MainWindow, Color.DimGray);
// Subscribe to GUI update.
// GuiController.OnGui call => UpdateDock;
// GuiController.OnGui call => UpdateEditorWindows;
// GuiController.OnGui call => ...;
guiController.OnGui += HandleOnGui;
}
internal static void Update()
{
// Update GuiController.
guiController.Update(Engine.Timestep.TotalSeconds);
}
internal static void Render()
{
// Reneder GuiController.
guiController.Render();
}
internal static void Quit()
{
guiController.Dispose();
}
private static void UpdateDock()
{
// Setup default dockspace for the main window.
uint id = ImGui.GetID("MainDockSpace");
ImGui.DockSpaceOverViewport(id, ImGui.GetMainViewport(), ImGuiDockNodeFlags.None);
}
private static void UpdateMainMenu()
{
if (ImGui.BeginMainMenuBar())
{
if (ImGui.BeginMenu("File"))
{
if (ImGui.MenuItem("Exit"))
{
Engine.Quit();
}
ImGui.EndMenu();
}
ImGui.EndMainMenuBar();
}
}
private static void HandleOnGui()
{
UpdateMainMenu();
UpdateDock();
ImGui.ShowDemoWindow();
}
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<IsPackable>false</IsPackable>
<Configurations>Debug;Test;Release</Configurations>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Test|x64' ">
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Nerfed.Runtime\Nerfed.Runtime.csproj" />
</ItemGroup>
<Import Project=".\CopyLibs.targets" />
</Project>

42
Nerfed.Editor/Program.cs Normal file
View File

@ -0,0 +1,42 @@
using Nerfed.Runtime;
namespace Nerfed.Editor;
internal class Program
{
private static void Main(string[] args)
{
Engine.OnInitialize += HandleOnInitialize;
Engine.OnUpdate += HandleOnUpdate;
Engine.OnRender += HandleOnRender;
Engine.OnQuit += HandleOnQuit;
Engine.Run(args);
}
private static void HandleOnInitialize()
{
// Open project.
// Setip EditorGui.
EditorGui.Initialize();
}
private static void HandleOnUpdate()
{
// Editor Update.
EditorGui.Update();
// Try Catch UserCode Update.
}
private static void HandleOnRender()
{
EditorGui.Render();
}
private static void HandleOnQuit()
{
EditorGui.Quit();
}
}

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Runtime ID" AfterTargets="Build">
<Message Text="Runtime ID: $(RuntimeIdentifier)" Importance="high"/>
</Target>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))">
<Content Include="..\libs\x64\**\*.*" >
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))">
<Content Include="..\libs\lib64\**\*.*" >
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))">
<Content Include="..\libs\osx\**\*.*" >
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -7,6 +7,11 @@ namespace Nerfed.Runtime;
public static class Engine public static class Engine
{ {
public static event Action OnInitialize;
public static event Action OnUpdate;
public static event Action OnRender;
public static event Action OnQuit;
public static TimeSpan MaxDeltaTime { get; set; } = TimeSpan.FromMilliseconds(100); public static TimeSpan MaxDeltaTime { get; set; } = TimeSpan.FromMilliseconds(100);
public static bool VSync { get; set; } public static bool VSync { get; set; }
@ -19,6 +24,7 @@ public static class Engine
private static Stopwatch gameTimer; private static Stopwatch gameTimer;
private static long previousTicks = 0; private static long previousTicks = 0;
private static TimeSpan accumulatedUpdateTime = TimeSpan.Zero; private static TimeSpan accumulatedUpdateTime = TimeSpan.Zero;
private static TimeSpan accumulatedDrawTime = TimeSpan.Zero; private static TimeSpan accumulatedDrawTime = TimeSpan.Zero;
// must be a power of 2 so we can do a bitmask optimization when checking worst case // must be a power of 2 so we can do a bitmask optimization when checking worst case
@ -38,9 +44,7 @@ public static class Engine
private const string WindowTitle = "Nerfed"; private const string WindowTitle = "Nerfed";
//.. //..
private static Gui.GuiController Controller; public static void Run(string[] args)
internal static void Run(string[] args)
{ {
Timestep = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetTimestep); Timestep = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetTimestep);
gameTimer = Stopwatch.StartNew(); gameTimer = Stopwatch.StartNew();
@ -55,7 +59,7 @@ internal static void Run(string[] args)
{ {
throw new Exception("Failed to init SDL"); throw new Exception("Failed to init SDL");
} }
GraphicsDevice = new GraphicsDevice(BackendFlags.All); GraphicsDevice = new GraphicsDevice(BackendFlags.All);
MainWindow = new Window(GraphicsDevice, new WindowCreateInfo(WindowTitle, WindowWidth, WindowHeight, ScreenMode.Windowed)); MainWindow = new Window(GraphicsDevice, new WindowCreateInfo(WindowTitle, WindowWidth, WindowHeight, ScreenMode.Windowed));
@ -64,23 +68,17 @@ internal static void Run(string[] args)
throw new Exception("Failed to claim window"); throw new Exception("Failed to claim window");
} }
MainWindow.OnCloseEvent += (w) => {
Quit();
};
AudioDevice = new AudioDevice(); AudioDevice = new AudioDevice();
Controller = new Gui.GuiController(GraphicsDevice, MainWindow, Color.DarkOliveGreen); OnInitialize?.Invoke();
Controller.OnGui += () => {
ImGuiNET.ImGui.ShowDemoWindow();
};
while (!quit) while (!quit)
{ {
Tick(); Tick();
} }
Controller.Dispose(); OnQuit?.Invoke();
GraphicsDevice.UnclaimWindow(MainWindow); GraphicsDevice.UnclaimWindow(MainWindow);
MainWindow.Dispose(); MainWindow.Dispose();
GraphicsDevice.Dispose(); GraphicsDevice.Dispose();
@ -157,7 +155,7 @@ private static void Tick()
ProcessSDLEvents(); ProcessSDLEvents();
// Tick game here... // Tick game here...
Controller.Update((float)Timestep.TotalSeconds); OnUpdate?.Invoke();
AudioDevice.WakeThread(); AudioDevice.WakeThread();
accumulatedUpdateTime -= Timestep; accumulatedUpdateTime -= Timestep;
@ -166,7 +164,7 @@ private static void Tick()
double alpha = accumulatedUpdateTime / Timestep; double alpha = accumulatedUpdateTime / Timestep;
// Render here.. // Render here..
Controller.Render(); OnRender?.Invoke();
accumulatedDrawTime -= framerateCapTimeSpan; accumulatedDrawTime -= framerateCapTimeSpan;
} }

View File

@ -9,7 +9,7 @@
namespace Nerfed.Runtime.Gui; namespace Nerfed.Runtime.Gui;
internal class GuiController : IDisposable public class GuiController : IDisposable
{ {
public event Action OnGui; public event Action OnGui;
@ -144,9 +144,13 @@ public GuiController(GraphicsDevice graphicsDevice, Window mainWindow, Color cle
io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos;
io.BackendFlags |= ImGuiBackendFlags.PlatformHasViewports; io.BackendFlags |= ImGuiBackendFlags.PlatformHasViewports;
io.BackendFlags |= ImGuiBackendFlags.RendererHasViewports; io.BackendFlags |= ImGuiBackendFlags.RendererHasViewports;
UpdatePerFrameImGuiData(1.0 / 60.0);
ImGui.NewFrame();
frameBegun = true;
} }
public void Update(float deltaTime) public void Update(double deltaTime)
{ {
if (frameBegun) if (frameBegun)
{ {
@ -167,12 +171,12 @@ public void Update(float deltaTime)
ImGui.EndFrame(); ImGui.EndFrame();
} }
private void UpdatePerFrameImGuiData(float deltaSeconds) private void UpdatePerFrameImGuiData(double deltaSeconds)
{ {
ImGuiIOPtr io = ImGui.GetIO(); ImGuiIOPtr io = ImGui.GetIO();
io.DisplaySize = new Vector2(mainWindow.Width, mainWindow.Height); io.DisplaySize = new Vector2(mainWindow.Width, mainWindow.Height);
io.DisplayFramebufferScale = new Vector2(1, 1); io.DisplayFramebufferScale = new Vector2(1, 1);
io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. io.DeltaTime = (float)deltaSeconds; // DeltaTime is in seconds.
} }
private void UpdateInput() private void UpdateInput()

View File

@ -1,33 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);Libraries\**\*</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<Compile Include="Libraries\SDL2CS\src\SDL2.cs" />
<Compile Include="Libraries\RefreshCS\RefreshCS.cs" />
<Compile Include="Libraries\FAudio\csharp\FAudio.cs" />
<Compile Include="Libraries\WellspringCS\WellspringCS.cs" />
<Compile Include="Libraries\dav1dfile\csharp\dav1dfile.cs" />
<Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\**\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
<PublishAot>true</PublishAot> <PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization> <InvariantGlobalization>true</InvariantGlobalization>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<IsPackable>false</IsPackable>
<Configurations>Debug;Test;Release</Configurations>
<Platforms>x64</Platforms>
</PropertyGroup> </PropertyGroup>
<Import Project=".\CopyLibs.targets" /> <PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);Libraries\**\*</DefaultItemExcludes>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DefineConstants>TRACE;LOG_INFO;PROFILING</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Test|x64' ">
<DefineConstants>TRACE;LOG_ERROR;PROFILING</DefineConstants>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<DefineConstants>TRACE;LOG_ERROR</DefineConstants>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="Libraries\SDL2CS\src\SDL2.cs"/>
<Compile Include="Libraries\RefreshCS\RefreshCS.cs"/>
<Compile Include="Libraries\FAudio\csharp\FAudio.cs"/>
<Compile Include="Libraries\WellspringCS\WellspringCS.cs"/>
<Compile Include="Libraries\dav1dfile\csharp\dav1dfile.cs"/>
<Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs"/>
</ItemGroup>
</Project> </Project>

View File

@ -17,12 +17,12 @@ public void Dispose() {
public static class Profiler public static class Profiler
{ {
[Conditional("PROFILER")] [Conditional("PROFILING")]
public static void BeginSample(string label) { public static void BeginSample(string label) {
} }
[Conditional("PROFILER")] [Conditional("PROFILING")]
public static void EndSample() { public static void EndSample() {
} }

View File

@ -1,9 +0,0 @@
namespace Nerfed.Runtime;
internal class Program
{
private static void Main(string[] args)
{
Engine.Run(args);
}
}

View File

@ -5,16 +5,35 @@ VisualStudioVersion = 17.10.35013.160
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Runtime", "Nerfed.Runtime\Nerfed.Runtime.csproj", "{98E09BAF-587F-4238-89BD-7693C036C233}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Runtime", "Nerfed.Runtime\Nerfed.Runtime.csproj", "{98E09BAF-587F-4238-89BD-7693C036C233}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Builder", "Nerfed.Builder\Nerfed.Builder.csproj", "{1B88DE56-2AD8-441E-9B10-073AA43840BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Editor", "Nerfed.Editor\Nerfed.Editor.csproj", "{FF7D032D-7F0B-4700-A818-0606D66AECF8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Test|x64 = Test|x64
Release|Any CPU = Release|Any CPU Release|x64 = Release|x64
Debug|x64 = Debug|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.ActiveCfg = Test|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.Build.0 = Test|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.ActiveCfg = Release|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Release|Any CPU.Build.0 = Release|Any CPU {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.Build.0 = Release|x64
{1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.ActiveCfg = Debug|x64
{1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.Build.0 = Debug|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.ActiveCfg = Test|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.Build.0 = Test|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.ActiveCfg = Release|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.Build.0 = Release|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.ActiveCfg = Debug|x64
{FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.Build.0 = Debug|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.ActiveCfg = Test|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.Build.0 = Test|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.ActiveCfg = Release|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.Build.0 = Release|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|x64.ActiveCfg = Debug|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|x64.Build.0 = Debug|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

Binary file not shown.

View File

@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"Nerfed.Builder/1.0.0": {
"runtime": {
"Nerfed.Builder.dll": {}
}
}
}
},
"libraries": {
"Nerfed.Builder/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

BIN
Tools/Nerfed.Builder/Nerfed.Builder.dll (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,13 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

BIN
Tools/glslc/Linux/glslc Executable file

Binary file not shown.

BIN
Tools/glslc/Win64/glslc.exe (Stored with Git LFS) Executable file

Binary file not shown.