Example projects

Some examples to demonstrate Detroit engine in action. Although some of the examples can be used as a standalone applications, their primary purpose is just to demonstrate the engine and nothing more.

  1. Vesmir is artificial universe simulation. It generates a galaxy and about ten thousand stars in it. Some stars have planets to form solar systems, where some planets has moons as their companion. All the stars and planet images are modeled in realtime based on their chemical composition, so the outlook of the objects are quite close how they would look in reality. Vesmir example demonstrates drawing operations, menues, some of the widgets how they interact with window, and how to bind own C functions to Ano script.

  2. Deskmenu is a small desktop app launcher. Menu pops up by pressing middle mouse button, or alternatively keep ctrl key pressed while pressing the left mouse button. Deskmenu example demonstrates how to attach menu to widget and how to call external command in widget callback function, as well how to set some window attributes, like borderless and keep-above.

  3. Julia draws a Julia set in little window. Julia example demonstrates how to spawn a thread for drawing and do some RPN expressions to plot the pixels to window.

  4. Mandelbrot pretty much the same as Julia example above but draws a Mandelbrot set.

  5. Widgets example is nice looking but obsolete application just for playing and getting touch with most of the widgets. Widgets example demonstrates how to use different type of widgets and their attributes.

Example snippets

Some small Ano script snippets to demonstrate how to get various things done. See engine operands reference for detailed explanations for each function.

Audible white noise

Example how to generate white noise and play it.

	; Global uninitialized variables
	var	[handle] handle_audio

	; Initialize audio system
	audio_init

	; Generate 5 seconds of white noise and play it
	audio_create_noise_white (5.0)
	cmp	rc (@0)
	je	"error"
	mov	handle_audio (rc)

	audio_play (handle_audio, 1.0, 0.0)
	audio_wait (handle_audio)
	audio_close (handle_audio)

: "error"
	exit

Audible random wave

Example how to generate random wave and play it.

	; Global uninitialized variables
	var	[handle] handle_audio

	; Initialize audio system
	audio_init

	; Generate 5 second 400Hz (average) random wave using amplitude of 1.0
	; and play it, sounds a bit like when sitting in aeroplane
	audio_create_wave_random (5.0, 400.0, 1.0)
	cmp	rc (@0)
	je	"error"
	mov	handle_audio (rc)

	audio_play (handle_audio, 1.0, 0.0)
	audio_wait (handle_audio)
	audio_close (handle_audio)

: "error"
	exit

Audible sine wave

Example how to generate sine wave and play it.

	; Global uninitialized variables
	var	[handle] handle_audio

	; Initialize audio system
	audio_init

	; Generate 5 second 440Hz sine wave and play it
	audio_create_wave_sine (5.0, 440.0)
	cmp	rc (@0)
	je	"error"
	mov	handle_audio (rc)

	audio_play (handle_audio, 1.0, 0.0)
	audio_wait (handle_audio)
	audio_close (handle_audio)

: "error"
	exit

Audible square wave

Example how to generate square wave and play it.

	; Global uninitialized variables
	var	[handle] handle_audio

	; Initialize audio system
	audio_init

	; Generate 5 second 440Hz square wave and play it
	audio_create_wave_square (5.0, 440.0)
	cmp	rc (@0)
	je	"error"
	mov	handle_audio (rc)

	audio_play (handle_audio, 1.0, 0.0)
	audio_wait (handle_audio)
	audio_close (handle_audio)

: "error"
	exit

Audio file

Example how to play audio file.

	; Global uninitialized variables
	var	[handle] handle_audio

	; Initialize audio system
	audio_init

	; Open sound file and play it
	audio_open ("audio_file.flac")
	cmp	rc (@0)
	je	"error"
	mov	handle_audio (rc)

	audio_play (handle_audio, 1.0, 0.0)
	audio_wait (handle_audio)
	audio_close (handle_audio)

: "error"
	exit

Draw simple primitives

Example how to draw simple primitives to window.

	; Global uninitialized variables
	var	[handle] handle_window_main

	; Global pre-initialized variables
	mov	color ("cyanwhite")
	mov	color_alpha (# 0xe0, 0xff, 0xff, 0x80)

	; Initialize windowing system
	window_init

	; Open main window
	window_open ("Drawing window", NULL, \
		[handle] @0, [uint] 0, [uint] 0, [uint] 1, \
		[int] -1, [int] -1, [uint] 600, [uint] 300, \
		"cb_mainloop_main", NULL, \
		"cb_keypress_main", "cb_keyrelease_main", \
		"cb_buttonpress_main", "cb_buttonrelease_main", \
		NULL, NULL, "cb_destroy_main", \
		"cb_motion_main", NULL, NULL, "cb_open_main")
	end

callback cb_mainloop_main {
	draw_wipe (handle_window_main)

	draw_pixel (handle_window_main, 10, 10, color)
	draw_pixel_alpha (handle_window_main, 20, 10, color_alpha)

	draw_subpixel (handle_window_main, 10, 20, color)
	draw_subpixel_alpha (handle_window_main, 20, 20, color_alpha)

	draw_set (handle_window_main, 10, 80, 20, 90, color)
	draw_set_alpha (handle_window_main, 30, 80, 40, 90, color_alpha)

	draw_border (handle_window_main, 10, 100, 10, 10, 1, color)
	draw_border_alpha (handle_window_main, 30, 100, 10, 10, 3, color_alpha)

	draw_copy (handle_window_main, 10, 10, 300, 10, 50, 50)
}

callback cb_open_main (hnd) {
	mov	handle_window_main (hnd)

	; Map main window
	window_map (handle_window_main)
}

callback cb_destroy_main {
	window_close (handle_window_main)

	exit
}

callback cb_keypress_main (x, y, x_root, y_root, state, keycode, key) {
}

callback cb_keyrelease_main (x, y, x_root, y_root, state, keycode, key) {
}

callback cb_buttonpress_main (x, y, x_root, y_root, state, button) {
}

callback cb_buttonrelease_main (x, y, x_root, y_root, state, button) {
}

callback cb_motion_main (x, y, x_root, y_root, state, detail) {
}

Draw moving block

Example how to draw mouse-following block to window.

	; Global uninitialized variables
	var	[handle] handle_window_main

	; Global pre-initialized variables
	mov	color ("cyanwhite")

	mov	pos_x ([int] 0)
	mov	pos_y ([int] 0)
	mov	set_w ([int] 64)
	mov	set_h ([int] 64)

	; Initialize windowing system
	window_init

	; Open main window
	window_open ("Drawing window", NULL, \
		[handle] @0, [uint] 0, [uint] 0, [uint] 1, \
		[int] -1, [int] -1, [uint] 600, [uint] 300, \
		"cb_mainloop_main", NULL, \
		"cb_keypress_main", "cb_keyrelease_main", \
		"cb_buttonpress_main", "cb_buttonrelease_main", \
		NULL, NULL, "cb_destroy_main", \
		"cb_motion_main", NULL, NULL, "cb_open_main")
	end

callback cb_mainloop_main {
	draw_wipe (handle_window_main)

	; Draw simple block where the pointer is
	draw_set (handle_window_main, \
		pos_x, pos_y, pos_x + set_w, pos_y + set_h, color)
}

callback cb_open_main (hnd) {
	mov	handle_window_main (hnd)

	; Map main window
	window_map (handle_window_main)
}

callback cb_destroy_main {
	window_close (handle_window_main)

	exit
}

callback cb_keypress_main (x, y, x_root, y_root, state, keycode, key) {
}

callback cb_keyrelease_main (x, y, x_root, y_root, state, keycode, key) {
}

callback cb_buttonpress_main (x, y, x_root, y_root, state, button) {
}

callback cb_buttonrelease_main (x, y, x_root, y_root, state, button) {
}

callback cb_motion_main (x, y, x_root, y_root, state, detail) {
	; Update block coordinates
	mov	pos_x (x - (set_w / 2))
	mov	pos_y (y - (set_h / 2))
}

Colors

Example how to use some color related functions.

	; Global uninitialized variables
	var	[color] color1
	var	[color] color2

	; Mix two colors together using factor 0.5
	mov	color1 ("blue")
	mov	color2 (# 0xff, 0x00, 0x00, 0xff)

	color_mix" (color1, color2, 0.5)
	mov	color1 (rc)
	dump	color1

	; Get color complement
	color_complement" (color1)
	mov	color1 (rc)
	dump	color1

	; Get color brightness
	color_brightness" (color1)
	mov	color1 (rc)
	dump	color1

	exit

Coordinates

Example how to use some coordinate related functions.

	; Set initial points for interpolation
	mov	point_1 (& -1.1, 0.0, 0.0)
	mov	point_2 (& -1.1, -0.75, 0.0)
	mov	point_3 (& 1.9, 0.75, 0.0)
	mov	point_4 (& 1.9, 0.0, 0.0)

	; Set interpolation point, bias and tension
	mov	intp (0.0)
	mov	bias (0.0)
	mov	tension (0.0)

	; Loop for ten interpolation points
	loop (mov i ([int] 0); i < 10; inc i) {
		coords_intp_hermite_x (point_1, point_2, point_3, point_4, \
			intp, bias, tension)

		mov	pos_x (rc)
		dump	pos_x

		coords_intp_hermite_y (point_1, point_2, point_3, point_4, \
			intp, bias, tension)

		mov	pos_y (rc)
		dump	pos_y

		add	intp (0.1)
	}

	exit

Images

Example how to use some image related functions.

	; Global uninitialized variables
	var	[image] image

	; Read TGA image in and write it out using RGB format
	image_read ("image_input.tga")
	cmp	rc (% 0)
	je	"error"

	mov	image (rc)
	dump	image

	image_write_rgb ("image_output.rgb", image)
	cmp	rc (0)
	jne	"error"

: "error"
	exit

Host info

Example how to show some info about underlying machine.

	; Global uninitialized variables
	var	[string] system
	var	[string] release
	var	[string] machine
	var	[string] hostname
	var	[string] username
	var	[string] groupname
	var	[string] homedir

	; Get the info
	node_get_system
	mov	system (rc)
	dump	system

	node_get_release
	mov	release (rc)
	dump	release

	node_get_machine
	mov	machine (rc)
	dump	machine

	node_get_hostname
	mov	hostname (rc)
	dump	hostname

	node_get_username
	mov	username (rc)
	dump	username

	node_get_groupname
	mov	groupname (rc)
	dump	groupname

	node_get_homedir
	mov	homedir (rc)
	dump	homedir

	exit

Clock

Example how to use some clock related functions.

	; Global uninitialized variables
	var	[number] ticks
	var	[number] new_multiplier
	var	[number] old_multiplier

	; Get system time in secs since epoch and set clock to that
	time
	mov	time (rc)
	dump	time

	clock_set (time)

	; Get clock tick count
	clock_get_ticks
	mov	ticks (rc)
	dump	ticks

	; Set clock multiplier to ten to make it run ten times faster
	clock_set_multiplier (10)
	mov	old_multiplier (rc)
	dump	old_multiplier

	; Get current multiplier
	clock_get_multiplier
	mov	new_multiplier (rc)
	dump	new_multiplier

	; Wait for a while to tick count to increase
	sleep (2, 0)

	; Get clock tick count again
	clock_get_ticks
	mov	ticks (rc)
	dump	ticks

	exit

Timer

Example how to set the timer.

	; Set timer to trigger one second and two nanoseconds from now
	timer	(1, 2, "my_timer")
	cmp	rc (0)
	jne	"error"

	mov	_msg ("Lets wait for timer...")
	dump	_msg

: "error"
	end

alarm my_timer {
	mov	_msg ("Hello from timer!")
	dump	_msg
}

Thread affinity

Example how to set a thread to run on certain CPU.

	mov	_msg ("Hello from main program!")
	dump	_msg

	thread_spawn ("Ted the Thread", "my_thread")

	; Take a nap while thread starts
	sleep (2, 0)

	exit

thread my_thread {
	; First stick this thread to run on first CPU...
	thread_affinity ([int] 1)

	mov	_msg ("Hello from thread!")
	dump	_msg

	; ...and then to run on all configured CPU's
	thread_affinity ([int] 0)

	mov	_msg ("Hello again from thread!")
	dump	_msg
}

Thread creation

Example how to spawn thread to run concurrently with main program.

	mov	_msg ("Hello from main program!")
	dump	_msg

	thread_spawn ("Ted the Thread", "my_thread")

	; Take a nap while thread starts
	sleep (2, 0)

	exit

thread my_thread {
	mov	_msg ("Hello from thread!")
	dump	_msg
}

System commands

Example how to call some system commands.

	fork
	mov	pid (rc)

	; Parent process exits immediately...
	cmp	pid (0)
	jne	"parent"

	; ...and child process does all the work
	mov	command ("uname")

	sleep ([long] 1, [long] 0)
	exec (command, "-p", "-m", "-r")

	sleep ([long] 3, [long] 0)
	system (command)

	sleep ([long] 5, [long] 0)

: "parent"
	exit

Remote listener

Example how to use remote operations.

	;
	; This is main program, just start remote thread and let it handle
	; remote connections. Program terminates when "remote_end" label is
	; called (see below).
	;

	remote_init
	end

: "remote_test" (param1, param2, param3)
	;
	; To call this function remotely (set SECRET with -na switch):
	;
	; $ telnet localhost 2109
	;   SECRET remote_test int:1 uint:2 float:3.3
	;
	; End code returned to caller is the sum of params or -1 if error
	; occurs
	;

	dump	param1
	dump	param2
	dump	param3
	end	(param1 + param2 + param3)

: "remote_end"
	;
	; To call this function remotely (set SECRET with -na switch):
	;
	; $ telnet localhost 2109
	;   SECRET remote_end
	;
	; Exit code returned to caller is 123
	;

	exit	(123)

Copyright © 2024, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.