import soloud_codegen
fo = open("../glue/soloud.cs", "w")
C_TO_CS_TYPES = {
"string":"string",
"int":"int",
"void":"void",
"const char *":"string",
"char *":"string",
"unsigned int":"uint",
"float":"float",
"double":"double",
"float *":"float[]",
"File *":"SoloudObject",
"unsigned char *":"IntPtr",
"const unsigned char *":"IntPtr",
"unsigned char":"byte",
"short *":"IntPtr"
}
for soloud_type in soloud_codegen.soloud_type:
C_TO_CS_TYPES[soloud_type + " *"] = "SoloudObject"
def has_ex_variant(funcname):
if funcname[-2::] == "Ex":
return False
for func in soloud_codegen.soloud_func:
if func[1] == (funcname + "Ex"):
return True
return False
fo.write("""
// SoLoud wrapper for C# (cs)
// This file is autogenerated; any changes will be overwritten
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace SoLoud
{
public class SoloudObject
{
public IntPtr objhandle;
}
""")
fo.write("\n")
def fix_default_param(defparam, classname):
if (classname + '::') == defparam[0:len(classname)+2:]:
return defparam[len(classname)+2::]
if defparam == "true":
return "1"
elif defparam == "false":
return "0"
return defparam.replace("::", ".")
def external_pointer_fix(param):
if param == "SoloudObject":
return "IntPtr"
if param == "string":
return "[MarshalAs(UnmanagedType.LPStr)] string"
return param
for x in soloud_codegen.soloud_type:
first = True
for y in soloud_codegen.soloud_func:
if (x + "_") == y[1][0:len(x)+1:]:
if first:
fo.write('\n')
fo.write('public class %s : SoloudObject, IDisposable\n{\n'%(x))
for z in soloud_codegen.soloud_enum:
if z[0:len(x)+1] == x.upper()+'_':
s = str(soloud_codegen.soloud_enum[z])
fo.write('\tpublic const int %s = %s;\n'%(z[len(x)+1::], s))
fo.write('\n\t[DllImport("soloud_x86.dll", CallingConvention = CallingConvention.Cdecl)]\n\tinternal static extern IntPtr %s_create();\n'%(x))
fo.write('\tpublic %s()\n\t{\n'%(x))
fo.write('\t\tobjhandle = %s_create();\n'%(x))
fo.write('\t}\n')
fo.write('\n\t[DllImport("soloud_x86.dll", CallingConvention = CallingConvention.Cdecl)]\n\tinternal static extern IntPtr %s_destroy(IntPtr aObjHandle);\n'%(x))
fo.write('\t~%s()\n\t{\n'%(x))
fo.write('\t\t%s_destroy(objhandle);\n'%(x))
fo.write('\t}\n')
fo.write('\tpublic void Dispose()\n\t{\n')
fo.write('\t\tif (objhandle != IntPtr.Zero) {\n')
fo.write('\t\t\t%s_destroy(objhandle);\n'%(x))
fo.write('\t\t\tobjhandle = IntPtr.Zero;\n')
fo.write('\t\t\tGC.SuppressFinalize(this);\n')
fo.write('\t\t}\n')
fo.write('\t}\n')
first = False
funcname = y[1][len(x)+1::]
if funcname[-2::] == "Ex":
funcname = funcname[:len(funcname)-2]
if funcname == "create" or funcname == "destroy" or has_ex_variant(y[1]):
pass else:
charptr = False
floatptr = False
ret = C_TO_CS_TYPES[y[0]]
if y[0] == 'const char *':
charptr = True
ret = 'IntPtr'
if y[0] == 'const unsigned char *':
charptr = True
ret = 'IntPtr'
if y[0] == 'float *':
floatptr = True
ret = 'IntPtr'
fo.write('\n\t[DllImport("soloud_x86.dll", CallingConvention = CallingConvention.Cdecl)]\n\tinternal static extern %s %s(IntPtr aObjHandle'%(ret, y[1]))
for z in y[2]:
if len(z) > 1:
if z[1] == 'a'+x:
pass else:
fo.write(', ')
fo.write(external_pointer_fix(C_TO_CS_TYPES[z[0]]) + ' ' + z[1])
fo.write(');\n')
fo.write('\tpublic %s %s('%(C_TO_CS_TYPES[y[0]], funcname))
firstparm = True
for z in y[2]:
if len(z) > 1:
if z[1] == 'a'+x:
pass else:
if firstparm:
firstparm = False
else:
fo.write(', ')
fo.write(C_TO_CS_TYPES[z[0]] + ' ' + z[1])
if len(z) > 2:
fo.write(' = ' + fix_default_param(z[2], x))
fo.write(')\n\t{\n')
if floatptr:
fo.write('\t\tfloat[] ret = new float[256];\n')
fo.write('\t\t')
if y[0] == 'void':
pass
elif charptr or floatptr:
fo.write('IntPtr p = ')
else:
fo.write('return ')
fo.write(y[1] + '(objhandle')
for z in y[2]:
if len(z) > 1:
if z[1] == 'a'+x:
pass else:
fo.write(', ')
fudged_type = C_TO_CS_TYPES[z[0]]
if fudged_type == 'SoloudObject':
fo.write(z[1] + '.objhandle')
else:
fo.write(z[1])
fo.write(');\n')
if charptr:
fo.write('\t\treturn Marshal.PtrToStringAnsi(p);\n')
if floatptr:
fo.write("""
\t\tbyte[] buffer = new byte[4];
\t\tfor (int i = 0; i < ret.Length; ++i)
\t\t{
\t\t\tint f_bits = Marshal.ReadInt32(p, i * 4);
\t\t\tbuffer[0] = (byte)((f_bits >> 0) & 0xff);
\t\t\tbuffer[1] = (byte)((f_bits >> 8) & 0xff);
\t\t\tbuffer[2] = (byte)((f_bits >> 16) & 0xff);
\t\t\tbuffer[3] = (byte)((f_bits >> 24) & 0xff);
\t\t\tret[i] = BitConverter.ToSingle(buffer, 0);
\t\t}
\t\treturn ret;
""")
fo.write('\t}\n')
if not first:
fo.write('}\n')
fo.write('}\n')
print("soloud.cs generated")
fo.close()