This commit is contained in:
Rune
2026-03-05 20:10:53 +01:00
commit cca2d94747
89 changed files with 58347 additions and 0 deletions

5
Setup/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
build
recovery
BeefSpace_User.toml
BeefSpace_Lock.toml
SDL3_all.h

66
Setup/BeefProj.toml Normal file
View File

@@ -0,0 +1,66 @@
FileVersion = 1
Dependencies = {corlib = "*", "Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Cpp2Beef.git"}}
[Project]
Name = "SDL3.Setup"
StartupObject = "SDL3.Setup.Program"
[Configs.Debug.Win32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Debug.Win64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/CxxBuilderPath.txt $(WorkspaceDir)/../CxxBuilderPath.txt"]
[Configs.Debug.Linux32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Debug.Linux64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Debug.macOS]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Release.Win32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Release.Win64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Release.Linux32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Release.Linux64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Release.macOS]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Paranoid.Win32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Paranoid.Win64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Paranoid.Linux32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Paranoid.Linux64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Paranoid.macOS]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Test.Win32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Test.Win64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Test.Linux32]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Test.Linux64]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]
[Configs.Test.macOS]
PostBuildCmds = ["cp $(ProjectDir Cpp2Beef)/CxxBuilder/dist/SetCxxBuilderExe.beefscript $(WorkspaceDir)/../SetCxxBuilderExe.beefscript"]

6
Setup/BeefSpace.toml Normal file
View File

@@ -0,0 +1,6 @@
FileVersion = 1
Projects = {"SDL3.Setup" = {Path = "."}, "Clang-C.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Clang-C.git"}, "Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/BeefBindings/Cpp2Beef.git"}}
ExtraPlatforms = ["Linux32", "Linux64", "macOS"]
[Workspace]
StartupProject = "SDL3.Setup"

353
Setup/src/Program.bf Normal file
View File

@@ -0,0 +1,353 @@
using System;
using System.IO;
using System.Collections;
using System.Diagnostics;
using Cpp2Beef;
using LibClang;
namespace SDL3.Setup;
class SDL3Generator : Cpp2BeefGenerator, this(Span<char8*> args)
{
protected override Span<char8*> Args => args;
protected override Flags Flags => .None;
private BumpAllocator alloc = new .() ~ delete _;
append Dictionary<String, StreamWriter> writers = .(16);
protected override StreamWriter GetWriterForHeader(StringView header)
{
String filename = Path.GetFileNameWithoutExtension(header, ..scope .(64));
if (!filename.StartsWith("SDL_") || filename == "SDL_begin_code") return null;
if (writers.TryAdd(filename, let keyPtr, let valuePtr))
{
*keyPtr = new:alloc .(filename);
*valuePtr = new:alloc .()..Create(scope $"../src/{filename}.bf")..Write("""
// This file was generated by Cpp2Beef
using System;
using System.Interop;
using static SDL3.SDL;
namespace SDL3;
""");
}
return *valuePtr;
}
protected override Block GetCursorBlock(CXCursor cursor)
{
if (Path.GetFileName(GetFilePath!(fileInfo.file), ..scope .(128)).StartsWith("SDL_test"))
return .CustomBlock("SDLTest");
return .CustomBlock("SDL");
}
protected override void HandleCursor(CXCursor cursor)
{
switch (cursor.kind)
{
case .MacroDefinition:
if (Clang.Cursor_IsMacroFunctionLike(cursor) != 0 && GetFilePath!(fileInfo.file).EndsWith("SDL_version.h"))
{
BeginCursor(cursor);
let tokens = ScopeTokenize!(cursor, unit);
WriteCustomAttributes(cursor);
str.Append("public static ");
if (GetCursorSpelling!(cursor) == "SDL_VERSION_ATLEAST")
str.Append("bool ");
else
str.Append("c_int ");
GetNameInBindings(cursor, str);
bool inArgs = true;
for (let token in tokens[1...])
{
if (inArgs)
{
let spelling = GetTokenSpelling!(token);
if (spelling == ")")
{
inArgs = false;
str.Append(") => ");
continue;
}
if (Clang.GetTokenKind(token) == .Identifier)
str.Append("c_int ");
str.Append(spelling);
if (spelling == ",")
str.Append(' ');
}
else
WriteToken(token);
}
str.Append(';');
return;
}
let spelling = GetCursorSpelling!(cursor);
if (spelling.StartsWith("SDL_PRI") || spelling.StartsWith("VK_DEFINE_"))
return;
switch (spelling)
{
case "FONT_LINE_HEIGHT":
BeginCursor(cursor);
str.Append("public static c_int FONT_LINE_HEIGHT => (FONT_CHARACTER_SIZE + 2);");
return;
case "PFN_xrGetInstanceProcAddr":
BeginCursor(cursor);
str.Append("public typealias PFN_xrGetInstanceProcAddr = SDL.FunctionPointer;");
return;
case "main", "SDL_SIZE_MAX", "SDL_FUNCTION", "SDL_FILE", "SDL_ASSERT_FILE", "SDL_LINE", "SDL_SCOPED_CAPABILITY", "SDL_NO_THREAD_SAFETY_ANALYSIS":
return;
}
case .TypedefDecl:
String prefix = scope .(64);
var spelling = GetCursorSpelling!(cursor);
if (spelling == "SDL_Keycode")
prefix.Set("SDLK_");
else
{
if (!spelling.StartsWith("SDL_")) fallthrough;
spelling.RemoveFromStart(4);
/*if (GetTypeSpelling!(Clang.GetTypedefDeclUnderlyingType(cursor)) != "Uint32")
fallthrough;*/
if (spelling == "TrayEntryFlags")
spelling = "Trayentry";
else if (spelling == "MouseButtonFlags")
spelling = "Button";
else if (spelling.EndsWith("Flags"))
spelling.RemoveFromEnd(5);
else if (spelling.EndsWith("Flag"))
spelling.RemoveFromEnd(4);
/*else if (spelling.EndsWith("ID"))
spelling.RemoveFromEnd(2);*/
else if (spelling == "BlendMode")
spelling = "Blendmode";
else if (spelling == "GLContextResetNotification")
spelling = "GlContextReset";
else if (spelling == "GLProfile")
spelling = "GlContextProfile";
else if (spelling == "Keycode")
spelling = "K";
else if (spelling != "GPUShaderFormat")
fallthrough;
if (spelling.StartsWith("GL"))
{
spelling = scope:: String(spelling);
spelling[1] = 'l';
}
prefix.Append("SDL");
if (spelling.StartsWith("GPU"))
{
prefix.Append("_GPU_");
for (let c in spelling[3...])
prefix.Append(c.ToUpper);
prefix.Append('_');
}
else
{
for (let c in spelling)
{
if (c.IsUpper) prefix.Append('_');
prefix.Append(c.ToUpper);
}
prefix.Append('_');
}
}
BeginCursor(cursor);
if (spelling == "Button") str.Append("[AllowDuplicates] ");
AccessSpecifier(cursor);
str.Append("enum ");
GetNameInBindings(cursor, str);
str.Append(" : ");
Type(Clang.GetTypedefDeclUnderlyingType(cursor));
void FixCurly()
{
if (fileInfo.queuedTokens.HasFlag(.LSquirly))
str.Append("\n{");
if (fileInfo.queuedTokens.HasFlag(.RSquirly))
str.Append("\n}");
else
str.Append("\n\t");
fileInfo.queuedTokens = .None;
}
bool isSDL_GLContextFlag = spelling == "GlContext";
{
BeginBody!(cursor);
for (let macro in this.[Friend]unitMacros)
{
let macroCursor = macro.value;
if (Clang.Cursor_IsMacroFunctionLike(macroCursor) != 0)
continue;
if (Clang.GetFileLocation(Clang.GetCursorLocation(macroCursor), ..?, ?, ?, ?) != fileInfo.file)
continue;
var macroSpelling = GetCursorSpelling!(macroCursor);
if (!macroSpelling.StartsWith(prefix))
continue;
if (isSDL_GLContextFlag)
{
if (!macroSpelling.EndsWith("_FLAG"))
continue;
macroSpelling.RemoveFromEnd(5);
}
macroSpelling.RemoveFromStart(prefix.Length);
BeginCursor(macroCursor);
FixCurly();
if (macroSpelling[0].IsDigit) str.Append('_');
UpperSnakeCase2PascalCase(macroSpelling, str);
let tokens = ScopeTokenize!(macroCursor, unit);
AllWhiteSpaceBetween(Clang.GetRangeEnd(Clang.GetTokenExtent(unit, tokens[0])), Clang.GetRangeStart(Clang.GetTokenExtent(unit, tokens[1])));
str.Append("= ");
WriteTokens(tokens[1...], Clang.GetNullLocation(), .Punctuation);
str.Append(',');
@macro.Remove();
WriteComments(Clang.GetCursorLocation(macroCursor));
}
}
FixCurly();
return;
default:
}
base.HandleCursor(cursor);
}
protected override void GetNameInBindings(CXCursor cursor, String outString)
{
bool RemovePrefix(ref StringView view)
{
if (view.StartsWith("SDLTest_")) view.RemoveFromStart(8);
else if (view.StartsWith("SDL_")) view.RemoveFromStart(4);
else return false;
return true;
}
var spelling = GetCursorSpelling!(cursor);
if (!RemovePrefix(ref spelling))
{
if (cursor.kind == .MacroDefinition)
switch (spelling)
{
case "NULL": outString.Append("null"); return;
case "TRUE": outString.Append("true"); return;
case "FALSE": outString.Append("false"); return;
}
base.GetNameInBindings(cursor, outString);
return;
}
switch (cursor.kind)
{
case .EnumConstantDecl:
var parentSpelling = GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor));
if (parentSpelling == "SDL_GPUTextureFormat")
{
spelling.RemoveFromStart("GPU_TEXTUREFORMAT_".Length);
outString.Append(spelling);
break;
}
StringView name = UpperSnakeCase2PascalCase(spelling, ..scope .(spelling.Length));
switch (parentSpelling)
{
case "SDL_AudioFormat": parentSpelling = "Audio";
case "SDL_AssertState": parentSpelling = "Assertion";
case "SDL_GamepadBindingType": parentSpelling = "GamepadBindtype";
case "SDL_RendererLogicalPresentation": parentSpelling = "LogicalPresentation";
default:
RemovePrefix(ref parentSpelling);
}
for (let c in parentSpelling)
{
if (name[0].ToLower == c.ToLower)
name.RemoveFromStart(1);
else
break;
}
if (name[0].IsDigit)
outString.Append('_');
outString.Append(name);
default:
outString.Append(spelling);
}
}
protected override void WriteToken(CXToken token)
{
var spelling = GetTokenSpelling!(token);
switch (spelling)
{
case "size_t": str.Append("c_size"); return;
case "SDL_BUTTON_LEFT": str.Append("Left"); return;
case "SDL_BUTTON_MIDDLE": str.Append("Middle"); return;
case "SDL_BUTTON_RIGHT": str.Append("Right"); return;
case "SDL_BUTTON_X1": str.Append("X1"); return;
case "SDL_BUTTON_X2": str.Append("X2"); return;
}
if (!spelling.StartsWith("SDL_") || !spelling.EndsWith("ID"))
{
base.WriteToken(token);
return;
}
spelling.RemoveFromStart(4);
str.Append("SDL.");
str.Append(spelling);
}
protected override bool IsOutParam(CXCursor arg, CXCursor method)
{
let comment = Clang.Cursor_GetParsedComment(method);
let spelling = GetCursorSpelling!(arg);
for (let i < Clang.Comment_GetNumChildren(comment))
{
let param = Clang.Comment_GetChild(comment, i);
if (Clang.Comment_GetKind(param) != .ParamCommand ||
ScopeCXString!(Clang.ParamCommandComment_GetParamName(param)) != spelling) continue;
let paragraph = Clang.BlockCommandComment_GetParagraph(param);
if (Clang.Comment_GetNumChildren(paragraph) == 0) continue;
let paragraphChild = Clang.Comment_GetChild(paragraph, 0);
if (Clang.Comment_GetKind(paragraphChild) != .Text) continue;
StringView paragraphText = ScopeCXString!(Clang.TextComment_GetText(paragraphChild))..TrimStart();
if (paragraphText.StartsWith("a pointer filled in") || paragraphText.StartsWith("a pointer to receive")) return true;
else break;
}
return base.IsOutParam(arg, method);
}
}
class Program
{
[CLink] static extern int32 system(char8*);
public static int Main(String[] args)
{
//Runtime.Assert(system("git -C .. submodule update") == 0, "Failed to fetch SDL3, check your internet connection");
{
StreamWriter all = scope .()..Create("SDL3_all.h");
for (let file in Directory.EnumerateFiles("../SDL/include/SDL3"))
{
let filename = file.GetFileName(..scope .(64));
if (filename == "SDL_oldnames.h" || filename == "SDL_egl.h" || filename == "SDL_intrin.h" || filename == "SDL_endian.h" ||
filename == "SDL_platform_defines.h" || filename == "SDL_begin_code.h" || filename == "SDL_close_code.h" || filename.StartsWith("SDL_opengl"))
continue;
all.Write("#include <SDL3/");
all.Write(filename);
all.Write(">\n");
}
}
SDL3Generator generator = scope .(char8*[?]("--language=c", "-I../SDL/include",
"-DSDL_oldnames_h_", "-DSDL_platform_defines_h_", "-DSDL_endian_h_",
"-DCrcUint32=Uint32", "-DCrcUint8=Uint8",
"-DSDL_SLOW_MEMCPY", "-DSDL_SLOW_MEMMOVE", "-DSDL_SLOW_MEMSET", "-DSDL_DISABLE_ALLOCA", "-DSDL_DISABLE_ANALYZE_MACROS"));
generator.Generate("SDL3_all.h", null);
return 0;
}
}