Commits

Anonymous committed a5d3b6c Draft

Removed other watch faces written by Trammel Hudson. To view his other watch faces go to https://bitbucket.org/hudson/pebble

Comments (0)

Files changed (83)

.hgignore

-syntax: glob
-*/include
-*/lib
-*/pebble_app.ld
-*/resources/wscript
-*/tools
-*/waf
-*/wscript
-*/.lock-waf_darwin_build
-*/.waf*
-*/build
-*.swp
-*.pfo
-*.orig
-*.bin
-*.elf
-*.pbw
-*.o
-.*.o.d
-resource_ids.auto.h
-app_resources.pbpack*
-*.log
-*.map

.hgtags

-dc01cb57c35db5de2a518d61dccc0ed28af2b3b5 makefile-works
-0772e0fc674ce4418228827c51df65037864b2ab qlock2-clone
-29fb3fabe7af1023a36bb1a9235c52e2768d94fe before-release-001-b1

Makefile

-DIRS += lib
-DIRS += hoelaat
-DIRS += auth
-DIRS += mario
-DIRS += words
-DIRS += cst
-DIRS += calendar
-DIRS += interval
-DIRS += worldmap
-DIRS += timezones
-
-all: $(DIRS)
-
-$(DIRS): FORCE
-	$(MAKE) -C $@/src
-
-clean:
-	for dir in $(DIRS); do \
-		$(MAKE) -C $$dir/src clean; \
-	done
-
-FORCE:

Makefile.pebble

-#
-# Makefile for Pebble watch projects.
-#
-# The makefile should define:
-# 	SRCS with a list of source files.
-#	APP := project to build
-#	FONTS := list of fonts to bundle
-#	IMAGES := list of images to bundle
-#
-# Change PEBBLE_HOME to point to the sdk directory
-# and GCC_PREFIX to point to your arm-none-eabi gcc tree.
-# Otherwise it should "just work".
-#
-
-# TOP is the location with of this build tree
-TOP := $(dir $(lastword $(MAKEFILE_LIST)))
--include $(TOP)/Makefile.config
-
-# If Makefile.config does not define these, use defaults paths.
-PEBBLE_HOME ?= $(HOME)/build/pebble/pebble-sdk-release-001/sdk
-ARM_GCC_PATH ?= $(HOME)/arm-cs-tools/bin
-
-GCC_PREFIX := $(ARM_GCC_PATH)/arm-none-eabi-
-export PATH := $(ARM_GCC_PATH):$(PATH)
-
-CC := $(GCC_PREFIX)gcc
-LD := $(CC)
-OBJCOPY := $(GCC_PREFIX)objcopy
-SIZE := $(GCC_PREFIX)size
-AR := $(GCC_PREFIX)ar
-PYTHON := python
-
-# If no version is specified, use a default one
-VERSION ?= 0.1
-APP ?= pebble-app
-
-# Our custom Pebble library shared with all our watch faces
-LIBPEBBLE_TH := $(TOP)lib/build/libpebble_th.a
-
-# Disable any localization; otherwise tr might complain
-override LANG := C
-
-
-# Helper macros
-map = $(foreach f,$2,$(call $1,$f))
-uppercase = $(shell echo $1 | tr -- '-.[:lower:]' '__[:upper:]')
-ucfile = $(call uppercase,$(basename $(notdir $1)))
-
-
-#
-# If no output directory is specified, put things into ../build/
-#
-O ?= ../build
-$(eval $(shell mkdir -p $O/src))
-
-ARCH_FLAGS += \
-	-mcpu=cortex-m3 \
-	-mthumb \
-
-CFLAGS += \
-	-std=c99 \
-	$(ARCH_FLAGS) \
-	-g \
-	-O0 \
-	-Wall \
-	-Wextra \
-	-Wno-error=unused-function \
-	-Wno-error=unused-variable \
-	-Wno-error=unused-parameter \
-	-fPIE \
-	-I$(PEBBLE_HOME)/include \
-	-I. \
-	-I../../lib/src \
-	-I$O \
-	-DNDEBUG \
-	-Wp,-MMD,$(dir $@).$(notdir $@).d \
-        -Wp,-MT,$@ \
-
-
-LDFLAGS += \
-	$(ARCH_FLAGS) \
-	-Wl,--warn-common \
-	-fPIE \
-	-Wl,-Map,$@.map,--emit-relocs \
-	-T$(PEBBLE_HOME)/pebble_app.ld \
-
-LDLIBS += \
-	-L$(PEBBLE_HOME)/lib \
-	-lpebble \
-
-BUILD_TIME := $(shell date "+%s")
-
-ifeq ($(LIB),)
-# Force all executables to depend on our pebble library
-all: $O/$(APP).pbw
-else
-# Libraries do not depend on anything external
-all: $O/$(LIB)
-endif
-
-
-#
-# Convert the elf file to a binary file, with
-# the appended Pebble metadata.
-#
-$O/pebble-app.bin: $O/pebble-app.elf
-	$(OBJCOPY) -O binary $< $@
-	$(PYTHON) $(PEBBLE_HOME)/waftools/inject_metadata.py $@
-
-# 
-# Bundle the binary (with pebble meta data) into an application.
-#
-
-# Final step to link everything into the PBW file
-$O/$(APP).pbw: $O/pebble-app.bin
-	$(PYTHON) $(PEBBLE_HOME)/tools/mkbundle.py \
-		--watchapp $< \
-		--watchapp-timestamp $(BUILD_TIME) \
-		--req-fw 1 \
-		--resources $O/app_resources.pbpack \
-		--resource-map $O/resource_map.json \
-		--resources-timestamp $(BUILD_TIME) \
-		-o $@ \
-		-v \
-
-
-
-#
-# Generate the list of object files from the SRCS list.
-# Every object requires that the resource_ids.auto.h be up to date
-#
-OBJS :=
-add_srcs = \
-	$(eval $2: $1) \
-	$(eval OBJS += $2) \
-
-$(foreach f,$(SRCS),$(call add_srcs,$f,$O/$(notdir $(f:.c=.o))))
-OBJS := $(strip $(OBJS))
-
-ifeq ($(LIB),)
-# Only build resource_ids.auto.h if we are making an application
-$(OBJS): $O/src/resource_ids.auto.h
-
-$O/$(APP).pbw: $O/app_resources.pbpack
-$O/pebble-app.elf: $(OBJS) $(LIBPEBBLE_TH)
-	$(LD) \
-		$(LDFLAGS) \
-		-o $@ \
-		$^ \
-		$(LDLIBS)
-	$(SIZE) $@
-
-$(LIBPEBBLE_TH):
-	$(MAKE) -C $(TOP)/lib/src
-
-else
-# Libraries do not use resources, but do need to link everything together
-$O/$(LIB): $(OBJS)
-	$(RM) $@
-	$(AR) \
-		crv \
-		$@ \
-		$^
-	$(SIZE) $@
-endif
-
-$O/%.o:
-	$(CC) \
-		$(CFLAGS) \
-		-c \
-		-o $@ \
-		$<
-
-
-# Generate a fake resource_map.json file
-$O/resource_map.json:
-	echo > $@ \
-		'{"friendlyVersion":"'$(VERSION)'","versionDefName":"RESOURCES"}'
-
-
-clean:
-	$(RM) \
-		$O/*.{o,a,pbw,pfo,pbi,elf,bin,map} \
-		a.out \
-		core \
-		$O/*.pbpack \
-		$O/*.pbpack.* \
-		$O/src/resource_ids.auto.h \
-
-#
-# Generate a font resource from a given ttf.
-# The fonts are specified in the leaf makefiles in $(FONT) as a list of:
-#
-#	path-to-font:size
-#
-# For example:
-#
-#	FONTS := fonts/Arial.ttf:28 fonts/Arial-Black.ttf:30
-#
-# This will produce resources named FONT_ARIAL_28 and FONT_ARIAL_BLACK_30.
-#
-# A somewhat complex make rule translates this list into the
-# targets for each font to be generated and as well as the
-# resource list to pass into the make bundle tool.
-#
-
-$O/%.pfo:
-	$(PYTHON) $(PEBBLE_HOME)/tools/font/fontgen.py \
-		pfo \
-		$(subst .,,$(suffix $(basename $@))) \
-		$< \
-		$@ \
-
-mkfont_rules = \
-	$(eval F := $(word 1,$1)) \
-	$(eval S := $(word 2,$1)) \
-	$(eval N := FONT_$(call ucfile,$F)_$S) \
-	$(eval R := $O/$N.$S.pfo) \
-	$(eval $R: $F) \
-	$(eval RESOURCES += $R) \
-	$(eval RESOURCE_LIST += $R $N) \
-
-mkfont = \
-	$(call mkfont_rules,$(subst :, ,$1)) \
-
-$(eval $(call map,mkfont,$(FONTS)))
-
-#
-# Images are converted to pbi format
-# If ":white" or ":black" are included, generate separate
-# resources for the two of them.
-#
-$O/%_white.pbi:
-	$(PYTHON) $(PEBBLE_HOME)/tools/bitmapgen.py \
-		white_trans_pbi \
-		$< \
-		$@ \
-
-$O/%_black.pbi:
-	$(PYTHON) $(PEBBLE_HOME)/tools/bitmapgen.py \
-		black_trans_pbi \
-		$< \
-		$@ \
-
-$O/%.pbi:
-	$(PYTHON) $(PEBBLE_HOME)/tools/bitmapgen.py \
-		pbi \
-		$< \
-		$@ \
-
-
-mkimage_rules = \
-	$(eval F := $(word 1,$1)) \
-	$(eval T := $(word 2,$1)) \
-	$(eval T := $(if $T,_$T,)) \
-	$(eval N := IMAGE_$(call ucfile,$F)$(call uppercase,$T)) \
-	$(eval R := $O/$N$T.pbi) \
-	$(eval $R: $F) \
-	$(eval RESOURCES += $R) \
-	$(eval RESOURCE_LIST += $R $N) \
-
-mkimage = \
-	$(call mkimage_rules,$(subst :, ,$1)) \
-
-$(eval $(call map,mkimage,$(IMAGES)))
-
-
-#
-# Generate the list of all resources from the fonts, images and
-# the resource map file.
-# \todo Images.
-#
-RESOURCES += $O/resource_map.json
-RESOURCE_LIST += $O/resource_map.json DUMMY
-
-#
-# Generate a resource binary from all of the fonts
-#
-$O/app_resources.pbpack: \
-	$O/app_resources.pbpack.manifest \
-	$O/app_resources.pbpack.table \
-	$O/app_resources.pbpack.data \
-
-	cat > $@ $^
-
-$O/app_resources.pbpack.data: $(RESOURCES)
-	cat > $@ $^
-
-$O/app_resources.pbpack.table: $(RESOURCES)
-	$(PYTHON) $(PEBBLE_HOME)/tools/pbpack_meta_data.py \
-		table \
-		$@ \
-		$^ \
-
-$O/%.manifest: $O/%.data
-	$(PYTHON) $(PEBBLE_HOME)/tools/pbpack_meta_data.py \
-		manifest \
-		$@ \
-		$(words $(RESOURCES)) \
-		$(BUILD_TIME) \
-		$(VERSION) \
-		$< \
-
-#
-# This header file name is forced by <pebble_app.h>.
-# Put it into the output build directory so that it does not
-# clutter the input source tree.
-#
-$O/src/resource_ids.auto.h: \
-	$O/app_resources.pbpack.data \
-	$(RESOURCES) \
-
-	$(PYTHON) $(PEBBLE_HOME)/tools/generate_resource_code.py \
-		resource_header \
-		$@ \
-		RESOURCES \
-		$(VERSION) \
-		$(BUILD_TIME) \
-		pebble_os.h \
-		$< \
-		$(RESOURCE_LIST) \
-
-#
-# Bring in all of the generated dependency files if any exist.
-# These are produced by the -MMD flag to gcc in $(CFLAGS).
-# If they do not exist, do not create a target for them.
-#
-$O/.*.o.d:
-	@true
--include $O/.*.o.d
-
-#
-# Start a web server in the .. directory
-#
-httpd:
-	cd ../.. ; $(PYTHON) -mSimpleHTTPServer

accel/src/Makefile

-#
-# Accelerometer demo
-#
-
-APP := accel
-
-SRCS += accel.c
-
-include ../../Makefile.pebble

accel/src/README

-This one doesn't work -- the accelerometer API doesn't work yet.

accel/src/accel.c

-/** \file
- * Show off the 3D accelerometer data.
- */
-#include "pebble_os.h"
-#include "pebble_app.h"
-#include "pebble_fonts.h"
-
-PBL_APP_INFO(
-	"Accelerometer",
-	"hudson",
-	1, // Version
-	INVALID_RESOURCE,
-	APP_INFO_WATCH_FACE
-);
-
-
-static Window window;
-static TextLayer time_layer;
-static Layer layer;
-
-static void
-bargraph_layer_update(
-	Layer * const me,
-	GContext * ctx
-)
-{
-/*
-	// Draw a white rectangle across the entire bottom
-	const unsigned w = me->bounds.size.w;
-	const unsigned h = me->bounds.size.h;
-	graphics_context_set_fill_color(ctx, GColorWhite);
-	graphics_fill_rect(ctx, GRect(0, 0, w, h), 0, GCornersAll);
-
-	graphics_context_set_fill_color(ctx, GColorBlack);
-	graphics_fill_rect(ctx, GRect(0, 0, (w * remaining) / 30, h), 4, GCornersRight);
-*/
-}
-
-
-static unsigned
-fmt_i16(
-	char * buf,
-	int16_t v_in
-)
-{
-	uint16_t v = v_in;
-
-	if (v_in < 0)
-	{
-		buf[0] = '-';
-		v = -v_in;
-	} else
-	if (v_in > 0)
-		buf[0] = '+';
-	else
-		buf[0] = ' ';
-
-	buf[5] = '0' + v % 10; v /= 10;
-	buf[4] = '0' + v % 10; v /= 10;
-	buf[3] = '0' + v % 10; v /= 10;
-	buf[2] = '0' + v % 10; v /= 10;
-	buf[1] = '0' + v % 10;
-
-	return 6;
-}
-
-
-static void
-handle_tick(
-	AppContextRef ctx,
-	PebbleTickEvent * const event
-)
-{
-	(void) ctx;
-	const PblTm * const ptm = event->tick_time;
-	static char time_buffer[32];
-	unsigned off = 0;
-
-	struct AccelData accel = { 12345, 9999, -9999 };
-	accel_get_xyz(&accel);
-	off += fmt_i16(time_buffer + off, accel.x);
-	time_buffer[off++] = '\n';
-	off += fmt_i16(time_buffer + off, accel.y);
-	time_buffer[off++] = '\n';
-	off += fmt_i16(time_buffer + off, accel.z);
-	time_buffer[off++] = '\n';
-
-	string_format_time(
-		time_buffer + off,
-		sizeof(time_buffer) - off,
-		"%H:%M:%S",
-		ptm
-	);
-
-	text_layer_set_text(&time_layer, time_buffer);
-}
-
-
-static void
-handle_init(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	window_init(&window, "Main");
-	window_stack_push(&window, true);
-
-	text_layer_init(&time_layer, GRect(0,0,144,168));
-	text_layer_set_text(&time_layer, "");
-	text_layer_set_font(&time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18));
-	layer_add_child(&window.layer, &time_layer.layer);
-
-/*
-	// Bargraph layer is across the bottom
-	const unsigned bargraph_height = 20;
-	layer_init(&bargraph_layer, GRect(0,168-bargraph_height-15,144,bargraph_height));
-	bargraph_layer.update_proc = bargraph_layer_update;
-
-	layer_add_child(&window.layer, &bargraph_layer);
-*/
-}
-
-
-void
-pbl_main(
-	void * const params
-)
-{
-	PebbleAppHandlers handlers = {
-		.init_handler	= &handle_init,
-		.tick_info	= {
-			.tick_handler = &handle_tick,
-			.tick_units = SECOND_UNIT,
-		},
-	};
-
-	app_event_loop(params, &handlers);
-}

auth/README

-***** WARNING: DO NOT CHECKIN src/otp.do-not-checkin *****
-
-This is the Google Two Factor authentication watch.  It displays
-the current time and a one-time password that is valid for thirty
-seconds.
-
-\todo: Write instructions for generating OTP from QR code.
-
-***** WARNING: DO NOT CHECKIN src/otp.do-not-checkin *****

auth/src/Makefile

-#
-# Google two-factor authentication
-#
-
-APP := auth
-
-SRCS += sha1.c
-SRCS += totp.c
-
-include ../../Makefile.pebble

auth/src/secret2otp

-#!/usr/bin/python
-import sys
-import base64
-
-raw = base64.b32decode(sys.argv[1].upper())
-bytes = [hex(ord(i)) for i in raw]
-
-print '/* DO NOT CHECK IN THIS GENERATED FILE */'
-print ', '.join(bytes)

auth/src/sha1.c

-#include <string.h>
-#include "sha1.h"
-
-#define HASH_LENGTH 20
-#define BLOCK_LENGTH 64
-
-typedef union
-{
-  uint8_t b[BLOCK_LENGTH];
-  uint32_t w[BLOCK_LENGTH/4];
-} _buffer;
-typedef union {
-  uint8_t b[HASH_LENGTH];
-  uint32_t w[HASH_LENGTH/4];
-} _state;
-
-static _buffer buffer;
-static uint8_t bufferOffset;
-static _state state;
-static uint32_t byteCount;
-static uint8_t keyBuffer[BLOCK_LENGTH];
-static uint8_t innerHash[HASH_LENGTH];
-    
-#define SHA1_K0 0x5a827999
-#define SHA1_K20 0x6ed9eba1
-#define SHA1_K40 0x8f1bbcdc
-#define SHA1_K60 0xca62c1d6
-
-static const uint8_t sha1InitState[] = {
-  0x01,0x23,0x45,0x67, // H0
-  0x89,0xab,0xcd,0xef, // H1
-  0xfe,0xdc,0xba,0x98, // H2
-  0x76,0x54,0x32,0x10, // H3
-  0xf0,0xe1,0xd2,0xc3  // H4
-};
-
-static void sha1_init(void) {
-  memcpy(state.b,sha1InitState,HASH_LENGTH);
-  byteCount = 0;
-  bufferOffset = 0;
-}
-
-static uint32_t sha1_rol32(uint32_t number, uint8_t bits) {
-  return ((number << bits) | (number >> (32-bits)));
-}
-
-static void sha1_hashBlock() {
-  uint8_t i;
-  uint32_t a,b,c,d,e,t;
-
-  a=state.w[0];
-  b=state.w[1];
-  c=state.w[2];
-  d=state.w[3];
-  e=state.w[4];
-  for (i=0; i<80; i++) {
-    if (i>=16) {
-      t = buffer.w[(i+13)&15] ^ buffer.w[(i+8)&15] ^ buffer.w[(i+2)&15] ^ buffer.w[i&15];
-      buffer.w[i&15] = sha1_rol32(t,1);
-    }
-    if (i<20) {
-      t = (d ^ (b & (c ^ d))) + SHA1_K0;
-    } else if (i<40) {
-      t = (b ^ c ^ d) + SHA1_K20;
-    } else if (i<60) {
-      t = ((b & c) | (d & (b | c))) + SHA1_K40;
-    } else {
-      t = (b ^ c ^ d) + SHA1_K60;
-    }
-    t+=sha1_rol32(a,5) + e + buffer.w[i&15];
-    e=d;
-    d=c;
-    c=sha1_rol32(b,30);
-    b=a;
-    a=t;
-  }
-  state.w[0] += a;
-  state.w[1] += b;
-  state.w[2] += c;
-  state.w[3] += d;
-  state.w[4] += e;
-}
-
-void sha1_addUncounted(uint8_t data) {
-  buffer.b[bufferOffset ^ 3] = data;
-  bufferOffset++;
-  if (bufferOffset == BLOCK_LENGTH) {
-    sha1_hashBlock();
-    bufferOffset = 0;
-  }
-}
-
-void sha1_write(uint8_t data) {
-  ++byteCount;
-  sha1_addUncounted(data);
-}
-
-void sha1_writebytes(const uint8_t* data, int length) {
- for (int i=0; i<length; i++)
- {
-   sha1_write(data[i]);
- }
-}
-
-void sha1_pad() {
-  // Implement SHA-1 padding (fips180-2 §5.1.1)
-
-  // Pad with 0x80 followed by 0x00 until the end of the block
-  sha1_addUncounted(0x80);
-  while (bufferOffset != 56) sha1_addUncounted(0x00);
-
-  // Append length in the last 8 bytes
-  sha1_addUncounted(0); // We're only using 32 bit lengths
-  sha1_addUncounted(0); // But SHA-1 supports 64 bit lengths
-  sha1_addUncounted(0); // So zero pad the top bits
-  sha1_addUncounted(byteCount >> 29); // Shifting to multiply by 8
-  sha1_addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as
-  sha1_addUncounted(byteCount >> 13); // byte.
-  sha1_addUncounted(byteCount >> 5);
-  sha1_addUncounted(byteCount << 3);
-}
-
-
-uint8_t* sha1_result(void) {
-  // Pad to complete the last block
-  sha1_pad();
-  
-  // Swap byte order back
-  for (int i=0; i<5; i++) {
-    uint32_t a,b;
-    a=state.w[i];
-    b=a<<24;
-    b|=(a<<8) & 0x00ff0000;
-    b|=(a>>8) & 0x0000ff00;
-    b|=a>>24;
-    state.w[i]=b;
-  }
-  
-  // Return pointer to hash (20 characters)
-  return state.b;
-}
-
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5c
-
-void sha1_initHmac(const uint8_t* key, int keyLength) {
-  uint8_t i;
-  memset(keyBuffer,0,BLOCK_LENGTH);
-  if (keyLength > BLOCK_LENGTH) {
-    // Hash long keys
-    sha1_init();
-    for (;keyLength--;) sha1_write(*key++);
-    memcpy(keyBuffer,sha1_result(),HASH_LENGTH);
-  } else {
-    // Block length keys are used as is
-    memcpy(keyBuffer,key,keyLength);
-  }
-  // Start inner hash
-  sha1_init();
-  for (i=0; i<BLOCK_LENGTH; i++) {
-    sha1_write(keyBuffer[i] ^ HMAC_IPAD);
-  }
-}
-
-uint8_t* sha1_resultHmac(void) {
-  uint8_t i;
-  // Complete inner hash
-  memcpy(innerHash,sha1_result(),HASH_LENGTH);
-  // Calculate outer hash
-  sha1_init();
-  for (i=0; i<BLOCK_LENGTH; i++) sha1_write(keyBuffer[i] ^ HMAC_OPAD);
-  for (i=0; i<HASH_LENGTH; i++) sha1_write(innerHash[i]);
-  return sha1_result();
-}
-
-
-static const uint8_t hmacKey1[] = {
-// Generate your key from the QR code and base32 decoding the value
-#include "otp.do-not-checkin"
-};
-
-
-/** C function to do oauth computation */
-uint32_t
-oauth_calc(
-	uint32_t unix_epoch
-)
-{
-	const uint32_t now = unix_epoch / 30;
-
-	uint8_t byteArray[] = {
-		0,
-		0,
-		0,
-		0,
-		now >> 24,
-		now >> 16,
-		now >>  8,
-		now >>  0,
-	};
-
-	sha1_initHmac(hmacKey1,sizeof(hmacKey1));
-	sha1_writebytes(byteArray, 8);
-	const uint8_t * const hash = sha1_resultHmac();
-  
-	const unsigned offset = hash[20 - 1] & 0xF; 
-	uint32_t truncatedHash = 0;
-	for (int j = 0; j < 4; ++j) {
-		truncatedHash <<= 8;
-		truncatedHash  |= hash[offset + j];
-	}
-    
-	truncatedHash &= 0x7FFFFFFF;
-	truncatedHash %= 1000000;
-
-	return truncatedHash;
-}

auth/src/sha1.h

-#ifndef Sha1_h
-#define Sha1_h
-
-#include <sys/types.h>
-#include <inttypes.h>
-
-uint32_t oauth_calc(uint32_t unix_epoch);
-
-#endif

auth/src/totp.c

-/** \file
- * Google Two Factor authentication watch face.
- *
- * You must set GMT_OFFSET for your local timezone!
- * -5 == NYC.
- */
-#include "pebble_os.h"
-#include "pebble_app.h"
-#include "pebble_fonts.h"
-#include "pebble_th.h"
-#include "sha1.h"
-
-#define GMT_OFFSET -5
-
-#define UUID {0x24, 0x15, 0x2D, 0xAE, 0xDD, 0x49, 0x47, 0x47, 0x96, 0xD5, 0x78, 0xB1, 0xDD, 0xBD, 0x1B, 0xB2}
-
-PBL_APP_INFO(
-	UUID,
-	"2wo Factor",
-	"hudson",
-	2, 0, // Version
-	INVALID_RESOURCE,
-	APP_INFO_WATCH_FACE
-);
-
-
-static char time_buffer[32];
-static char otp_buffer[32];
-static Window window;
-static TextLayer time_layer;
-static TextLayer otp_layer;
-static Layer bargraph_layer;
-static uint32_t remaining;
-static unsigned old_half;
-
-static void
-bargraph_layer_update(
-	Layer * const me,
-	GContext * ctx
-)
-{
-	// Draw a white rectangle across the entire bottom
-	const unsigned w = me->bounds.size.w;
-	const unsigned h = me->bounds.size.h;
-	graphics_context_set_fill_color(ctx, GColorWhite);
-	graphics_fill_rect(ctx, GRect(0, 0, w, h), 0, GCornersAll);
-
-	graphics_context_set_fill_color(ctx, GColorBlack);
-	graphics_fill_rect(ctx, GRect(0, 0, (w * remaining) / 30, h), 4, GCornersRight);
-}
-
-
-static void
-handle_tick(
-	AppContextRef ctx,
-	PebbleTickEvent * const event
-)
-{
-	(void) ctx;
-	const PblTm * const ptm = event->tick_time;
-
-	// Only recompute and update if we have a new time step
-	remaining = 30 - (ptm->tm_sec % 30);
-	layer_mark_dirty(&bargraph_layer);
-
-	unsigned new_half = ptm->tm_sec > 30;
-	if (new_half == old_half)
-		return;
-	old_half = new_half;
-
-	string_format_time(
-		time_buffer,
-		sizeof(time_buffer),
-		"%H:%M",
-		event->tick_time
-	);
-	text_layer_set_text(&time_layer, time_buffer);
-
-	// Convert the time into a unix epoch time based on our local time.
-	// this should be done in a library
-	const uint32_t now = unix_epoch_time(ptm, 3600 * GMT_OFFSET);
-	uint32_t auth = oauth_calc(now);
-
-	otp_buffer[6] = '\0';
-	otp_buffer[5] = '0' + auth % 10; auth /= 10;
-	otp_buffer[4] = '0' + auth % 10; auth /= 10;
-	otp_buffer[3] = '0' + auth % 10; auth /= 10;
-	otp_buffer[2] = '0' + auth % 10; auth /= 10;
-	otp_buffer[1] = '0' + auth % 10; auth /= 10;
-	otp_buffer[0] = '0' + auth % 10; auth /= 10;
-	text_layer_set_text(&otp_layer, otp_buffer);
-}
-
-
-static void
-handle_init(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	// Store an invalid value in the old_half so that we will
-	// be forced to recompute the current hash
-	old_half = 999;
-
-	window_init(&window, "RFC 6238");
-	window_stack_push(&window, true);
-
-	text_layer_init(&time_layer, GRect(22,10,144-24,50));
-	time_buffer[0] = '\0';
-	text_layer_set_text(&time_layer, time_buffer);
-	text_layer_set_font(&time_layer, fonts_get_system_font(FONT_KEY_GOTHAM_42_BOLD));
-	layer_add_child(&window.layer, &time_layer.layer);
-
-	text_layer_init(&otp_layer, GRect(13,70,144-13,40));
-	text_layer_set_font(&otp_layer, fonts_get_system_font(FONT_KEY_GOTHAM_30_BLACK));
-	otp_buffer[0] = '\0';
-	text_layer_set_text(&otp_layer, otp_buffer);
-	layer_add_child(&window.layer, &otp_layer.layer);
-
-	// Bargraph layer is across the bottom
-	const unsigned bargraph_height = 20;
-	layer_init(&bargraph_layer, GRect(0,168-bargraph_height-15,144,bargraph_height));
-	bargraph_layer.update_proc = bargraph_layer_update;
-
-	layer_add_child(&window.layer, &bargraph_layer);
-}
-
-
-void
-pbl_main(
-	void * const params
-)
-{
-	PebbleAppHandlers handlers = {
-		.init_handler	= &handle_init,
-		.tick_info	= {
-			.tick_handler = &handle_tick,
-			.tick_units = SECOND_UNIT,
-		},
-	};
-
-	app_event_loop(params, &handlers);
-}

calendar/src/Makefile

-APP := calendar
-
-SRCS += main.c
-
-FONTS := \
-	fonts/SourceCodePro-Light.otf:16 \
-	fonts/SourceCodePro-Light.otf:20 \
-
-IMAGES := \
-	images/menu_icon.png \
-
-include ../../Makefile.pebble

calendar/src/fonts/SourceCodePro-Black.otf

-../../../words/src/fonts/SourceCodePro-Black.otf

calendar/src/fonts/SourceCodePro-Light.otf

-../../../words/src/fonts/SourceCodePro-Light.otf

calendar/src/images/menu_icon.png

Removed
Old image

calendar/src/main.c

-/** \file
- * Calendar clock
- */
-#include <pebble_os.h>
-#include <pebble_app.h>
-#include <pebble_fonts.h>
-
-
-#define UUID {0xA4, 0x8B, 0x43, 0x03, 0xFA, 0x4F, 0x4F, 0xF2, 0xBB, 0x49, 0x3E, 0xA2, 0x38, 0x91, 0x57, 0xE0}
-
-PBL_APP_INFO(
-	UUID,
-	"Calendar",
-	"hudson",
-	2, 0, // Version
-	RESOURCE_ID_IMAGE_MENU_ICON,
-	APP_INFO_WATCH_FACE
-);
-
-#define FONT_H 16
-#define FONT_W 7
-#define ROWS 8
-#define COLS 7
-#define FONT_OFF	RESOURCE_ID_FONT_SOURCECODEPRO_LIGHT_16
-static GFont font_off;
-
-static Window window;
-static TextLayer layers[ROWS][COLS];
-static TextLayer time_layer;
-
-static char time_text[8];
-
-static int mdays[] =
-{
-	31, // dec, previous year == 0
-	31, // jan
-	28, // feb; will be updated with actual number of days
-	31, // mar
-	30, // april
-	31, // may
-	30, // jun
-	31, // july
-	31, // aug
-	30, // sep
-	31, // oct
-	30, // nov
-	31, // dec
-	31, // jan, next year == 13
-};
-
-static const char days[7][4] =
-{
-	"M",
-	"T",
-	"W",
-	"R",
-	"F",
-	"S",
-	"Z",
-};
-
-static const char dates[32][4] =
-{
-	"--",
-	" 1",
-	" 2",
-	" 3",
-	" 4",
-	" 5",
-	" 6",
-	" 7",
-	" 8",
-	" 9",
-	"10",
-	"11",
-	"12",
-	"13",
-	"14",
-	"15",
-	"16",
-	"17",
-	"18",
-	"19",
-	"20",
-	"21",
-	"22",
-	"23",
-	"24",
-	"25",
-	"26",
-	"27",
-	"28",
-	"29",
-	"30",
-	"31",
-};
-
-
-#if 0
-/** Draw a box in a corner to indicate the number of minutes past the five.
- */
-static void
-minute_layer_update(
-        Layer * const me,
-        GContext * ctx
-)
-{
-	const int w = 4;
-	GRect r = GRect(0, 0, w, w);
-
-	if (minute_num == 0)
-		return; // nothing to draw
-	else
-	if (minute_num == 1)
-		r.origin = GPoint(0,0);
-	else
-	if (minute_num == 2)
-		r.origin = GPoint(144-w,0);
-	else
-	if (minute_num == 3)
-		r.origin = GPoint(144-w,168-w);
-	else
-	if (minute_num == 4)
-		r.origin = GPoint(0,168-w);
-
-	graphics_context_set_fill_color(ctx, GColorWhite);
-	graphics_fill_rect(ctx, r, 1, GCornersAll);
-}
-#endif
-
-
-static void
-day_mark(
-	int row,
-	int col,
-	int mday,
-	int today
-)
-{
-	TextLayer * const layer = &layers[row][col];
-	if (today)
-	{
-		text_layer_set_text_color(layer, GColorBlack);
-		text_layer_set_background_color(layer, GColorWhite);
-	} else {
-		text_layer_set_text_color(layer, GColorWhite);
-		text_layer_set_background_color(layer, GColorClear);
-	}
-
-	//text_layer_set_font(layer, today ? font_on : font_off);
-	text_layer_set_text(layer, dates[mday]);
-}
-
-
-static void
-handle_tick(
-	AppContextRef ctx,
-	PebbleTickEvent * const event
-)
-{
-	(void) ctx;
-	const PblTm * const ptm = event->tick_time;
-
-	string_format_time(
-		time_text,
-		sizeof(time_text),
-		"%H:%M",
-		ptm
-	);
-
-	text_layer_set_text(&time_layer, time_text);
-
-	// Update the number of days in feb
-	int year = ptm->tm_year + 1900;
-	if (year % 4 == 0 && year % 400 != 0)
-		mdays[2] = 29;
-	else
-		mdays[2] = 28;
-
-	// can we use mday or yday to simplify this?
-	int mday = ptm->tm_mday;
-	int month = ptm->tm_mon + 1;
-
-	// shift to start the week on monday, not sunday
-	int wday = (ptm->tm_wday + 7 - 1) % 7;
-
-	// Compute the 
-	if (mday <= 14 + wday)
-	{
-		month--;
-		mday = mdays[month] + mday - 14 - wday;
-	} else {
-		mday -= 14 + wday;
-	}
-
-	// Update the text for the calendar block
-	// mday and month are now set for the monday two weeks
-	// before the current day.
-	for (int row = 1 ; row < ROWS ; row++)
-	{
-		for (int col = 0 ; col < 7 ; col++)
-		{
-			const int today = month == ptm->tm_mon+1 && mday == ptm->tm_mday;
-
-			day_mark(row, col, mday, today);
-			if (++mday > mdays[month])
-			{
-				month++;
-				mday = 1;
-			}
-		}
-	}
-
-#if 0
-	// update the minute box
-	minute_num = min % 5;
-	layer_mark_dirty(&minute_layer);
-
-	// light up the one hour marker
-	for (int i = 1 ; i <= 12 ; i++)
-		word_mark(i, i == hour ? 1 : 0);
-#endif
-}
-
-
-static void
-day_layer_init(
-	int row,
-	int col
-)
-{
-	TextLayer * const layer = &layers[row][col];
-
-	GRect frame = GRect(
-		3 * col * FONT_W + (row == 0 ? FONT_W : 0),
-		row * FONT_H + 20,
-		2 * FONT_W,
-		FONT_H+2
-	);
-
-	text_layer_init(layer, frame);
-	text_layer_set_text_color(layer, GColorWhite);
-	text_layer_set_background_color(layer, GColorClear);
-	text_layer_set_font(layer, font_off);
-
-	if (row == 0)
-		text_layer_set_text(layer, days[col]);
-	else
-		text_layer_set_text(layer, ""); // will be set later
-
-	layer_add_child(&window.layer, &layer->layer);
-}
-
-
-static void
-handle_init(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	window_init(&window, "Main");
-	window_stack_push(&window, true);
-	window_set_background_color(&window, GColorBlack);
-
-	font_off = fonts_load_custom_font(resource_get_handle(FONT_OFF));
-
-	resource_init_current_app(&RESOURCES);
-
-	for (int row = 0 ; row < ROWS ; row++)
-	{
-		for (int day = 0 ; day < 7 ; day++)
-		{
-			day_layer_init(row, day);
-		}
-	}
-
-	text_layer_init(&time_layer, GRect(40, -4, 80, 25));
-	text_layer_set_text_color(&time_layer, GColorWhite);
-	text_layer_set_background_color(&time_layer, GColorClear);
-	text_layer_set_font(&time_layer, fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SOURCECODEPRO_LIGHT_20)));
-
-	text_layer_set_text(&time_layer, "");
-	layer_add_child(&window.layer, &time_layer.layer);
-
-	// Create a graphics layer for the entire background
-	//layer_init(&minute_layer, GRect(0, 0, 144, 168));
-	//minute_layer.update_proc = minute_layer_update;
-	//layer_add_child(&window.layer, &minute_layer);
-}
-
-
-void
-pbl_main(
-	void * const params
-)
-{
-	PebbleAppHandlers handlers = {
-		.init_handler	= &handle_init,
-		.tick_info	= {
-			.tick_handler = &handle_tick,
-			.tick_units = MINUTE_UNIT,
-		},
-	};
-
-	app_event_loop(params, &handlers);
-}

common/fmt.c

-/** \file
- * Format integers
- */
-#include "fmt.h"
-
-static char
-hexdigit(
-	uint8_t x
-)
-{
-	if (x <= 9)
-		return '0' + x - 0;
-	else
-	if (x <= 15)
-		return 'A' + x - 0xA;
-	else
-		return '?';
-}
-
-
-unsigned
-fmt_i16(
-	char * buf,
-	int16_t v_in,
-	int base
-)
-{
-	uint16_t v = v_in;
-
-	if (v_in < 0)
-	{
-		buf[0] = '-';
-		v = -v_in;
-	} else
-	if (v_in > 0)
-		buf[0] = '+';
-	else
-		buf[0] = ' ';
-
-	if (base == 10)
-	{
-		buf[5] = hexdigit(v % 10); v /= 10;
-		buf[4] = hexdigit(v % 10); v /= 10;
-		buf[3] = hexdigit(v % 10); v /= 10;
-		buf[2] = hexdigit(v % 10); v /= 10;
-		buf[1] = hexdigit(v % 10); v /= 10;
-		return 6;
-	} else
-	if (base == 16)
-	{
-		buf[4] = hexdigit(v % 16); v /= 16;
-		buf[3] = hexdigit(v % 16); v /= 16;
-		buf[2] = hexdigit(v % 16); v /= 16;
-		buf[1] = hexdigit(v % 16);
-		return 5;
-	}
-
-	buf[1] = '?';
-	return 2;
-}
-
-
-unsigned
-fmt_i32(
-	char * buf,
-	int32_t v_in,
-	int base
-)
-{
-	uint32_t v = v_in;
-
-	if (v_in < 0)
-	{
-		buf[0] = '-';
-		v = -v_in;
-	} else
-	if (v_in > 0)
-		buf[0] = '+';
-	else
-		buf[0] = ' ';
-
-	if (base == 10)
-	{
-		buf[10] = hexdigit(v % 10); v /= 10;
-		buf[9] = hexdigit(v % 10); v /= 10;
-		buf[8] = hexdigit(v % 10); v /= 10;
-		buf[7] = hexdigit(v % 10); v /= 10;
-		buf[6] = hexdigit(v % 10); v /= 10;
-		buf[5] = hexdigit(v % 10); v /= 10;
-		buf[4] = hexdigit(v % 10); v /= 10;
-		buf[3] = hexdigit(v % 10); v /= 10;
-		buf[2] = hexdigit(v % 10); v /= 10;
-		buf[1] = hexdigit(v % 10); v /= 10;
-		return 11;
-	} else
-	if (base == 16)
-	{
-		buf[8] = hexdigit(v % 16); v /= 16;
-		buf[7] = hexdigit(v % 16); v /= 16;
-		buf[6] = hexdigit(v % 16); v /= 16;
-		buf[5] = hexdigit(v % 16);
-		buf[4] = hexdigit(v % 16); v /= 16;
-		buf[3] = hexdigit(v % 16); v /= 16;
-		buf[2] = hexdigit(v % 16); v /= 16;
-		buf[1] = hexdigit(v % 16);
-		return 9;
-	}
-
-	buf[1] = '?';
-	return 2;
-}

common/fmt.h

-#ifndef _fmt_h_
-#define _fmt_h_
-
-#include <stdint.h>
-
-unsigned
-fmt_i16(
-	char * buf,
-	int16_t v,
-	int base
-);
-
-unsigned
-fmt_i32(
-	char * buf,
-	int32_t v,
-	int base
-);
-
-#endif

cst/src/Makefile

-APP := cst
-
-SRCS += cst.c
-
-FONTS := \
-	fonts/CST-Black.ttf:32 \
-	fonts/CST-Light.ttf:15 \
-
-IMAGES := \
-	images/menu_icon.png \
-
-include ../../Makefile.pebble

cst/src/cst.c

-/** \file
- * CST font clock
- *
- * Two lines:
- * HH:MM (large, bold)
- * YYYY-MM-DD
- */
-#include <pebble_os.h>
-#include <pebble_app.h>
-#include <pebble_fonts.h>
-#include <pebble_th.h>
-
-#define UUID {0x7F, 0x58, 0x4D, 0xD7, 0x32, 0xC7, 0x49, 0x65, 0x8B, 0xD6, 0x6F, 0xCE, 0x06, 0x82, 0x2B, 0xA2}
-
-PBL_APP_INFO(
-	UUID,
-	"CST Style",
-	"hudson",
-	2, 0, // Version
-	RESOURCE_ID_IMAGE_MENU_ICON,
-	APP_INFO_WATCH_FACE
-);
-
-static Window window;
-
-static GFont font_big;
-static GFont font_small;
-
-static char time_text[8];
-static char date_text[16];
-
-static TextLayer time_layer;
-static TextLayer date_layer;
-static TextLayer day_layer;
-
-
-static const char *days[] = {
-	"Sunday",
-	"Monday",
-	"Tuesday",
-	"Wednesday",
-	"Thursday",
-	"Friday",
-	"Saturday",
-};
-
-
-/** Called once per minute */
-static void
-handle_tick(
-	AppContextRef ctx,
-	PebbleTickEvent * const event
-)
-{
-	(void) ctx;
-	const PblTm * const ptm = event->tick_time;
-
-	string_format_time(
-		time_text,
-		sizeof(time_text),
-		"%H:%M",
-		ptm
-	);
-
-	string_format_time(
-		date_text,
-		sizeof(date_text),
-		"%d %B",
-		ptm
-	);
-
-
-	text_layer_set_text(&date_layer, date_text);
-	text_layer_set_text(&time_layer, time_text);
-	text_layer_set_text(&day_layer, days[ptm->tm_wday]);
-}
-
-
-static void
-handle_init(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	window_init(&window, "Main");
-	window_stack_push(&window, true);
-	window_set_background_color(&window, GColorBlack);
-
-	resource_init_current_app(&RESOURCES);
-
-	int y = 15;
-	int h = 30;
-
-	font_big  = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_CST_BLACK_32));
-	font_small  = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_CST_LIGHT_15));
-
-	// Stack top to bottom.  Note that the hour can take up
-	// two rows at midnight.
-	text_layer_setup(
-		&window,
-		&time_layer,
-		GRect(0, 80, 144, 168),
-		font_big
-	);
-
-	text_layer_setup(
-		&window,
-		&date_layer,
-		GRect(0, 120, 144, 40),
-		font_small
-	);
-
-	text_layer_setup(
-		&window,
-		&day_layer,
-		GRect(0, 140, 144, 40),
-		font_small
-	);
-}
-
-
-static void
-handle_deinit(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	fonts_unload_custom_font(font_big);
-	fonts_unload_custom_font(font_small);
-}
-
-
-void
-pbl_main(
-	void * const params
-)
-{
-	PebbleAppHandlers handlers = {
-		.init_handler	= &handle_init,
-		.deinit_handler	= &handle_deinit,
-		.tick_info	= {
-			.tick_handler = &handle_tick,
-			.tick_units = MINUTE_UNIT,
-		},
-	};
-
-	app_event_loop(params, &handlers);
-}

cst/src/fonts/CST-Black.ttf

Binary file removed.

cst/src/fonts/CST-Light.ttf

Binary file removed.

cst/src/images/menu_icon.png

Removed
Old image

cube/src/Makefile

-#
-# 3D wireframe demo
-#
-
-APP := wireframe
-
-SRCS += wireframe.c
-SRCS += camera.c
-SRCS += teatime.c
-SRCS += ../../common/fmt.c
-
-include ../../Makefile.pebble

cube/src/README

-3D cubes!

cube/src/camera.c

-#include <stdint.h>
-#include <math.h>
-#include <pebble_os.h>
-#include "draw.h"
-#include "camera.h"
-
-/* sin_lookup() takes deg * 32768 / 90.
- * returns -65536 to 65536
- */
-static const int scale = 65536;
-
-void
-camera_setup(
-	camera_t * c,
-	int32_t eye_z,
-	int32_t a[3]
-)
-{
-	int32_t sx = sin_lookup(a[0]);
-	int32_t cx = cos_lookup(a[0]);
-	int32_t sy = sin_lookup(a[1]);
-	int32_t cy = cos_lookup(a[1]);
-	int32_t sz = sin_lookup(a[2]);
-	int32_t cz = cos_lookup(a[2]);
-
-	c->r[0][0] = ( cy * cz) / scale;
-	c->r[0][1] = ((-cy * sz) + (sx * sy * cz) / scale) / scale;
-	c->r[0][2] = (( sx * sz) + (cx * sy * cz) / scale) / scale;
-
-	c->r[1][0] = ( cx * sz) / scale;
-	c->r[1][1] = (( cx * cz) + (sx * sy * sz) / scale) / scale;
-	c->r[1][2] = ((-sx * cz) + (cx * sy * sz) / scale) / scale;
-
-	c->r[2][0] = (-sy);
-	c->r[2][1] = ( sx * cy) / scale;
-	c->r[2][2] = ( cx * cy) / scale;
-
-	c->eye_z = eye_z;
-}
-
-
-int
-camera_project(
-	const camera_t * c,
-	const vertex_t * const v,
-	pixel_t * const pixel
-)
-{
-	int32_t p[3] = { 0, 0, c->eye_z * scale };
-	for (int i = 0 ; i < 3 ; i++)
-		for (int j = 0 ; j < 3 ; j++)
-			p[i] += c->r[i][j] * v->x[j];
-
-	if (p[2] <= 0)
-	{
-		// The point is behind us
-		pixel->x = pixel->y = -1;
-		return 0;
-	}
-
-	// Smaller == wider angle view
-	const int32_t zoom = 1;
-
-	// Transform to screen coordinate frame,
-	// limiting to the actual boundaries
-	int32_t px = (p[1] * c->eye_z * zoom) / p[2] + VSCREEN_WIDTH / 2;
-	if (px < 0)
-		px = 0;
-	if (px >= VSCREEN_WIDTH-1)
-		px = VSCREEN_WIDTH-1;
-	pixel->x = px;
-
-	int32_t py = (p[0] * c->eye_z * zoom) / p[2] + VSCREEN_HEIGHT / 2;
-	if (py < 0)
-		py = 0;
-	if (py >= VSCREEN_HEIGHT-1)
-		py = VSCREEN_HEIGHT-1;
-	pixel->y = py;
-
-	return 1;
-}

cube/src/camera.h

-/** \file
- * Camera projection transformations.
- */
-#ifndef _camera_h_
-#define _camera_h_
-
-#include <stdint.h>
-#include "coords.h"
-
-typedef struct
-{
-	int32_t eye_z;
-	int8_t r[3][3];
-} camera_t ;
-
-
-/** Initialize the camera to be positioned at x and with euler angles a.
- */
-void
-camera_setup(
-	camera_t * c,
-	int32_t eye_z,
-	int32_t a[3]
-);
-
-
-
-/** Project a 3D point to the 2D image.
- * Returns 0 if the point is behind us and should not be drawn.
- */
-int
-camera_project(
-	const camera_t * c,
-	const vertex_t * x,
-	pixel_t * pixel_out
-);
-
-#endif

cube/src/coords.h

-/** \file
- * Coordinate systems used in the wireframe and camera framework.
- */
-#ifndef _coords_h_
-#define _coords_h_
-
-#include <stdint.h>
-
-
-typedef struct
-{
-	int8_t x[3];
-} __attribute__((__packed__))
-vertex_t;
-
-
-typedef struct
-{
-	uint8_t v0;
-	uint8_t v1;
-} __attribute__((__packed__))
-edge_t;
-
-
-typedef struct
-{
-	uint8_t x;
-	uint8_t y;
-	//int8_t z; // depth, right now -1 == behind the camera, 1 == infront
-} __attribute__((__packed__))
-pixel_t;
-
-#endif

cube/src/cube.c

-/** \file
- * Show off the 3D accelerometer data.
- */
-#include "pebble_os.h"
-#include "pebble_app.h"
-#include "pebble_fonts.h"
-
-PBL_APP_INFO(
-	"Accelerometer",
-	"hudson",
-	1, // Version
-	INVALID_RESOURCE,
-	APP_INFO_WATCH_FACE
-);
-
-
-static Window window;
-static TextLayer time_layer;
-static Layer layer;
-
-static void
-bargraph_layer_update(
-	Layer * const me,
-	GContext * ctx
-)
-{
-/*
-	// Draw a white rectangle across the entire bottom
-	const unsigned w = me->bounds.size.w;
-	const unsigned h = me->bounds.size.h;
-	graphics_context_set_fill_color(ctx, GColorWhite);
-	graphics_fill_rect(ctx, GRect(0, 0, w, h), 0, GCornersAll);
-
-	graphics_context_set_fill_color(ctx, GColorBlack);
-	graphics_fill_rect(ctx, GRect(0, 0, (w * remaining) / 30, h), 4, GCornersRight);
-*/
-}
-
-
-static unsigned
-fmt_i16(
-	char * buf,
-	int16_t v_in
-)
-{
-	uint16_t v = v_in;
-
-	if (v_in < 0)
-	{
-		buf[0] = '-';
-		v = -v_in;
-	} else
-	if (v_in > 0)
-		buf[0] = '+';
-	else
-		buf[0] = ' ';
-
-	buf[5] = '0' + v % 10; v /= 10;
-	buf[4] = '0' + v % 10; v /= 10;
-	buf[3] = '0' + v % 10; v /= 10;
-	buf[2] = '0' + v % 10; v /= 10;
-	buf[1] = '0' + v % 10;
-
-	return 6;
-}
-
-
-static void
-handle_tick(
-	AppContextRef ctx,
-	PebbleTickEvent * const event
-)
-{
-	(void) ctx;
-	const PblTm * const ptm = event->tick_time;
-	static char time_buffer[32];
-	unsigned off = 0;
-
-	struct AccelData accel = { 12345, 9999, -9999 };
-	accel_get_xyz(&accel);
-	off += fmt_i16(time_buffer + off, accel.x);
-	time_buffer[off++] = '\n';
-	off += fmt_i16(time_buffer + off, accel.y);
-	time_buffer[off++] = '\n';
-	off += fmt_i16(time_buffer + off, accel.z);
-	time_buffer[off++] = '\n';
-
-	string_format_time(
-		time_buffer + off,
-		sizeof(time_buffer) - off,
-		"%H:%M:%S",
-		ptm
-	);
-
-	text_layer_set_text(&time_layer, time_buffer);
-}
-
-
-static void
-handle_init(
-	AppContextRef ctx
-)
-{
-	(void) ctx;
-
-	window_init(&window, "Main");
-	window_stack_push(&window, true);
-
-	text_layer_init(&time_layer, GRect(0,0,144,168));
-	text_layer_set_text(&time_layer, "");
-	text_layer_set_font(&time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18));
-	layer_add_child(&window.layer, &time_layer.layer);
-
-/*
-	// Bargraph layer is across the bottom
-	const unsigned bargraph_height = 20;
-	layer_init(&bargraph_layer, GRect(0,168-bargraph_height-15,144,bargraph_height));
-	bargraph_layer.update_proc = bargraph_layer_update;
-
-	layer_add_child(&window.layer, &bargraph_layer);
-*/
-}
-
-
-void
-pbl_main(
-	void * const params
-)
-{
-	PebbleAppHandlers handlers = {
-		.init_handler	= &handle_init,
-		.tick_info	= {
-			.tick_handler = &handle_tick,
-			.tick_units = SECOND_UNIT,
-		},
-	};
-
-	app_event_loop(params, &handlers);
-}

cube/src/cube.h

-/** \file
- * Vertex and edge definition for a cube
- */
-#ifndef EDGE_COLOR
-#define EDGE_COLOR { 0, 0xFF, 0, 0 }
-#endif
-
-static const vertex_t vertices[] = {
-	{ { -50, -50, -50 } },
-	{ { -50, -50,  50 } },
-	{ { -50,  50, -50 } },
-	{ { -50,  50,  50 } },
-	{ {  50, -50, -50 } },
-	{ {  50, -50,  50 } },
-	{ {  50,  50, -50 } },
-	{ {  50,  50,  50 } },
-};
-static const edge_t edges[] = {
-	{ 0, 1 },
-	{ 0, 2 },
-	{ 0, 4 },
-	{ 1, 3 },
-	{ 1, 5 },
-	{ 2, 3 },
-	{ 2, 6 },
-	{ 3, 7 },
-	{ 4, 5 },
-	{ 4, 6 },
-	{ 5, 7 },
-	{ 6, 7 },
-};

cube/src/draw.c

-/** \file
- * Drawing functions.
- */
-#include "draw.h"
-#include "mathutil.h"
-
-void
-draw_pixel(
-	color24_t c,
-	uint32_t x,
-	uint32_t y
-)
-{
-	if (x >= VSCREEN_WIDTH || y >= VSCREEN_HEIGHT)
-		return;
-
-	x >>= VSCREEN_SHIFT;
-	y >>= VSCREEN_SHIFT;
-	pulse_set_draw_window(x, y, x, y);
-	pulse_draw_point24(c);
-}
-
-
-void
-draw_line(
-	color24_t c,
-	uint32_t x0,
-	uint32_t y0,
-	uint32_t x1,
-	uint32_t y1
-)
-{
-#if 0
-	const int32_t dx = abs(x1 - x0);
-	const int32_t dy = abs(y1 - y0);
-
-	const int32_t sx = x0 < x1 ? 1 : -1;
-	const int32_t sy = y0 < y1 ? 1 : -1;
-	int32_t err = dx - dy;
-
-#if VSCREEN_SHIFT != 0
-	uint32_t last_px = -1;
-	uint32_t last_py = -1;
-#endif
-
-	while(1)
-	{
-#if VSCREEN_SHIFT != 0
-		uint32_t px = x0 >> VSCREEN_SHIFT;
-		uint32_t py = y0 >> VSCREEN_SHIFT;
-		if (px != last_px || py != last_py)
-		{
-			last_px = px;
-			last_py = py;
-			draw_pixel(c, x0, y0);
-		}
-#else
-		draw_pixel(c, x0, y0);
-#endif
-
-		if (x0 == x1 && y0 == y1)
-			break;
-		int32_t e2 = 2 * err;
-		if (e2 > -dy)
-		{
-			err -= dy;
-			x0 += sx;
-		}
-		if (e2 < +dx)
-		{
-			err += dx;
-			y0 += sy;
-		}
-	}
-#endif
-}
-
-static char buf[2];
-struct PWidgetTextDynamic font;
-
-void
-draw_monostring(
-	uint32_t x,
-	uint32_t y,
-	color24_t color,
-	const char * s
-)
-{
-	pulse_init_dynamic_text_widget(
-		&font,
-		buf,
-		FONT,
-		color,
-		PWTS_TRUNCATE
-	);
-
-	uint32_t orig_x = x >> VSCREEN_SHIFT;
-
-	struct PWTextBox box = {
-		.left		= orig_x,
-		.top		= y >> VSCREEN_SHIFT,
-		.right		= SCREEN_WIDTH - 1,
-		.bottom		= SCREEN_HEIGHT - 1,
-	};
-
-	buf[1] = '\0';
-
-	while ((buf[0] = *s++))
-	{
-		if (buf[0] == '\n')
-		{
-			box.left = orig_x;
-			box.top += FONT_HEIGHT;
-		} else {
-			pulse_render_text(&box, &font);
-			box.left += FONT_WIDTH;
-		}
-	}
-}

cube/src/draw.h

-/** \file
- * Line and pixel drawing routines.
- * Using a virtual screen buffer that is twice the resolution
- * along each axis so that anti-aliasing can be done later.
- */
-#ifndef _draw_h_
-
-#define SCREEN_WIDTH 144
-#define SCREEN_HEIGHT 168
-
-#define VSCREEN_SHIFT 1
-#define VSCREEN_WIDTH (SCREEN_WIDTH << VSCREEN_SHIFT)
-#define VSCREEN_HEIGHT (SCREEN_HEIGHT << VSCREEN_SHIFT)
-
-
-/* Draw a pixel in vscreen coordinates */
-void
-draw_pixel(
-	int c,
-	int x,
-	int y
-);
-
-
-/* Draw a non-antialised line using Bresenham's_line_algorithm
- * in vscreen coordinates */
-void
-draw_line(
-	int c,
-	int x0,
-	int y0,
-	int x1,
-	int y1
-);
-
-
-#endif

cube/src/mathutil.h

-/** \file
- * Math utility functions
- */
-#ifndef _mathutil_h_
-#define _mathutil_h_
-
-#include <stdint.h>
-
-static inline int32_t
-iabs(
-	int32_t x
-)
-{
-	if (x < 0)
-		return -x;
-	return x;
-}
-
-
-static inline uint32_t
-limit(
-	int32_t x,
-	int32_t min,
-	int32_t max
-)
-{
-	if (x < min)
-		return min;
-	if (x > max)
-		return max;
-	return x;
-}
-
-
-#endif

cube/src/teatime.c

-/** \file
- * Show off the 3D accelerometer data.
- */
-#include <pebble_os.h>
-#include <pebble_app.h>
-#include <pebble_fonts.h>
-#include "draw.h"
-#include "mathutil.h"
-#include "camera.h"
-#include "wireframe.h"
-#include "fmt.h"
-
-PBL_APP_INFO(
-	"Teatime",
-	"hudson",
-	1, // Version
-	INVALID_RESOURCE,
-	APP_INFO_WATCH_FACE
-);
-
-
-static Window window;
-static TextLayer time_layer;
-static Layer layer;
-
-static camera_t camera;
-static int32_t euler[3];
-
-// Bring in a model to render
-//#include "teapot.h"
-#include "cube.h"
-
-#define ARRAY_COUNT(x) (sizeof(x) / sizeof(*x))
-static pixel_t pixels[ARRAY_COUNT(vertices)];
-
-
-static void
-layer_update(
-	Layer * const me,