1 module allegro5.internal.da5; 2 3 /* 4 * Issue: MinGW 4.5 and below has a bizzare calling convention when 5 * returning structs. ColorWrapper takes care of the difference in 6 * calling convention. If this wrapper is necessary, then D programs 7 * that use DAllegro5 should link against allegro_color even when they 8 * never call any allegro_color function. 9 * 10 * The following toolchains (to compile Allegro DLLs) are free of this issue: 11 * - MSVC, 12 * - maybe MinGW 4.6. 13 * ColorWrapper resolves to a mere binding on all systems that don't 14 * need the caretaking, and allegro_color needs not be linked against 15 * then unless you call a function from allegro_color. 16 * 17 * ColorWrapper is private to DAllegro5. Call ColorWrapper in DAllegro5 18 * outside any "nothrow @nogc extern (C)" because ColorWrapper will 19 * insert attributes itself. 20 */ 21 string ColorWrapper(string prefix, string func, string arg_decls, string arg_names)() 22 { 23 static if (NeedsMinGW4CallingConvention) 24 { 25 // Implement a new D function to wrap Allegro's C function, 26 // fixing the calling convention (see comment for ColorWrapper above). 27 return 28 `nothrow @nogc ALLEGRO_COLOR ` ~ func ~ `(` ~ arg_decls ~ `) 29 { 30 auto ret = ` ~ prefix ~ func ~ `(` ~ arg_names ~ `); 31 asm nothrow @nogc 32 { 33 sub ESP, 4; 34 } 35 return ret; 36 }`; 37 } 38 else 39 { 40 // Declare function as a normal C binding. 41 return 42 `nothrow @nogc extern (C) 43 ALLEGRO_COLOR ` ~ func ~ `(` ~ arg_decls ~ `);`; 44 } 45 } 46 47 bool NeedsMinGW4CallingConvention() pure nothrow @nogc 48 { 49 version(ALLEGRO_MINGW_4_5) 50 { 51 return true; 52 } 53 else 54 { 55 return false; 56 } 57 }