Archive

Java

This one took a while. Weighing in at 38 versions and I-don’t-know-how-many reflected and hacked APIs, Dashboard is now open-source for all to see. This was probably the app that took the most development time until now (still on-going!), and I think the one I’m most proud of.

I’m liking the idea of doing future releases via self-approved pull requests. Could be interesting!

>>> Dashboard source code <<< 

I’m a big fan of Blinkt light hats for Raspberry Pi. I have one showing me server status, rail delays, and weather conditions.

_20161016_153730

Server down!

I have another at work showing the status of the last link check on our ReadMe.io site.

img_20161117_165458

And now I have one as a dynamic backlight for my new PC build.

img_20161120_135026

And the best part? This last one has an API! It has five modes, powered by a Node.js Express server and the node-blinkt NPM package:

  • /set { "to": [r, g, b] } – Set a color instantly.
  • /fade { "to": [r, g, b] } – Fade from the current colour to this one.
  • ‘CPU’ – Fade to a colour on a HSV scale from green to red depending on current CPU load.
  • ‘Screen’ – Take an average of the four screen corners, and set to that colour ten times a second.
  • ‘Demo’ – Fade to a random colour from the rainbow every 15 seconds.
  • ‘Test’ – Ping the Pi and set the ‘Test’ button to green if it responds ‘OK’ and HTTP 200.

The last three are driven by a Java control panel that permanently lives on the new PC.

controller

Thanks to the motherboard supplying power after the PC turns off, I can use ‘Demo’ as a nightlight! Not that I need one…

A few days ago, an interesting idea came up in the PebbleDev Slack channel: could a library make it easier for Pebble developers to integrate their apps with Android APIs, but save the pain of each and every one of them needing to publish an app with PebbleKit Android? This would be similar to how Dashboard operates, but by sharing the API access to other apps that are installed.

Turns out, it can! In one of my signature coding bursts I set to work, and prototyped a system that did just this. The result is the Dash API. With it, you can finally (and easily) provide one of the most common watchface widget requests – things like the phone’s battery level, or connectivity status.

How does it work?

The Dash API (named after Dashboard) Pebble package uses AppMessage to send requests to read data (such as WiFi network name, or phone battery level), or write to an API (such as turning off WiFi). Using a unique key to recognise Dash API messages, the Android app can respond to these by reading the data or manipulating the Android API and returning a response code. All the developer needs to do is instruct their users to install my Dash API Android app, and then their app (and any others that use the Dash API) can take advantage of the APIs presented through the library. This approach makes the Dash API an install once, use in many apps service.

The upshot of all this is that a C developer making a watchface that wants to show the phone battery level (such as the demo app Dual Gauge) need only use the Pebble package and not write a single line of Java, let alone go to the trouble of publishing an Android app on Google Play.

But how can one companion app target them all, without knowing they exist?

Luckily, you can extract the UUID of an app that sends an AppMessage packet to the phone from the Intent object broadcast from the Pebble Android app. Most (hopefully app) companion apps that manually register a BroadcastReceiver do a ‘good citizen’ UUID check to make sure they only respond to messages from their corresponding watchapp. This data can be used to simply redirect an incoming message’s result right back at it, without the need to create a PebbleKit Android app with baked in UUID for each individual app.

So how can I use it?

Simple. As explained in the GitHub README.md file, a C developer should first install the package:


$ pebble package install pebble-dash-api

Next, include the single library file and call the initialiser when your app is starting, supplying the app’s name (for presentation in the Android app) and an error callback for receiving any errors that may occur:

#include <pebble-dash-api/pebble-dash-api.h>;
#include <pebble-events/pebble-events.h>

#define APP_NAME "My App"

static void error_callback(ErrorCode code) {
  // Receive error codes here
}

static void init() {
  dash_api_init(APP_NAME, error_callback);
  events_app_message_open();

  /* Other init code */
}

Next, check the Android app is available and up to date:

dash_api_check_is_available();

The result will be passed to your error_callback. Once you get ErrorCodeSuccess, it is safe to start making queries, such as getting the battery level, etc. Code examples are included in the GitHub README.md file.

What else do I need to know?

As of 1.1 (released today), apps that read data and API states can do so invisibly. However, apps that wish to write to an API (such as turning off WiFi) will cause a notification to appear that will prompt the user to grant it access within the Dash API app. Once this is done, operation will continue without further intervention, unless permission is revoked. This should hopefully prevent any rogue apps messing with the phone, and give users visibility into which Pebble apps they have used are using the Dash API.

Links

GitHub Repo

Dash API Android app (direct your users here!)

NPM Package

Example App (Dual Gauge)

What’s next?

In the future, I’d like to expand the capabilities offered by the Dash API to other popular widget requests, things such as unread SMS count and next Calendar appointment. Perhaps for another day – coordinating GitHub repos, NPM packages, Android apps, and Pebble apps is quite tiring!

Contrary to popular belief, I do other programming stuff outside of Pebble apps (as well as my other hobby – ignoring app feature requests!). One of these things is a arcade game side project that’s been on-for-a-few-weekends, off-for-a-few-months. Inspired by the sort of rapid-fire indie games my brother and his friends play (Duck Game, Samurai Gunn, Monaco, and recently Ultimate Chicken Horse), I embarked on a project to make a game similar to these that could be played by several friends around a single TV, much like local multiplayer games from my Youth (particularly Worms).

This effort saw me create a basic looping game prototype with Java2D, which began life as a top-down space-themed ship simulator, but didn’t make it very far before switching to the arcade-multiplayer genre I wanted it to become. Soon enough, drawing lots of tiles hit its max potential and so I had to spend a lot of time tearing it apart and replacing Java2D with LWJGL OpenGL for speed. The results were worth the effort, but I’m still left with an incomplete game.

Like many of my programming projects, I work on it less constantly, and more in inspired fits and bursts. So far I have intro sequences, a menu system, a tiled world system with lighting based on a novel pathfinding algorithm, up to four XBox controller support, player sprite animation and collision, and other things. But it’s still incomplete. Until I add weapons, NPCs, effects, and room generation, it’ll stay that way.

But in the meantime, I created lots of very useful sub-components that I really don’t want to have been for nothing, and will probably end up reusing in my own projects. So I decided to pull out the engine, and release it on GitHub as a standalone project that can be run independently of all the other fluff that makes up the game in progress. Importing the code into Eclipse and adding LWJGL.jar (with local libraries and binaries) will let you play around with it and build a game on top of it if you want.

Check out the GitHub repository README.md for a full list of features and how to implement it. Once I have a working prototype of the game, I’ll probably post about that as well. It’s all about the journey, right?

screenshot

blogbanner

It’s here! The redesign I’ve been planning since many months ago (the previous colour watchapp design was a bit of a bodge), and I’ve wanted to add in a few extra features:

  • GSM signal strength
  • Wifi network name
  • Phone free space
  • Resync every 30 seconds while the app is open
  • Option to jump straight to a certain toggle when the app is opened

…and all the usual refactoring (I can’t help myself) and some protocol simplification. Here’s a rule of thumb: if your AppMessage protocol uses arithmetic and nested switch statements, ditch it!

I also improved a lot of the Android code, added fail cases, and more logging etc. to better help me diagnose problems when a user sends me a debug log. Finally, I brought a little animation magic to the UI, and relied more heavily on system UI components instead of over-complicating things by rolling my own version of everything.

Download on Google Play and Pebble appstore!

A feverish evening spent with little else to do resulted in a quick port of my isometric Pebble library to Java Canvas with Graphics2D. Might prove useful for an isometric tile game or such if the mood takes me. There’s something distinctly satisfying about seeing the same results on a different platform.

screenshot

To use, create a context where a Graphics2D object is available, then use static methods of the Isometric class to draw stuff.

public void program(Graphics2D g2d) {
  // Black background
  g2d.setColor(Color.BLACK);
  g2d.fillRect(0, 0, Build.WINDOW_SIZE.width, Build.WINDOW_SIZE.height);

  Isometric.drawRect(g2d, new Vec3(100, 100, 100), new Dimension(100, 100), Color.BLUE);
  Isometric.fillRect(g2d, new Vec3(50, 50, 50), new Dimension(50, 50), Color.RED);

  Isometric.fillBox(g2d, new Vec3(150, 150, 150), new Dimension(25, 25), 25, Color.YELLOW);
  Isometric.drawBox(g2d, new Vec3(150, 150, 150), new Dimension(25, 25), 25, Color.BLACK);
}

You can see all the applicable code on GitHub.

So I’ve had an idea in my head for a while that has probably been done before, but as I’ve already mentioned, I prefer to do everything I can from scratch when it comes to programming, which takes time, but is incredibly rewarding when what I strive for comes to life as I imagined.

This particular idea is for a real-time space RPG, the main mechanic being that you set a course and a speed, and it might take a few real-time minutes to reach your destination, such that you would play the game ongoing in the background for something else you are doing, similar to an MMO.

I’ve attempted this before, and the main difference in having a game world many times larger than the screen is that you must position everything relative to some abstracted co-ordinate system completely separate from where each item may be drawn on the actual screen. This was achieved before by drawing each item if it was less than a screen width or height away from the player’s drawing location in the middle of the screen, then whenever the player moved it’s ‘co-ordinate’, all the other in-game items moved in the opposite direction, very effectively creating the illusion of moving through a world, even though the player’s sprite stays put on the screen.

This feeling was further enhanced by moving the player’s ‘co-ordinate’ using the sin/cosine of the speed and angle, allowing the player to appear to move in large smooth, sweeping arcs.

With my new skills from recent projects still fresh in mind, I set out to make this a much tighter experience, with some more intuitive input system beyond WSAD keyboard keys. I envisaged a speed slider, and a ‘ring slider’ around the player in the center of the screen, allowing a course to be set and speed to be set by dragging them. As everything is done on a Graphics2D enhanced Canvas component, using pre-written Swing sliders is out of the question, so I set out to recreate these UI elements from scratch to be drawn using Graphics2D methods.

The linear slider was fairly easy, using the mouseDragged() method from the MouseMotionListener class. Position the slider where the user clicked (x co-ordinate only!) as long as it was between the slider’s start and finish positions.

So far so good.

But the ‘ring slider’ required much more thinking about. I first attempted to use counters and quadrant detection of the existing angle position of the ring, but this was way too complex. Then as I was thinking about something else, the answer came to me: use GCSE maths! Specifically, the circle trigonometry stuff. It all came down to this: circletheoremSo using the mouse’s dragging x co-ordinate, I can find the corresponding y co-ordinate for that point around the ‘ring slider”scircle. From this, the angle (theta, θ) the slider should be set to can be found using the tangent:

arctanBut this only works up to 90 degrees using tangent (which is actually infinite at 90 degrees), so the calculation is carried out subtly differently depending on which of four quadrant rectangles the user is dragging in, after which the resultant 0 – 90 angle is adjusted to read what it should in the quadrant:

quadrantssrc

Here is the code for calculation of the angle of the ‘ring slider’ in quadrant 0:

//Setup quad rects for ring slider of any bounds x, y, width & height
quad0 = new Rectangle(x + width/2, y, width/2, height/2);
quad1 = new Rectangle(x + width/2, y + height/2, width/2, height/2);
quad2 = new Rectangle(x, y + height/2, width/2, height/2);
quad3 = new Rectangle(x, y, width/2, height/2);

//Test user click - 2x2 rect around mouse pointer location
Rectangle thisRect = new Rectangle(inCurrent.x - 1, inCurrent.y - 1, 2, 2);

//Show angle
if(thisRect.intersects(quad0))
    thisQuad = 0;
else if(thisRect.intersects(quad1))
    thisQuad= 1;
else if(thisRect.intersects(quad2))
    thisQuad = 2;
else if(thisRect.intersects(quad3))
    thisQuad = 3;

switch(thisQuad) {
    case 0: {
        float adj = inCurrent.x - quad0.x;
        float opp = (quad0.y + quad0.height) - inCurrent.y;

        double theta = Math.toDegrees(Math.atan(opp/adj));
        angle = 90 - (int)Math.round(theta);

        //Range control
        if(angle < 0)
            angle = 0;
        if(angle > 90)
            angle = 90;
        break;
    }
    //Then the other quads for cases 1 through 3...
}

The end result of all this, together with a spawning starfield of stars (who move proportionately to their size to create the illusion of depth) is this (Click to enlarge):

inactionI realise that a simple image isn’t that exciting, so if you want to play around with these UI elements and see the whole demo in action, here is an executable bundle!

The last couple of weeks I haven’t been posting anything interesting, mainly due to a new project I’m spending a lot of time on, which is very exciting. I’m working with a friend to create an open-world RPG basically from scratch, and working on it has given me lots of opportunity to problem-solve, develop my coding practices and go to new places I wouldn’t have gone otherwise.

A summary of highlights so far, which I may cover in separate detail posts are:

  • Triple threaded engine (Logic, Renderer, Occlusion) using Java2D
  • Tile based maps with three layers loaded by a tile sheet parser that splits up a single image of tiles into single sprites for use by each map tile.
  • Any-size maps with aggressive occlusion (drawing only those tiles that need to be), enabling smooth 60 FPS motion even at 1920 x 1080.
  • Animated Player and NPCs that similarly have their animation frames dynamically loaded from external sprite sheets composed of individual frames.
  • Thread driven scripts and events using a bespoke language that are interpreted and acted upon at run-time.
  • Map files are read into a bundle that then exposes it’s data to the game, ensuring only the correct data is available, and the game cannot accidentally corrupt a map file.
  • A dedicated map maker package that enables creation of these maps, adding events, NPCs and map-to-map jumps.

Stay tuned for more information!

In developing the GClient (detailed in the preceeding post), I discovered for myself that the method to be implemented for some interfaces and object types (such as run() in a Runnable object) are done by declaring them as ‘abstract’ methods. This means when a programmer creates a new instance of that object, the abstract method that needs to be implemented is shown to be ‘filled up’ with context specific code. Below is an example:

This is an abstract method from my ‘PythonConnection’ class:


/**
  * Implement this to act on data received
  * @param data String containing the data received from the remote python host
  */
	public abstract void onReceive(String data);

When a new PythonConnection object is created, the opportunity to implement onReceive() is shown as below:


PythonConnection pyCon = new PythonConnection() {

			@Override
			public void onReceive(String data) {
				//Put code to use the 'data' String here!
				//Update UI, send a response etc...

			}
		};

Where does the ‘data’ String come from, you ask? Well when the underlying Thread receives data from the BufferedReader, it calls onReceive(), supplying the String read from the Reader and continues listening once onReceive() returns. Here is where that occurs in a typical server (such as in the GClient):


/**
  * Start the receiving thread that will call onReceive() when it has data
  */
	private void startListening() {

		receiveThread = new Thread(new Runnable() {

			@Override
			public void run() {
				listening = true;
				System.out.println("Ready to receive.");

				while(listening) {
					try {
						String packet = fromPython.readLine();
						if(packet != null) {
							onReceive(packet);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		});

		receiveThread.start();
	}

Previously to get around this ‘sending data across classes’ problem (which got especially nasty when Threads came into it) I would either pass the object creating the abstract object or use some sort of ‘shared static class’, which wasn’t ideal and generated problems of its own.

This is an example of one of the joys of exploring a language by using it! I foresee much use for this functionality.

GClientLOgoWhile developing a number of different minor projects that involved communication between Android and my laptop, Pebble or Raspberry Pi I found myself almost writing a new app for each project, with names like ‘PebbleButtonDemo’ or ‘AndroidTestClient’.

It occurred to me ‘why keep inventing the wheel?’, meaning that this was a wasted practice. The vast majority of these situations simply called for a TCP Socket connection that sent pre-defined commands as text strings. With that in mind, I conspired to create a general purpose app that did these things and did them well.

But in order to solve the problem of writing a new app for every application when the underlying mechanism remained the same, it needed more ‘customisability’ than simply an EditText for address and port. The next logical step to this is to allow each project/application (server, that is) to customize the general client on the Android phone to it’s purpose, and in this first incarnation offers the following ‘customisables’:

  • Android Activity title in the Action bar by sending “TITLE” + the new title String
  • A set of three customizable Buttons by sending ‘BUTTON” followed by the button number, button text and the command it should trigger to be sent back to the application server.
  • Protocols agreed for these actions in both Java and Python servers I’ve written.

More features are possible with a more advanced protocol, such as sending vectors to draw on the remote Canvas, or even images, but those will have to come later when a specific project calls for it.

So, upon opening the app, this is what is seen:

Screenshot_2013-07-25-22-37-13The key UI elements to note are:

  • The customizable Activity title.
  • The ‘I/O Traffic’ section, which contains a customized SurfaceView element (actually a subclass of my Android Game Engine), which fills up green when a connection is established and animates blue ‘bits’ left and right whenever data is sent or received.
  • The ‘Connection Settings’ section, which contains EditText fields for host address and port number, a Spinner for language selection on the application server side, and connect/disconnect Buttons.
  • The ‘Log History’ section contains a ScrollView housing a TextView that shows all events that take place, be they received data, sent commands or local events such as IOExceptions and disconnects.
  • The ‘Custom Buttons’ section, which houses the three customizable Buttons that can be setup from the application server side with details I’ll now detail below.

To continue the spirit of a general purpose app, I created static methods for setting up these customizable UI elements, shown below:

public class GClientTools {
	//Protocol configuration
	private static final String PROTOCOL_TITLE = "TITLE";
	private static final String PROTOCOL_BUTTON = "BUTTON";
	private static final String PROTOCOL_SEP_1 = ":";
	private static final String PROTOCOL_SEP_2 = ";";
	private static final String PROTOCOL_SEP_3 = ".";

	/**
	 * Use the GClient syntax to set the GClient Activity title
	 * @param inStream 	Established output stream.
	 * @param inTitle	Title to set to.
	 */
	public static void setTitle(PrintStream inStream,String inTitle) {
		String packet = PROTOCOL_TITLE + PROTOCOL_SEP_1 + inTitle;
		inStream.println(packet);
		System.out.println("Title now '" + inTitle + "'. (" + packet + ")");
	}

	/**
	 * Configure a GClient custom button
	 * @param inStream		Established output stream.
	 * @param inButtonNumber	Which button to customise. No range checking.
	 * @param inText		Text to display on the button.
	 * @param inCommand		Command the button will send back to this server.
	 */
	public static void setCustomButton(PrintStream inStream, int inButtonNumber, String inText, String inCommand) {
		String packet = PROTOCOL_BUTTON + PROTOCOL_SEP_1 + inButtonNumber + PROTOCOL_SEP_2 + inText + PROTOCOL_SEP_3 + inCommand;
		inStream.println(packet);
		System.out.println("Button " + inButtonNumber + " now '" + inText + "' --> <" + inCommand + ">. (" + packet + ")");
	}

}

As a test case, I wrote a quick application server that accepts the GClient connection and makes use of these static methods to set the Activity title and one custom Button. The I/O Traffic bar has filled up green and the Log History shows all events:

Screenshot_2013-07-25-22-36-50That’s it for now. The major things I learned writing this app were:

  • A much more stable and UI friendly threaded approach to networking, using four threads (UI, sending, receiving and connecting)
  • Precise Android XML UI design including nested layouts and more features of the RelativeLayout.
  • Setting Android UI views to use 9-Patch images and custom background styles and colours.

First version source code is available here! The GClientTestServer port is a constant field in the class file. The GClientTestServer also contains the GClientTools class in the util package, which I’ll be next using for adapting current project servers and eliminating a few test apps altogether!