Daed Gaem

An emulator for five DOS games from around 1984. The app is written in C# and serves as an example application for Bluebonnet.

(Please note: The five DOS games are not distributed with this app, and have to be downloaded on first play. All rights to these fives games belong to their respective owners.)

Bluebonnet is a light-weight .NET platform for Android Java which translates compiled .NET assemblies into Java classes.

GitHub pages:  BluebonnetDaed Gaem

Privacy Policy

This app does not collect, store or transmit any personal or private information.

Bluebonnet, light-weight .NET on Java

Bluebonnet is a partial implementation of the .NET platform on top of the Java Virtual Machine, and compatible with Android runtime. The Bluebonnet bytecode compiler translates .NET CIL into Java bytecode in Java classes, and additional run-time support is provided by the Baselib library.

The Bluebonnet platform is compatible with Java on all API levels of the Android platform. This means Android apps can be written in languages such as C# and F#. After conversion, they run as 100% Java code on Android, with no native code libraries. They require only a thin, light-weight support library — the Baselib library.

The Baselib library is itself written in C# and compiled to Java using Bluebonnet. It provides support for .NET features such as types (primitive types, value types, generic types), reflection, collections, and some basic functionality from the .NET Base Class Libraries (BCL).

It should be emphasized that Bluebonnet does not aim to be a full implementation of .NET, and that large parts of the standard .NET libraries are not implemented in Baselib at this time. Having said that, it is possible to create simple Android apps with Bluebonnet. For an example, take a look at the Unjum proof-of-concept game (also on Github).

This game relies on BNA (Github link), which is a partial implementation of the XNA 4 library for Android. The game was developed in F# in Visual Studio on Windows using the original implementation of XNA 4 from Microsoft. Then the game binary was run through Bluebonnet, combined with BNA (as well as with Baselib and the F# core library) and packaged into an APK, ready to run on Android.

For more information, and to download Bluebonnet, please visit the Bluebonnet Github page.


A simple puzzle game for Android, written in F# 5 (.NET 5), with an XNA-like graphics layer, written in C#. It serves as a proof-of-concept application for Bluebonnet and BNA.

Bluebonnet is a light-weight .NET platform for Android Java which translates compiled .NET assemblies into Java classes. BNA is an Android-compatible implementation of XNA 4, written in C# and translated to Android Java using Bluebonnet.

GitHub pages:  BluebonnetBNAUnjum

Eight Board


Five games on an 8×8 board, playable against a friend or computer AI

Checkers, English draughts, Russian shashki, Halma (Chinese checkers),
Othello, Reversi, Wolf and Sheep (Fox and Hounds), all these games
are integrated in one easy-to-use package.

Play against a computer AI opponent, with eight levels of difficulty. Or play against one of your friends! (Random match making not available.)


Privacy Policy

When playing against a friend, this game calculates a 5-digit number from your phone ID and combines it with a similar 5-digit number from your friend to identify the game in progress.

Your real phone ID is never saved, transmitted or tracked; the 5-digit number is not used to track or identify you personally; and none of your personal information is collected by us nor transmitted to any third party.

Spin Match


Collect and match vegetables as they are falling onto a spinning platform

Cabbages, tomatoes and pumpkins and other kinds of yummy vegetables are falling from above. Spin the platform below and catch the vegetable at the right spot so you can build sets of three or more of the same vegetable.



Privacy Policy

This app does not collect any information about you or your device, and does not share any such information with any third party.

Loulabelle, a Lua to JavaScript compiler


version 5203, released May 2018

Compiler/transpiler from Lua 5.2 to JavaScript.
Written in Lua 5.2 and can be compiled to JavaScript.

Project home page:



Online playground:


Reference manual:


Source code download:


GitHub page:


Using ptrace on OS X

Documentation on the subject of using ptrace in OS X seems somewhat lacking. This text attempts to summarize the steps necessary to trace another process. In OS X, the ptrace service itself offers little more than attaching to and detaching from the target process. Other system calls are necessary to accomplish additional jobs, such as accessing target memory and registers.


The first of these system calls is task_for_pid, which gets a “task port” for the target process. (Some parts of the OS X kernel use the term “task” for a process.) This port (or handle) is used in other system calls to query or manipulate the target process.

#include <mach/mach.h>


Note that the first argument specifies which process receives the new task port, with mach_task_self() indicating the current process, and the third argument points to the variable which actually receives the port.

To release the port, at the end of the ptrace session:


The task_for_pid system call is protected by the gatekeeper security framework, and will fail (with error code 5, KERN_FAILURE) unless the calling process is digitally signed, and its Info.plist includes the SecTaskAccess key.

An example of a minimal Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

If desired, this Info.plist can be embedded into the executable by specifying the sectcreate option in the link step:

gcc -sectcreate __TEXT __info_plist Info.plist -o program object1 object2...

Finally, digitally signing the executable is accomplished with codesign(1) utility. This text will not go into the details of using this utility, or generating a self-signed certificate. For more information, please see Mac OS X and Task_for_pid() Mach Call.

Mach exceptions

As part of controlling a process using ptrace, the controlling process expects to be notified about signals in the target process. Using ptrace with the PT_ATTACH request, these notifications are delivered via SIGCHLD signals sent to the controlling process.

However, OS X version 10.2 introduced the PT_ATTACHEXC form of ptrace, which delivers mach exceptions (as opposed to just UNIX signals) via mach messages. And in recent versions of OS X, the old PT_ATTACH form is marked deprecated. This text will therefore focus on the newer PT_ATTACHEXC form.

Mach exception are enumerated in /usr/include/mach/exception_types.h and deal with various faults and traps. For example, EXC_BAD_ACCESS is a memory access fault, and EXC_BREAKPOINT is a software breakpoint trap. One of the exceptions, EXC_SOFTWARE (with code EXC_SOFT_SIGNAL) is used to represent a UNIX signal as a mach exception.

Requesting mach exceptions

To receive mach exceptions, the controlling process must register an “exception port” with the target process, to request notifications on a set of exception types. The controlling process should then listen on the port to receive notifications about exceptions (including UNIX signals) that occur in the target process.

The set of exception types is defined in exception_types.h as EXC_MASK_ALL, but note that previous versions of OS X may not support all exception types, and will fail requests that specify exception types which are not recognized. Note also that LLDB ignores EXC_RESOURCE so it may be advisable to do the same.

It is useful to save the set of exception ports already registered for the target process, before replacing them. This makes it easier to detach the process, as will be discussed in a later section of this document.

Example Code:

/* save the set of exception ports registered in the process */

exception_mask_t       saved_masks[EXC_TYPES_COUNT];
mach_port_t            saved_ports[EXC_TYPES_COUNT];
exception_behavior_t   saved_behaviors[EXC_TYPES_COUNT];
thread_state_flavor_t  saved_flavors[EXC_TYPES_COUNT];
mach_msg_type_number_t saved_exception_types_count;


/* allocate and authorize a new port */


/* and again */        target_exception_port,

/* register the exception port with the target process */


Attaching to the target process

With an exception port registered on the target process, it is finally possible to attach to the process with ptrace.

/* attach to the target process */

ptrace(PT_ATTACHEXC, target_pid, 0, 0);

As part of the attach sequence, the target process will be signalled with SIGSTOP, and this signal will be delivered to the controlling process as a mach “soft signal” exception, that is, exception type EXC_SOFTWARE with code EXC_SOFT_SIGNAL, and sub-code SIGSTOP.

Receiving mach exceptions

When an exception occurs in some thread in the target process, the kernel pushes an exception message into a queue associated with the exception port. The thread then blocks (in the kernel) while waiting for a reply to the exception message. This wait is indefinite; it does not include a timeout.

If the controlling process is not listening on the exception port at the time when an exception is sent, the exception message will remain in the exception port queue, and the thread which sent the exception will remain blocking while waiting for a reply.

While a thread is waiting for a reply in this way, other threads in the process continue to execute, and can generate exceptions, which are handled in the same way as described above.

This queueing mechanism allows the controlling process to have a main loop in which it waits for an exception message, processes the exception, sends a reply message, and then restarts the loop. Processing the exception may take any length of time.

If the exception is a UNIX signal, the UNIX status of the process is set to stopped, before the thread sends the message. This does not prevent other threads in the process from continuing to execute. However, delivery of additional UNIX signal exceptions will be suspended while the UNIX status of the process remains stopped.

/* wait indefinitely to receive an exception message */


char req[128], rpl[128];			/* request and reply buffers */

mach_msg((mach_msg_header_t *)req,	/* receive buffer */
		 MACH_RCV_MSG,				/* receive message */
		 0, 						/* size of send buffer */
		 sizeof(req),				/* size of receive buffer */
		 target_exception_port,		/* port to receive on */
		 MACH_MSG_TIMEOUT_NONE,		/* wait indefinitely */
		 MACH_PORT_NULL);			/* notify port, unused */

/* suspend all threads in the process after an exception was received */


Parsing mach exceptions

Functions for handling the exception message are defined in /usr/include/mach/mach_exc.defs and generated using the mig(1) program. The kernel-side calls the generated mach_exception_raise function when sending the exception.

The controlling process, listening on the exception port, is the receiving end, and receives the exception as a message buffer. It then calls mach_exc_server to extract the data from the message buffer and convert these to function arguments, which are used in the call to the catch_mach_exception_raise function.

The catch_mach_exception_raise function is provided by the program code of the controlling process. In other words, the stub generated by mig(1) calls catch_mach_exception_raise.

Note that mach_exc.defs defines exception_raise, exception_raise_state, and exception_raise_state_identity. A flag passed to task_set_exception_ports (EXCEPTION_DEFAULT in the code fragment above) selects which exception function is used.

To generate the mach_exc_server function for the receiving end, mig(1) is invoked:

mig /usr/include/mach/mach_exc.defs

This generates mach_excUser.c, mach_excServer.c, and mach_exc.h. The second file, mach_excServer.c, contains the mach_exc_server function. This file should be compiled into the executable of the controlling process.

if (kret_from_mach_msg == KERN_SUCCESS) {

	/* mach_exc_server calls catch_mach_exception_raise */
	boolean_t message_parsed_correctly =
				mach_exc_server((mach_msg_header_t *)req,
								(mach_msg_header_t *)rpl);
	if (! message_parsed_correctly) {
		kret_from_catch_mach_exception_raise =
				((mig_reply_error_t *)rpl)->RetCode;

/* resume all threads in the process before replying to the exception */


/* reply to the exception */

mach_msg_size_t send_sz = ((mach_msg_header_t *)rpl)->msgh_size;

mach_msg((mach_msg_header_t *)rpl,	/* send buffer */
		 MACH_SEND_MSG,				/* send message */
		 send_sz,					/* size of send buffer */
		 0,							/* size of receive buffer */
		 MACH_PORT_NULL,			/* port to receive on */
		 MACH_MSG_TIMEOUT_NONE,		/* wait indefinitely */
		 MACH_PORT_NULL);			/* notify port, unused */

/* target process is now running.  wait for a new exception */

goto wait_for_exception;

The last remaining piece is implementing catch_mach_exception_raise,
which is called by the mach_exc_server function after it has parsed the incoming exception message and extracted the message arguments.

As discussed in a preceding section, if the exception is a UNIX soft signal exception, an additional step is required. Before sending the soft signal exception message to the controlling process, the kernel sets the process status to stopped (p_stat = SSTOP).

Similarly, before replying to the message, the controlling process must tell the kernel to reset the process status (p_stat = SRUN). This is accomplished with a call to ptrace with the PT_THUPDATE request, which also modifies the signal number.

By changing the signal number, the controlling process can hide the signal from the target process, by modifying the signal number to zero. For example, for the case of handling SIGSTOP. Or the controlling process can leave the signal to be handled by the target process, or request that some other signal be handled instead.

/* catch_mach_exception_raise */

kern_return_t catch_mach_exception_raise(
    mach_port_t exception_port, 
    mach_port_t thread_port,
    mach_port_t task_port,
    exception_type_t exception_type,
    mach_exception_data_t codes,
    mach_msg_type_number_t num_codes)
	/* exception_type is defined in exception_types.h 						*/

	/* an exception may include a code and a sub-code.  num_codes specifies */
	/* the number of enties in the codes argument, between zero and two.    */
	/* codes[0] is the code, codes[1] is the sub-code.                      */

	if (exception_type == EXC_SOFTWARE && code[0] == EXC_SOFT_SIGNAL) {
		/* handling UNIX soft signal: 							     		*/
		/* this example clears SIGSTOP before resuming the process.  		*/
		if (codes[2] == SIGSTOP)
			codes[2] = 0;


/* catch_mach_exception_raise_state */

kern_return_t catch_mach_exception_raise_state(
    mach_port_t exception_port, 
    exception_type_t exception,
    const mach_exception_data_t code, 
    mach_msg_type_number_t codeCnt,
    int *flavor, 
    const thread_state_t old_state,
    mach_msg_type_number_t old_stateCnt, 
    thread_state_t new_state,
    mach_msg_type_number_t *new_stateCnt)
	/* not used because EXCEPTION_STATE is not specified in the call */
	/* to task_set_exception_ports, but referenced by mach_exc_server */

/* catch_mach_exception_raise_state_identity */

kern_return_t catch_mach_exception_raise_state_identity(
    mach_port_t exception_port, 
    mach_port_t thread, 
    mach_port_t task,
    exception_type_t exception, 
    mach_exception_data_t code,
    mach_msg_type_number_t codeCnt, 
    int *flavor, 
    thread_state_t old_state,
    mach_msg_type_number_t old_stateCnt, 
    thread_state_t new_state,
    mach_msg_type_number_t *new_stateCnt)
	/* not used because EXCEPTION_STATE_IDENTITY is not specified in the   */
	/* call to task_set_exception_ports, but referenced by mach_exc_server */

Detaching target process

As discussed in a preceding section, an exception in the target process causes the thread that triggered the exception to block until the controlling process send a reply message. Detaching from the target process does not release such threads, so all pending exceptions should be handled before detaching.

The saved exception port information should be restored, to prevent new exceptions being sent to the controlling process. However, it is possible the exception port queue contains additional exceptions that have not yet been handled, and must be handled by replying to them.

Detaching from the process can only be requested if the process has a stopped status, as discussed above in the context of UNIX signals. At that point ptrace can be called with request PT_DETACH (or PT_KILL) to detach (or kill) the target process.

Note that PT_THUPDATE resets the stopped status, so it conflicts with PT_DETACH and PT_KILL. If the controlling process wishes to use the stopped status (as a result of an exception) to detach or kill the target, then it should not use PT_THUPDATE in the context of handling that same exception.

The target process may not have a stopped status at the time detaching is requested: The process may be running, or it may be stopped due to an exception that is not a UNIX soft signal exception. In either case, it would be necessary for the controlling process to signal the target process with SIGSTOP, which would generate a UNIX soft signal exception. Then the controlling process continues to handle exceptions, while waiting to receive a UNIX soft signal exception. When it is received, the target process can be detached.

Alternatively, if the target process is to be killed rather than detached, it is possible to handle all pending exceptions, and then send a SIGKILL to the target process, without taking into account whether the target process has a stopped status or not.

/* restore saved exception ports */

for (uint32_t i = 0; i < saved_exception_types_count; ++i) {


/* issue PT_DETACH if there is a pending exception */

if (last_exception_type was a UNIX soft signal) {

	if (reply not yet sent for last exception) {
		ptrace(PT_DETACH, target_pid, 0, 0);

/* process all pending exceptions */

kern_return_t kret_recv = 0;

for (kret_recv == 0) {

	/* reply to last exception */

	mach_msg((mach_msg_header_t *)rpl,	/* send buffer */
			 MACH_SEND_MSG,				/* send message */
			 send_sz,					/* size of send buffer */
			 0,							/* size of receive buffer */
			 MACH_PORT_NULL,			/* port to receive on */
			 MACH_MSG_TIMEOUT_NONE,		/* wait indefinitely */
			 MACH_PORT_NULL);			/* notify port, unused */
	/* get next exception, with timeout option.   when the result   */
	/* is timeout, it means the exception port queue was exhausted. */
	/* no new messages will be queued, because the exception port   */
	/* is no longer associated with the target process.				*/

	kret_recv =
	mach_msg((mach_msg_header_t *)req,		/* receive buffer */
		 MACH_RCV_MSG | MACH_RCV_TIMEOUT,	/* receive message */
		 0, 								/* size of send buffer */
		 sizeof(req),						/* size of receive buffer */
		 target_exception_port,				/* port to receive on */
		 1,									/* wait one millisecond */
		 MACH_PORT_NULL);					/* notify port, unused */

/* release exception port */

mach_port_deallocate(mach_task_self(), target_exception_port);

/* if detach was not possible, kill the target process */

if (! ptraced_detached_called) {

	kill(target_pid, SIGKILL);


This concludes the basic overview of dealing with exception ports in OS X. Please note that some aspects in the example code were simplified for sake of brevity and clarity. As an example, a real debugger would let the user decide how handle an exception, and therefore would not issue ptrace(PT_THUPDATE) in catch_mach_exception_raise immediately after receiving the exception.

As mentioned in the opening paragraph, ptrace on OS X is limited. The reader may wish to look further into thread_get_state and thread_set_state for access to the register state in the target process, and the mach_vm_* functions for access to the virtual memory space of the target process.








Over Fill


Draw lines to claim areas while avoiding enemy balls!

Enjoy a 3D third person perspective while moving around the playing field.
Look around and plan your path to avoid the fast-moving enemy balls.
Draw closed shapes to claim areas. Complete levels and reveal pictures.




Privacy Policy

This app does not collect, store or transmit any personal or private information.

AudioPlayer for Unity on Android and iOS

Many Android devices exhibit varying degrees of latency when playing sound via the Unity AudioSource.

This is a well known issue and there are already several solutions out there to work around
the problem. This is generally achieved by using the Android SoundPool service. The solution offered here is no different in that regard.

The AudioPlayer.cs class provides a platform-neutral API, and two implementations — uses SoundPool on Android, and Unity AudioSource on other platforms. Compiler #if directives select which implementation to build, according to the target platform.

Download AudioPlayer.cs here. (right-click Save As.)

Project and Scene Setup

DSP Buffer Size

For best performance on iOS, the DSP Buffer Size parameter in AudioManager should be set to Best latency, which translates to a DSP Buffer Size of 256KB. When running within the Unity editor, the AudioPlayer class will check and display a warning (via Debug.Assert) if this is not the case.

Placement in Scene

Create an empty GameObject, then use Add Component to add the script AudioPlayer.cs (Audio Player).

It is ok to add more script components to this GameObject. For example, if the scene includes a sound manager class that decides when to play effects, it is possible to place that script on the same GameObject. The example provided below is one such very simple sound manager class.

Sound Files

This class expects sound files as MP3 files that reside within the StreamingAssets directory, which should be placed directly below the Assets folder.

Component Properties

NumChannels (int) determines the maximum number of effects that can play at once. Each channel can play only one sound at a time, but sounds from all channels will be mixed together. The default is 4 channels.

On Android, this value is used during the creation of the SoundPool object. On other platforms, this determines the number of Unity AudioSource objects which will be created.

For API methods that expect a channel number, specify the channel as a number between zero (0) and NumChannels.

Sound (boolean) is set to false if all sound should be muted. It is probably easier to adjust this property using the AudioPlayer.SetSound() method, which does not require a reference to the GameObject containing the AudioPlayer script component.

Using the API – Example Code

using UnityEngine;
using System.Collections;

public class SoundManager : MonoBehaviour {

public PlayerObject player;

// below constants assume the default of four channels in AudioPlayer
const int firstChannel = 0;   // channel zero not used in the example
const int walkChannel = 1;
const int pickupChannel = 2;
const int introChannel = 3;

bool walking;
bool paused;
bool intro;

void Start() {

AudioPlayer.SetSound(PlayerPrefs.GetInt("sound", 1) != 0);

// request to load sound effects.  these must be MP3 files placed
// in the StreamingAssets folder, directly below Assets folder.


// request various game objects to signal us so we know when
// to play or stop playing sound effects

player.OnMove += OnPlayerMove;
player.OnPickup += OnPickupCollected;

// set a flag to play level intro sound effect

intro = true;

// signal the player is walking or stopping.  player walking is
// a state, not a single event, so we set a flag, and let our
// Update() method continuously one of three possible effects.
// note that the code below works the same whether the signal
// is sent every frame, or only when the player state really changes.

void OnPlayerMove(bool walkingOrStopped) {

// walkingOrStopped is true for started walking, false otherwise

if (walkingOrStopped)
walking = true;

else if (walking) {
// player stopped walking, stop sound and clear our flag
walking = false;

// signal that a pickup was collected.  unlike movement,
// this is an event rather than a state change, so we can
// play the pickup effect immediately.  the last parameter,
// 0.5f, controls the volume -- half volume in this case.

void OnPickupCollected() {

AudioPlayer.Play(pickupChannel, "pickup", 0.5f);

// Update method, which we use
// - to manage pause/resume, and sound on/off
// - play level intro sound
// - play continuous sound effects (like walking)

void Update() {

// a frame where timeScale is zero, means the game is paused.
// if it wasn't already paused, let's pause all sound.

if (Time.timeScale == 0f) {

if (! paused) {

paused = true;


if (paused) {

// resuming from pause, and assuming the pause screen
// presents a choice to mute all sounds, which is then
// stored in PlayerPrefs.
// apply the sound on/off flag to the AudioPlayer object,
// then resume all sounds -- which would actually stop all
// sounds if the call to SetSound() disabled all sounds.

AudioPlayer.SetSound(PlayerPrefs.GetInt("sound", 1) != 0);
paused = false;

// if sound is muted, we have nothing further to do

if (! AudioPlayer.GetSound())

// we need to play level intro sound.  this demonstrates that
// sounds are not immediately playable after a call to
// AudioPlayer.Load().
// we have to keep trying to play the sound, and ask AudioPlayer
// if the sound really is playing.  note that this effort is only
// necessary for non-recurring sounds which should play soon
// after the call to AudioPlayer.Load(), so typically this would
// be a level intro sound.

if (intro) {

if (AudioPlayer.IsPlaying(introChannel))
intro = false;
AudioPlayer.Play(introChannel, "intro");

// while the player is walking, which is a continuous state,
// we want to keep playing one of several walking sound
// effects that we have.

if (walking && (! AudioPlayer.IsPlaying(walkChannel))) {

int r = Random.Range(1, 3 + 1);
string clip = "walk" + r.ToString();
AudioPlayer.Play(walkChannel, clip);

API Reference

All methods are static and do not require a reference to the GameObject that contains the AudioPlayer component. They are to be invoked as (for example) AudioPlayer.Play(), as shown in the example above.

bool GetSound()
– Returns true if sound is enabled, false if sound is muted.

void SetSound(bool sound)
– Enables or mutes sound. The Play() method will not begin playing any new sounds while sound is muted. But note that calling SetSound(false) does not pause or stop any currently playing sounds.

void Load(string name)
– Makes a request to load an MP3 sound file from the StreamingAssets directory. This directory should be placed directly below the Assets folder. The .MP3 extension should not be included in this parameter, only the file name. Note that this method call returns before the sound is loaded, and the sound may not be immediately available to play. The example above shows this issue in the context of trying to play a sound at the start of a scene.

void Play(int channel, string name, float volume = 1f, bool loop = false)
– First, this stops the currently playing sound on the specified channel. Then, if sound is not muted, plays the specified sound on the channel. Volume should be a value between 0 and 1. The channel number is a number between 0 and the value set in the NumChannels property of the AudioPlayer component.

void Stop(int channel)
– Stops playing the currently playing sound on the specified channel.

bool IsPlaying(int channel)
– Returns true if sound is currently playing on the specified channel. As noted above, calling SetSound(false) does not stop sounds that are currently playing, so it is possible for this method to return true even after sound has been muted, while any previously-started sounds have not yet finished playing.

void Pause()
– Pauses all channels that are currently playing. It is not recommended to issue calls to Play() after a call to Pause() and before a matching call to Resume().

void Resume()
– Resumes play on all channels that were paused by a previous call to Pause(). Note that if SetSound(false) was called to mute sounds after pausing, then a call to this method will stop, rather than resume, all sounds that were playing prior to calling Pause(). It is not recommended to issue calls to Play() after a call to Pause() and before a matching call to Resume().


Public domain, free to use however you wish.