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!