Hi game developers,
I've invented a new programming language based on over 20 years of experience writing games for a living and I'd like
to invite you all to give it a try.
The language is called C-UP, which is a play on the classic gaming terminology for lives/turns/power-ups: 1-up, 2-up, etc.
It's a C style imperative language so it should look very familiar to most of you but I hope it introduces enough new
concepts to make it worthwhile. I guess the headline features are safe automatic parallelism, full support for
SIMD vector types, proper arrays with slicing, multi-methods and generics, but there's lots of other good stuff.
Vector math is all SIMD based with intrinsic functions for things like dot, cross, min, max, sin, cos, etc.
There are libraries for collections, matrices, quaternions, window management, OpenGL, OpenCL, input, file system and
3d rigid body dynamics. Audio and networking are at the top of my list of libraries to implement next although you are
free to make your own.
There's also a debugger written in C-UP itself.
You can download it for free (Windows only) at: www.c-up.net.
Sorry for the basic website implementation but all of my time is being devoted to the language itself.
Unfortunately this means that there are no forums or anything yet but you can email me at the address given on the site
and of course discuss here. I'll try to answer any questions you have but it is just me and I do have a full time job in the
industry as well so please bear with me.
Thanks in advance for any time you're able to spend looking at this project - I hope you like it,
Si
P.S. Here's a little C-UP program to give you a taste of the language. This example draws some 2d coloured squares in parallel
using simd vector maths and 2d arrays with slicing.
// entry point
int Main(string[] args)
{
// allocate a 2d dynamic array of 4 byte simd vector type
// (a comprehensive range of simd types is supported)
byte4[,] image = new byte4[64, 64];
parallel
{
// fill the top-left quarter in red (array slicing with .. allows us to make a sub-array aliased over the master array)
BlendRect(image[0..32, 0..32], byte4(255, 0, 0, 255));
// fill the top-right quarter in green
BlendRect(image[0..32, 32..64], byte4(0, 255, 0, 255));
// fill the bottom-left quarter in blue
BlendRect(image[32..64, 0..32], byte4(0, 0, 255, 255));
// fill the bottom-right quarter in yellow
BlendRect(image[32..64, 32..64], byte4(255, 255, 0, 255));
// blend a 50% alpha white square over the middle
BlendRect(image[16..48, 16..48], byte4(255, 255, 255, 128));
// The calls to the parallel BlendRect function don't execute until the parallel block { } exits
// and then they execute in parallel with automatic dependency checking.
// In this example the first 4 squares will be filled in parallel and the final one will not happen until
// they are all complete because it overlaps them all
}
return 0;
}
// fill an alpha blended rectangle
parallel void BlendRect(byte4[,] local rect, byte4 colour)
{
// expand source colour to 16 bits per channel
short4 srcColour = colour;
// foreach on a 2d array gives each row in turn as a 1d array
foreach (byte4[] row; rect)
{
// foreach on a 1d array yields each element in turn
foreach (byte4& pixel; row)
{
// expand destination colour to 16 bits per channel
short4 dstColour = *pixel;
// perform blend - vector component swizzling and write masking is supported like glsl
pixel.rgb = cast(byte4)(dstColour + ((srcColour - dstColour) * srcColour.aaaa) >> 8);
}
}
}