Commits

Jason McKesson committed 7f8c521

GL Load primary dev finished. Need to debug.

  • Participants
  • Parent commits e239ec9

Comments (0)

Files changed (5)

File modules/CommonStyle.lua

 	return "IntGetProcAddress"
 end
 
+function common.FixupIndexedList(specData, indexed)
+	assert(indexed)
+	for _, func in ipairs(specData.funcData.functions) do
+		if(indexed[1] == func.name) then
+			indexed[1] = func
+		end
+		if(indexed[3] == func.name) then
+			indexed[3] = func
+		end
+	end
+	for _, enum in ipairs(specData.enumerations) do
+		if(indexed[2] == enum.name) then
+			indexed[2] = enum
+		end
+		if(indexed[4] == enum.name) then
+			indexed[4] = enum
+		end
+	end
+end
+
+function common.GetProcExtsFromExtListFunc(hFile, specData, spec, options,
+							indexed, GetFuncPtrName, GetEnumName)
+	return [[
+static void ProcExtsFromExtList()
+{
+	GLint iLoop;
+	GLint iNumExtensions = 0;
+	]] .. GetFuncPtrName(indexed[1], spec, options)
+	.. [[(]] .. GetEnumName(indexed[2], spec, options)
+	.. [[, &iNumExtensions);
+
+	for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
+	{
+		const char *strExtensionName = (const char *)]] ..
+		GetFuncPtrName(indexed[3], spec, options) ..
+		[[(]] .. GetEnumName(indexed[4], spec, options) .. [[, iLoop);
+		LoadExtByName(strExtensionName);
+	}
+}
+]]
+end
 
 --You give it a function that takes a const char*.
 function common.GetProcessExtsFromStringFunc(funcFormat, arguments)
 	return ret
 end
 
+function common.WriteCMappingTable(hFile, specData, spec,
+							options, structName, varName, GetExtVariableName, GetExtLoaderFuncName)
+	--Write the struct for the mapping table.
+	hFile:write("typedef int (*PFN_LOADFUNCPOINTERS)();\n")
+	hFile:fmt("typedef struct %s%sStrToExtMap_s\n",
+		options.prefix, spec.DeclPrefix())
+	hFile:write("{\n")
+	hFile:inc()
+	hFile:write("char *extensionName;\n")
+	hFile:write("int *extensionVariable;\n")
+	hFile:write("PFN_LOADFUNCPOINTERS LoadExtension;\n")
+	hFile:dec()
+	hFile:fmt("} %s;\n", structName)
+	hFile:write "\n"
+	
+	--Write the mapping table itself.
+	hFile:fmt("static %s %s[] = {\n",
+		structName,
+		varName)
+	hFile:inc()
+	for _, extName in ipairs(options.extensions) do
+		if(#specData.extdefs[extName].funcs > 0) then
+			hFile:fmt('{"%s", &%s, %s},\n',
+				spec.ExtNamePrefix() .. extName,
+				GetExtVariableName(extName, spec, options),
+				GetExtLoaderFuncName(extName, spec, options))
+		else
+			hFile:fmt('{"%s", &%s, NULL},\n',
+				spec.ExtNamePrefix() .. extName,
+				GetExtVariableName(extName, spec, options))
+		end
+	end
+	hFile:dec()
+	hFile:write("};\n")
+
+	hFile:write "\n"
+	hFile:fmt("static int g_extensionMapSize = %i;\n", #options.extensions);
+end
+
+function common.WriteCFindExtEntryFunc(hFile, specData, spec,
+							options, structName, varName, sizeName)
+	hFile:fmt("static %s *FindExtEntry(const char *extensionName)\n",
+		structName)
+	hFile:write("{\n")
+	hFile:inc()
+	hFile:write("int loop;\n")
+	hFile:fmt("%s *currLoc = %s;\n",
+		structName,
+		varName)
+	hFile:writeblock([[
+for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
+{
+	if(strcmp(extensionName, currLoc->extensionName) == 0)
+		return currLoc;
+}
+
+return NULL;
+]])
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function common.WriteCClearExtensionVarsFunc(hFile, specData, spec,
+							options, GetExtVariableName, clearValue)
+	hFile:fmt("static void ClearExtensionVars()\n")
+	hFile:write("{\n")
+	hFile:inc()
+	for _, extName in ipairs(options.extensions) do
+		hFile:fmt('%s = %s;\n',
+			GetExtVariableName(extName, spec, options),
+			clearValue)
+	end
+	hFile:dec()
+	hFile:write("}\n")
+	hFile:write "\n"
+end
+
+--Write a function that loads an extension by name. It is called when
+--processing, so it should also set the extension variable based on the load.
+function common.WriteCLoadExtByNameFunc(hFile, specData, spec,
+							options, structName, successValue)
+	hFile:writeblock([[
+static void LoadExtByName(const char *extensionName)
+{
+	]] .. structName .. [[ *entry = NULL;
+	entry = FindExtEntry(extensionName);
+	if(entry)
+	{
+		if(entry->LoadExtension)
+		{
+			int numFailed = entry->LoadExtension();
+			if(numFailed == 0)
+			{
+				*(entry->extensionVariable) = ]] ..
+				successValue ..
+				[[;
+			}
+			else
+			{
+				*(entry->extensionVariable) = ]] ..
+				successValue ..
+				[[ + numFailed;
+			}
+		}
+		else
+		{
+			*(entry->extensionVariable) = ]] ..
+			successValue ..
+			[[;
+		}
+	}
+}
+]])
+end
+
 common.DeepCopyTable = DeepCopyTable
 
 local my_struct =

File modules/StructGLLoad.lua

 				{ type="filter", name="VersionHasCoreFuncs(sub_version, specData, spec, options)",
 					{ type="write", name="CallCoreLoad(hFile, sub_version, spec, options)" },
 				},
-				{ type="filter", name="HasCompatibility(version, specData, spec, options)", neg=true,
+				{ type="filter", name="VersionHasCompProfile(version)", neg=true,
 					{ type="filter", name="VersionHasCompFuncs(sub_version, specData, spec, options)",
 						{ type="write", name="CallCoreCompLoad(hFile, sub_version, spec, options)" },
 					},
 			},
 		},
 		{ type="blank" },
-		{ type="filter", name="HasCompatibility(version, specData, spec, options)",
+		{ type="filter", name="VersionHasCompProfile(version)",
 			{ type="block", name="LoadAllCoreCompFunc(hFile, version, spec, options)",
 				{ type="sub-version-iter",
 					{ type="filter", name="VersionHasCoreFuncs(sub_version, specData, spec, options)",
 			{ type="blank" },
 		},
 	},
-	
 
+	--Write the main loading function.
+	{ type="write", name="MainLoadPrelim(hFile, specData, spec, options)", },
+	{ type="blank", },
+	{ type="write", name="MainLoader(hFile, specData, spec, options)", },
+	{ type="blank", },
+	{ type="write", name="MainExtraFuncs(hFile, specData, spec, options)", cond="version-iter" },
 }
 
 local decl_header_struct =
 
 	--Compatibility headers.
 	{ type="version-iter",
-		{ type="filter", name="HasCompatibility(version, specData, spec, options)",
+		{ type="filter", name="VersionHasCompProfile(version)",
 			{ type="file", style="incl_hdr", name="VersionFilenameComp(basename, version, spec, options)",
 				{ type="block", name="IncludeGuardComp(hFile, version, spec, options)",
 					{ type="blank" },

File modules/StyleGLLoadC.lua

 end
 
 
+
+function source.WriteMainLoadPrelim(hFile, specData, spec, options)
+	--Write the extension function mapping table.
+	common.WriteCMappingTable(hFile, specData, spec, options,
+		glload.GetMapTableStructName(spec, options),
+		"ExtensionTable",
+		glload.GetExtVariableName,
+		glload.GetLoadExtensionFuncName)
+	hFile:write "\n"
+	
+	--Write the function to find entries.
+	common.WriteCFindExtEntryFunc(hFile, specData, spec,
+							options, glload.GetMapTableStructName(spec, options),
+							"ExtensionTable")
+	hFile:write "\n"
+
+	--Write the function to clear the extension variables.
+	common.WriteCClearExtensionVarsFunc(hFile, specData, spec, options,
+		glload.GetExtVariableName,
+		"0")
+	hFile:write "\n"
+
+	--Write a function that loads an extension by name.
+	common.WriteCLoadExtByNameFunc(hFile, specData, spec, options,
+		glload.GetMapTableStructName(spec, options),
+		spec.DeclPrefix() .. "LOAD_SUCCEEDED")
+		
+	if(options.version) then
+		hFile:write "\n"
+		
+		--Write a table that maps from version X.Y profile Z to a loading function.
+		hFile:fmtblock([[
+typedef struct %s%sVersProfToLoaderMap_s
+{
+	int majorVersion;
+	int minorVersion;
+	int compatibilityProfile;
+	PFN_LOADFUNCPOINTERS LoadVersion;
+} %s;
+]], options.prefix, spec.DeclPrefix(), "VersionMapEntry")
+		hFile:write "\n"
+		
+		hFile:write("static VersionMapEntry g_versionMapTable[] =\n")
+		hFile:write("{\n")
+		hFile:inc()
+		local numEntries = 0
+		for _, version in ipairs(spec.GetCoreVersions()) do
+			local major, minor = version:match("(%d+)%.(%d+)")
+			hFile:fmt("{%s, %s, 0, %s},\n",
+				major, minor,
+				glload.GetLoadAllCoreFuncName(version, spec, options))
+			numEntries = numEntries + 1
+			if(my_style.FilterVersionHasCompProfile(version)) then
+				hFile:fmt("{%s, %s, 1, %s},\n",
+					major, minor,
+					glload.GetLoadAllCoreCompFuncName(version, spec, options))
+				numEntries = numEntries + 1
+			end
+		end
+		hFile:dec()
+		hFile:write("};\n")
+		hFile:write "\n"
+		hFile:fmt("static int g_numVersionMapEntries = %i;\n", numEntries)
+		hFile:write "\n"
+		
+		--Write a function to find a map entry and call the loader, returning
+		--the value.
+		hFile:writeblock([[
+static int LoadVersionFromMap(int major, int minor, int compatibilityProfile)
+{
+	int loop = 0;
+	for(; loop < g_numVersionMapEntries; ++loop)
+	{
+		if(
+			(g_versionMapTable[loop].major == major) &&
+			(g_versionMapTable[loop].minor == minor) &&
+			(g_versionMapTable[loop].compatibilityProfile == compatibilityProfile))
+		{
+			return g_versionMapTable[loop].LoadVersion()
+		}
+	}
+	
+	return 0;
+}
+]])
+		hFile:write "\n"
+		
+		--Write a function to get the current version from a string.
+		hFile:writeblock(common.GetParseVersionFromString())
+		hFile:write "\n"
+		
+		--Write function to load extensions from alist functions.
+		local indexed = spec.GetIndexedExtStringFunc(options);
+		common.FixupIndexedList(specData, indexed)
+		hFile:writeblock(common.GetProcExtsFromExtListFunc(
+			hFile, specData, spec, options,
+			indexed, glload.GetFuncPtrName, glload.GetEnumeratorName))
+		
+	end
+	hFile:write "\n"
+	hFile:writeblock(common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
+end
+
+local function FindFuncByName(specData, name)
+	for _, func in ipairs(specData.funcData.functions) do
+		if(name == func.name) then
+			return func
+		end
+	end
+end
+
+function source.WriteMainLoader(hFile, specData, spec, options)
+	if(options.version) then
+		hFile:writeblock[[
+static int g_majorVersion = 0;
+static int g_minorVersion = 0;
+]]
+		hFile:write "\n"
+	end
+
+	hFile:fmt("int %sLoadFunctions(%s)\n", spec.DeclPrefix(), spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	
+	if(options.version) then
+		hFile:writeblock[[
+int numFailed = 0;
+int compProfile = 0;
+
+g_majorVersion = 0;
+g_minorVersion = 0;
+]]
+		hFile:write "\n"
+	end
+	
+	hFile:write("ClearExtensionVars();\n")
+	hFile:write "\n"
+	
+	--Load the extensions. Needs to be done differently based on the removal
+	--of glGetString(GL_EXTENSIONS).
+	if(options.version) then
+		--Get the current version.
+		--To do that, we need certain functions.
+		local strFunc = FindFuncByName(specData, "GetString")
+		
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, strFunc, spec, options))
+		strFunc = glload.GetFuncPtrName(strFunc, spec, options)
+		
+		hFile:write "\n"
+		hFile:fmt("ParseVersionFromString(&g_majorVersion, &g_minorVersion, (const char*)%s(GL_VERSION))", strFunc)
+		hFile:write "\n"
+		
+		--Load extensions in different ways, based on version.
+		hFile:write("if(g_majorVersion < 3)\n")
+		hFile:write "{\n"
+		hFile:inc()
+		--Load the file from a list of extensions. We already have the string getter.
+		hFile:fmt("ProcExtsFromExtString((const char*)%s());\n", strFunc)
+		hFile:dec()
+		hFile:write "}\n"
+		hFile:write "else\n"
+		hFile:write "{\n"
+		hFile:inc()
+		--Load some additional functions.
+		local indexed = spec.GetIndexedExtStringFunc(options);
+		common.FixupIndexedList(specData, indexed)
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, indexed[1], spec, options))
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, indexed[3], spec, options))
+		hFile:write("\n")
+		hFile:write("ProcExtsFromExtList();\n")
+		hFile:dec()
+		hFile:write "}\n"
+	else
+		local extListName, needLoad = spec.GetExtStringFuncName()
+		if(needLoad) then
+			extListName = FindFuncByName(specData, extListName)
+			
+			hFile:writeblock(glload.GetInMainFuncLoader(hFile, extListName, spec, options))
+
+			extListName = glload.GetFuncPtrName(extListName, spec, options);
+		end
+
+		local function EnumResolve(enumName)
+			return GetEnumName(specData.enumtable[enumName], spec, options)
+		end
+		
+		hFile:write "\n"
+		hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
+			extListName,
+			spec.GetExtStringParamList(EnumResolve))
+	end
+	
+	hFile:write "\n"
+	--Write the core loading, if any.
+	if(options.version) then
+		--Step 1: figure out if we're core or compatibility. Only applies
+		--to GL 3.1+
+		hFile:writeblock [[
+if(g_majorVersion >= 3)
+{
+	if(g_majorVersion == 3 && g_minorVersion == 0)
+	{ //Deliberately empty. Core/compatibility didn't exist til 3.1.
+	}
+	else if(g_majorVersion == 3 && g_minorVersion == 1)
+	{
+		if(glext_ARB_compatibility)
+			compProfile = 1;
+	}
+	else
+	{
+		GLint iProfileMask = 0;
+		glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &iProfileMask);
+		
+		if(!iProfileMask)
+		{
+			if(glext_ARB_compatibility)
+				compProfile = 1;
+		}
+		else
+		{
+			if(iProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+				compProfile = 1;
+		}
+	}
+}
+]]
+		hFile:write "\n"
+
+		--Step 2: load the version.
+		local major, minor = options.version:match("(%d+)%.(%d+)")
+
+		hFile:fmtblock([[
+numFailed = LoadVersionFromMap(g_majorVersion, g_minorVersion, compProfile);
+if(numFailed == 0)
+{
+	//Unable to find a compatible one. Load max version+compatibility.
+	numFailed = LoadVersionFromMap(4, 3, compProfile);
+}
+
+return numFailed;
+]], major, minor)
+		
+	else
+		hFile:fmt("return %s;\n", spec.DeclPrefix() .. "LOAD_SUCCEEDED")
+	end
+	
+	hFile:dec()
+	hFile:write "}\n"
+end
+
+function source.WriteMainExtraFuncs(hFile, specData, spec, options)
+	hFile:writeblock[[
+int GetMajorVersion() { return g_majorVersion; }
+int GetMinorVersion() { return g_minorVersion; }
+
+int IsVersionGEQ( int testMajorVersion, int testMinorVersion )
+{
+	if(g_majorVersion > testMajorVersion) return 1;
+	if(g_majorVersion < testMajorVersion) return 0;
+	if(g_minorVersion >= testMinorVersion) return 1;
+	return 0;
+}
+]]
+end
+
 ------------------------------------------------------
 -- Filters
 
 end
 
 
-function my_style.FilterHasCompatibility(version, specData, spec, options)
+function my_style.FilterVersionHasCompProfile(version)
 	if(tonumber(version) >= 3.1) then
 		return true
 	else

File modules/StylePointerC.lua

 
 function my_style.source.WriteUtilityDefs(hFile, specData, spec, options)
 	--Write the struct for the mapping table.
-	hFile:write("typedef int (*PFN_LOADEXTENSION)();\n")
-	hFile:fmt("typedef struct %s%sStrToExtMap_s\n",
-		options.prefix, spec.DeclPrefix())
-	hFile:write("{\n")
-	hFile:inc()
-	hFile:write("char *extensionName;\n")
-	hFile:write("int *extensionVariable;\n")
-	hFile:write("PFN_LOADEXTENSION LoadExtension;\n")
-	hFile:dec()
-	hFile:fmt("} %s;\n", GetMapTableStructName(spec, options))
-	hFile:write "\n"
-	
-	--Write the mapping table itself.
-	hFile:fmt("static %s %s[] = {\n",
+	local mapStructName = string.format("%s%sStrToExtMap_s", options.prefix, spec.DeclPrefix())
+	common.WriteCMappingTable(hFile, specData, spec, options,
 		GetMapTableStructName(spec, options),
-		GetMapTableVarName())
-	hFile:inc()
-	for _, extName in ipairs(options.extensions) do
-		if(#specData.extdefs[extName].funcs > 0) then
-			hFile:fmt('{"%s", &%s, %s},\n',
-				spec.ExtNamePrefix() .. extName,
-				GetExtVariableName(extName, spec, options),
-				GetExtLoaderFuncName(extName, spec, options))
-		else
-			hFile:fmt('{"%s", &%s, NULL},\n',
-				spec.ExtNamePrefix() .. extName,
-				GetExtVariableName(extName, spec, options))
-		end
-	end
-	hFile:dec()
-	hFile:write("};\n")
-	hFile:write "\n"
-	
-	hFile:fmt("static int g_extensionMapSize = %i;\n", #options.extensions);
+		GetMapTableVarName(),
+		GetExtVariableName,
+		GetExtLoaderFuncName)
 	hFile:write "\n"
 	
 	--Write function to find map entry by name.
-	hFile:fmt("static %s *FindExtEntry(const char *extensionName)\n",
-		GetMapTableStructName(spec, options))
-	hFile:write("{\n")
-	hFile:inc()
-	hFile:write("int loop;\n")
-	hFile:fmt("%s *currLoc = %s;\n",
+	common.WriteCFindExtEntryFunc(hFile, specData, spec, options,
 		GetMapTableStructName(spec, options),
 		GetMapTableVarName())
-	hFile:writeblock([[
-for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
-{
-	if(strcasecmp(extensionName, currLoc->extensionName) == 0)
-		return currLoc;
-}
-
-return NULL;
-]])
-	hFile:dec()
-	hFile:write("}\n")
 	hFile:write "\n"
 
 	--Write the function to clear the extension variables.
-	hFile:fmt("static void ClearExtensionVars()\n")
-	hFile:write("{\n")
-	hFile:inc()
-	for _, extName in ipairs(options.extensions) do
-		hFile:fmt('%s = %s;\n',
-			GetExtVariableName(extName, spec, options),
-			GetStatusCodeName("LOAD_FAILED", spec, options))
-	end
-	hFile:dec()
-	hFile:write("}\n")
+	common.WriteCClearExtensionVarsFunc(hFile, specData, spec, options,
+		GetExtVariableName,
+		GetStatusCodeName("LOAD_FAILED", spec, options))
 	hFile:write "\n"
 	
-	--Write a function that loads an extension by name. It is called when
-	--processing, so it should also set the extension variable based on the load.
-	hFile:writeblock([[
-static void LoadExtByName(const char *extensionName)
-{
-	]] .. GetMapTableStructName(spec, options) .. [[ *entry = NULL;
-	entry = FindExtEntry(extensionName);
-	if(entry)
-	{
-		if(entry->LoadExtension)
-		{
-			int numFailed = entry->LoadExtension();
-			if(numFailed == 0)
-			{
-				*(entry->extensionVariable) = ]] ..
-				GetStatusCodeName("LOAD_SUCCEEDED", spec, options) ..
-				[[;
-			}
-			else
-			{
-				*(entry->extensionVariable) = ]] ..
-				GetStatusCodeName("LOAD_SUCCEEDED", spec, options) ..
-				[[ + numFailed;
-			}
-		}
-		else
-		{
-			*(entry->extensionVariable) = ]] ..
-			GetStatusCodeName("LOAD_SUCCEEDED", spec, options) ..
-			[[;
-		}
-	}
-}
-]])
-
+	--Write a function that loads an extension by name.
+	common.WriteCLoadExtByNameFunc(hFile, specData, spec, options,
+		GetMapTableStructName(spec, options),
+		GetStatusCodeName("LOAD_SUCCEEDED", spec, options))
 	hFile:write "\n"
-	
 end
 
 local function WriteAncillaryFuncs(hFile, specData, spec, options)
 	local indexed = spec.GetIndexedExtStringFunc(options);
 	if(indexed) then
-		for _, func in ipairs(specData.funcData.functions) do
-			if(indexed[1] == func.name) then
-				indexed[1] = func
-			end
-			if(indexed[3] == func.name) then
-				indexed[3] = func
-			end
-		end
-		for _, enum in ipairs(specData.enumerations) do
-			if(indexed[2] == enum.name) then
-				indexed[2] = enum
-			end
-			if(indexed[4] == enum.name) then
-				indexed[4] = enum
-			end
-		end
-	
-		hFile:writeblock([[
-static void ProcExtsFromExtList()
-{
-	GLint iLoop;
-	GLint iNumExtensions = 0;
-	]] .. GetFuncPtrName(indexed[1], spec, options)
-	.. [[(]] .. GetEnumName(indexed[2], spec, options)
-	.. [[, &iNumExtensions);
-
-	for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
-	{
-		const char *strExtensionName = (const char *)]] ..
-		GetFuncPtrName(indexed[3], spec, options) ..
-		[[(]] .. GetEnumName(indexed[4], spec, options) .. [[, iLoop);
-		LoadExtByName(strExtensionName);
-	}
-}
-]])
+		common.FixupIndexedList(specData, indexed)
+		hFile:writeblock(common.GetProcExtsFromExtListFunc(
+			hFile, specData, spec, options,
+			indexed, GetFuncPtrName, GetEnumName))
 	else
 		hFile:writeblock(common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
 	end

File modules/glload_util.lua

 
 local util = require "util"
+local common = require "CommonStyle"
 
 local data = {}
 
 	return "LoadVersion_" .. version:gsub("%.", "_") .. "_Comp"
 end
 
---[[
-$<specname>
-$<prefix>
-$<desc>
-$<extra>
-]]
+function data.GetMapTableStructName(spec, options)
+	return string.format("%s%sStrToExtMap", options.prefix, spec.DeclPrefix())
+end
+
+function data.GetInMainFuncLoader(hFile, func, spec, options)
+	local ret = ""
+	ret = ret .. string.format('%s = %s("%s%s");\n',
+		data.GetFuncPtrName(func, spec, options),
+		common.GetProcAddressName(spec),
+		spec.FuncNamePrefix(), func.name)
+	ret = ret .. string.format('if(!%s) return %s;\n',
+		data.GetFuncPtrName(func, spec, options),
+		"0")
+	return ret
+end
+
 
 local hdr_extra_spec =
 {
 int $<prefix>GetMinorVersion();
 
 ///Returns non-zero if the current GL version is greater than or equal to the given version.
-int $<prefix>IsVersionGEQ(int iMajorVersion, int iMinorVersion);
+int $<prefix>IsVersionGEQ(int testMajorVersion, int testMinorVersion);
 ]=],
 }
 
 
 \return Will return $<prefix>LOAD_FAILED if the loading failed entirely and nothing was loaded. Returns $<prefix>LOAD_SUCCEEDED if the loading process worked as planned. If it is neither, then the (return value - $<prefix>LOAD_SUCCEEDED) is the number of core functions that fialed to load.
 **/
-int $<prefix>LoadFunctions();
+int $<prefix>LoadFunctions($<params>);
 
 $<extra>
 ///@}
 	ret = ret:gsub("%$%<specname%>", spec.DisplayName())
 	ret = ret:gsub("%$%<prefix%>", spec.DeclPrefix())
 	ret = ret:gsub("%$%<desc%>", hdr_desc[options.spec])
+	ret = ret:gsub("%$%<params%>", spec.GetLoaderParams())
 	return ret
 end