Lunea is a set of: preprocessor and libraries for D oriented to make games or multimedia applications using an enviroment oriented to processors (little threads).

There is several languages similar to Lunea:

Then, why make another pseudo-language/library to do same task?

Originally div had Pascal sintax and it was limited to the API its served. It was only for DOS.

Fenix intends port DIV to several SOs and Systems through SDL and a interpreted byte-code. SDL -> Portable.

CDIV is a set of libraries and defines to program using the "process orientated" programming philosophy. The sintaxis is tricky and has the needed to use pointers. Sintaxis inherited from C++. Allegro -> Portable.

Lunea is a set of libraries and a preprocessor to program using the "process orientated" programming philosophy. The sintaxis is simple and you haven't to use pointer. Sintaxis inherited from D. Inheriting all the advantages of D.
SDL + OpenGL -> Portable. Hardware accelerated; compiled. Very Fast.
Furthermore, Lunea introduces new features in comparison of cdiv and fenix.

Currently I have been working on it for months and now it works with enough features to allow making simple games. Now I'll intend to establish a work group and add new features to the pseudo-language and release a prior beta version of project.

Below, you can see a screenshot of a demo i have done and the sourcecode.

Screenshot

Example

Image moon;
Image light;

// Here we have a process with several actions we can swap in execution time.
process MyMoon {
	real vx = 0, vy = 0;

	// main action is executed firstly but we can change the action executing after
	action main {
		graph = moon;

		new MyMoonShadow; frame();

		while (true) {
			// We change the velocity of process using keyboard
			if (key[_right] && vx <  8) vx += 2;
			if (key[_left]  && vx > -8) vx -= 2;
			if (key[_down]  && vy <  8) vy += 2;
			if (key[_up]    && vy > -8) vy -= 2;

			// We change the action executing for this instance of process
			if (key[_m]) action(main2);

			// We update the position throgh the velocity variables
			x += vx; y += vy;

			// Here we decrease the velocity variables
			if (vx != 0) vx = (vx < 0) ? vx + 1 : vx - 1;
			if (vy != 0) vy = (vy < 0) ? vy + 1 : vy - 1;

			// We change the angle and size values causing bitmap spining
			angle += 0.05;
			size   = 1.0 + (cos(angle) / 3);

			frame();
		}
	}

	action main2 {
		while (true) {
			angle += 0.05;
			//size   = 1.0 + (cos(angle) / 3);
			frame();
		}
	}
}

process MyMoonShadow {
	action main {
		// We'll use the same graphic that uses its parent
		graph = father.graph;

		group.z        = father;
		group.priority = father;

/*
It's a dump of process hierarchy:
We can see how MyMoonShadow process
is a child of Moon process in Z and
PRIORITY trees so even when, for example,
the Z value of MyMoonShadow is minor than
the Z value of MyMoon since MyMoonShadow is
a child of MyMoon it will be render after
as well as all process that have MyMoon or
MyMoonShadow as group.z.

DUMP {
	DUMP(ALL) {
		- (1, MainProcess)
		- (2, Light)
		- (3, MyMoon)
		- (4, MyMoon)
		- (5, MyMoonShadow)
		- (6, MyMoonShadow)
	}
	DUMP(Z) {
		-[0] (0, ProcessManager) {
			-[-1] (1, MainProcess)
			-[1] (4, MyMoon) {
				-[0] (6, MyMoonShadow)
			}
			-[1] (3, MyMoon) {
				-[0] (5, MyMoonShadow)
			}
			-[5] (2, Light)
		}
	}
	DUMP(E) {
		-[0] (0, ProcessManager) {
			-[0] (1, MainProcess)
			-[0] (2, Light)
			-[0] (3, MyMoon) {
				-[0] (5, MyMoonShadow)
			}
			-[0] (4, MyMoon) {
				-[0] (6, MyMoonShadow)
			}
		}
	}
}
*/

		while (true) {
			z        = father.z - 1;
			angle    = father.angle;
			size     = father.size;
			alpha    = father.alpha / 3;
			tint     = 0x00000000;
			x        = father.x + (((father.x - Screen.width  / 2) * 30) / (Screen.width  / 2)) * size;
			y        = father.y + (((father.y - Screen.height / 2) * 30) / (Screen.height / 2)) * size;

			frame();
		}
	}
}

// Its a very simple process that blends "light.png" at middle of screen.
// Its alpha is changing. If "angle" variable is minor than 0 or over 2 * PI,
// Process Manager changes it to a equivalent value inner ]0, 2 * PI[
process Light {
	action main {
		graph = light;

		x = 320; y = 240; z = 5;

		while (true) {
			alpha = 0.7 + (cos(angle += 0.1) / 4);

			frame();
		}
	}
}

/*
"program" is a process instanced at beginning:

int main(char[][] args) {
	try {
		return pmanager.start(args, new MainProcess);
	} catch (Exception e) {
		writefln(e.toString);
	}
}

The Process Manager (pmanager) has the task of execute all process orderer by
priority and render them orderer by z.
*/
program {
	// Code executed just after the process is instantiated
	this() {
		Screen.set(640, 480, "Lunea Test");

		moon  = Image.fromFile("moon2.png");
		light = Image.fromFile("light.png");
	}

	// Code executed when program process is destroyed
	~this() {
		Logger.add("Finishing the program");
	}

    action main {
		// Set fps of game to 60
		fps = 60;

		// Instances a new Light process
		new Light;

		// Instances a new MyMoon process
		// setting its x, y, z values
		with (new MyMoon) {
			x = 320 - (moon.w / 2);
			y = 240 - (moon.h / 2);
			z = 1;
		}

		with (new MyMoon) {
			x = 120 - (moon.w / 2);
			y = 140 - (moon.h / 2);
			z = 1;
		}

		// Change the z value of MainProcess (a shining blended box)
		z = -1;

		// Running main process until ESC key is pressed
		while (!key[_esc]) {
			// Changing angle of process
			angle += 0.01;

			if (key[_f]) fps = fmin(fmax(30, Mouse.y / 4), 120);

			frame();
		}

		// Removes all process and finalizes the program
		exit();

    }

	// We use direct-opengl to render a shaded filled box
	// We can override default draw method of process
	action draw {
		// We use angle to establish the alpha value we'll use to render the box
		float alpha = 1 - (fabs(cos(angle)) / 2);

		glEnable(GL_BLEND); glBegin(GL_POLYGON);
			glColor4f(0.0, 0.0, 1.0, 1.0 - alpha / 2); glVertex2i(  0,   0);
			glColor4f(0.0, 0.0, 1.0, 1.0 - alpha / 2); glVertex2i(640,   0);
			glColor4f(1.0, 0.0, 0.0, alpha); glVertex2i(640, 480);
			glColor4f(1.0, 0.0, 0.0, alpha); glVertex2i(  0, 480);
		glEnd(); glDisable(GL_BLEND);
	}
}

/*
Using Lunea we haven't makefiles or something similar.
We use the "lunea" command (even without parameters) and
the program search .lun files in current directory searching
for config blocks and obtaining how to compile from there.
*/
config {
	title:            "Lunea Test";
	console:          "false";
	driver:           "gl2d";
	output:           "test";

	import:           "std.stdio";
	import:           "std.math";

	icon:             "icon.ico";

	comments:         "Comments";
	companyname:      "CompanyName";
	filedescription:  "FileDescription";
	fileversion:      "1, 0, 0, 1";
	internalname:     "InternalName";
	legalcopyright:   "LegalCopyright";
	legaltrademarks:  "LegalTrademarks";
	productname:      "ProductName";
	productversion:   "1, 0, 0, 1";
}