initial commit
commit
3cf894b67f
|
@ -0,0 +1,2 @@
|
||||||
|
# Pebble tests
|
||||||
|
Various tests and experiments for the Pebble smartwatch platforms
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example jshint configuration file for Pebble development.
|
||||||
|
*
|
||||||
|
* Check out the full documentation at http://www.jshint.com/docs/options/
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// Declares the existence of the globals available in PebbleKit JS.
|
||||||
|
"globals": {"localStorage": true, "Int16Array": true, "Uint32Array": true, "setTimeout": true, "Uint8ClampedArray": true, "navigator": true, "setInterval": true, "WebSocket": true, "Int32Array": true, "Uint8Array": true, "Float64Array": true, "Int8Array": true, "XMLHttpRequest": true, "Uint16Array": true, "Float32Array": true, "console": true, "Pebble": true},
|
||||||
|
|
||||||
|
// Do not mess with standard JavaScript objects (Array, Date, etc)
|
||||||
|
"freeze": true,
|
||||||
|
|
||||||
|
// Do not use eval! Keep this warning turned on (ie: false)
|
||||||
|
"evil": false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The options below are more style/developer dependent.
|
||||||
|
* Customize to your liking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// All variables should be in camelcase - too specific for CloudPebble builds to fail
|
||||||
|
// "camelcase": true,
|
||||||
|
|
||||||
|
// Do not allow blocks without { } - too specific for CloudPebble builds to fail.
|
||||||
|
// "curly": true,
|
||||||
|
|
||||||
|
// Prohibits the use of immediate function invocations without wrapping them in parentheses
|
||||||
|
"immed": true,
|
||||||
|
|
||||||
|
// Don't enforce indentation, because it's not worth failing builds over
|
||||||
|
// (especially given our somewhat lacklustre support for it)
|
||||||
|
"indent": false,
|
||||||
|
|
||||||
|
// Do not use a variable before it's defined
|
||||||
|
"latedef": "nofunc",
|
||||||
|
|
||||||
|
// Spot undefined variables
|
||||||
|
"undef": "true",
|
||||||
|
|
||||||
|
// Spot unused variables
|
||||||
|
"unused": "true"
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"author": "lastfuture@lastfuture.de",
|
||||||
|
"dependencies": {},
|
||||||
|
"keywords": [],
|
||||||
|
"name": "colortest",
|
||||||
|
"pebble": {
|
||||||
|
"displayName": "colortest",
|
||||||
|
"enableMultiJS": false,
|
||||||
|
"messageKeys": [],
|
||||||
|
"projectType": "native",
|
||||||
|
"resources": {
|
||||||
|
"media": []
|
||||||
|
},
|
||||||
|
"sdkVersion": "3",
|
||||||
|
"targetPlatforms": [
|
||||||
|
"chalk"
|
||||||
|
],
|
||||||
|
"uuid": "30630c34-d469-4d4d-a709-4e9d48e0c43e",
|
||||||
|
"watchapp": {
|
||||||
|
"watchface": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <pebble.h>
|
||||||
|
|
||||||
|
static Window *s_window;
|
||||||
|
static Layer *s_canvas;
|
||||||
|
|
||||||
|
static int s_hours, s_minutes;
|
||||||
|
|
||||||
|
/*uint8_t sortedcolors[64] = {
|
||||||
|
0, 1, 2, 16, 3, 17, 18, 4, 32, 19, 5, 33, 6, 34, 20, 48,
|
||||||
|
7, 35, 21, 49, 22, 50, 8, 36, 23, 51, 9, 37, 10, 38, 24, 52,
|
||||||
|
11, 39, 25, 53, 26, 54, 12, 40, 27, 55, 13, 41, 14, 42, 28, 56,
|
||||||
|
15, 43, 29, 57, 30, 58, 44, 31, 59, 45, 46, 60, 47, 61, 62, 63
|
||||||
|
};*/
|
||||||
|
|
||||||
|
uint8_t sortedcolors[64] = {0,1,16,2,17,18,3,4,5,19,20,32,6,21,33,22,34,7,23,35,36,37,38,39,48,49,50,51,52,8,9,53,24,10,25,54,26,11,55,27,40,41,42,43,56,57,58,59,12,13,28,14,29,30,15,31,44,45,46,47,60,61,62,63};
|
||||||
|
|
||||||
|
int compare( const void* a, const void* b)
|
||||||
|
{
|
||||||
|
uint32_t int_a = * ( (uint32_t*) a );
|
||||||
|
uint32_t int_b = * ( (uint32_t*) b );
|
||||||
|
|
||||||
|
if ( int_a == int_b ) return 0;
|
||||||
|
else if ( int_a < int_b ) return -1;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static uint16_t int_sqrt(uint16_t value)
|
||||||
|
{
|
||||||
|
uint16_t answer = value;
|
||||||
|
uint16_t answer_sqr = value*value;
|
||||||
|
while(answer_sqr>value)
|
||||||
|
{
|
||||||
|
answer = (answer + value/answer)/2;
|
||||||
|
answer_sqr = answer * answer;
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void layer_update_proc(Layer *layer, GContext *ctx) {
|
||||||
|
GRect bounds = layer_get_bounds(layer);
|
||||||
|
|
||||||
|
GRect righthalf = GRect(bounds.size.w/2, bounds.origin.y, bounds.size.w/2, bounds.size.h);
|
||||||
|
graphics_context_set_fill_color(ctx, GColorBlack);
|
||||||
|
graphics_fill_rect(ctx, righthalf, 0, GCornerNone);
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint32_t brightnesstable[64];
|
||||||
|
uint32_t brightnesstable2[64];
|
||||||
|
for(uint8_t i=0; i<64; i++) {
|
||||||
|
GColor8 color = (GColor8) { .argb = i+0b11000000 };
|
||||||
|
uint32_t brightness = color.r*475251000 + color.g*774330000 + color.b*181260000;
|
||||||
|
brightnesstable[i] = brightness;
|
||||||
|
brightnesstable2[i] = brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sortedcolors[64];
|
||||||
|
qsort(brightnesstable, 64, sizeof(uint32_t), compare);
|
||||||
|
for(uint8_t i=0; i<64; i++) {
|
||||||
|
for(uint8_t j=0; j<64; j++) {
|
||||||
|
if (brightnesstable[i] == brightnesstable2[j]) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO, "%d", j);
|
||||||
|
sortedcolors[i] = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(uint8_t i=0; i<64; i++) {
|
||||||
|
uint8_t argb = sortedcolors[i]+0b11000000;
|
||||||
|
//APP_LOG(APP_LOG_LEVEL_INFO, "Color %i", argb);
|
||||||
|
GRect colorstripe = GRect(26+bounds.origin.x+(i*2), bounds.origin.y, 2, bounds.size.h);
|
||||||
|
graphics_context_set_fill_color(ctx, (GColor8) { .argb = argb });
|
||||||
|
graphics_fill_rect(ctx, colorstripe, 0, GCornerNone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_load(Window *window) {
|
||||||
|
Layer *window_layer = window_get_root_layer(window);
|
||||||
|
GRect bounds = layer_get_bounds(window_layer);
|
||||||
|
|
||||||
|
s_canvas = layer_create(bounds);
|
||||||
|
layer_set_update_proc(s_canvas, layer_update_proc);
|
||||||
|
layer_add_child(window_layer, s_canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_unload(Window *window) {
|
||||||
|
layer_destroy(s_canvas);
|
||||||
|
window_destroy(s_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_push() {
|
||||||
|
s_window = window_create();
|
||||||
|
window_set_background_color(s_window, GColorWhite);
|
||||||
|
window_set_window_handlers(s_window, (WindowHandlers) {
|
||||||
|
.load = window_load,
|
||||||
|
.unload = window_unload,
|
||||||
|
});
|
||||||
|
window_stack_push(s_window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_update(int hours, int minutes) {
|
||||||
|
s_hours = hours;
|
||||||
|
s_minutes = minutes;
|
||||||
|
layer_mark_dirty(s_canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tick_handler(struct tm *time_now, TimeUnits changed) {
|
||||||
|
main_window_update(time_now->tm_hour, time_now->tm_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
main_window_push();
|
||||||
|
|
||||||
|
tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit() {
|
||||||
|
tick_timer_service_unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
app_event_loop();
|
||||||
|
deinit();
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file is the default set of rules to compile a Pebble project.
|
||||||
|
#
|
||||||
|
# Feel free to customize this to your needs.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
try:
|
||||||
|
from sh import CommandNotFound, jshint, cat, ErrorReturnCode_2
|
||||||
|
hint = jshint
|
||||||
|
except (ImportError, CommandNotFound):
|
||||||
|
hint = None
|
||||||
|
|
||||||
|
top = '.'
|
||||||
|
out = 'build'
|
||||||
|
|
||||||
|
def options(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def configure(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def build(ctx):
|
||||||
|
if False and hint is not None:
|
||||||
|
try:
|
||||||
|
hint([node.abspath() for node in ctx.path.ant_glob("src/**/*.js")], _tty_out=False) # no tty because there are none in the cloudpebble sandbox.
|
||||||
|
except ErrorReturnCode_2 as e:
|
||||||
|
ctx.fatal("\nJavaScript linting failed (you can disable this in Project Settings):\n" + e.stdout)
|
||||||
|
|
||||||
|
# Concatenate all our JS files (but not recursively), and only if any JS exists in the first place.
|
||||||
|
ctx.path.make_node('src/js/').mkdir()
|
||||||
|
js_paths = ctx.path.ant_glob(['src/*.js', 'src/**/*.js'])
|
||||||
|
if js_paths:
|
||||||
|
ctx(rule='cat ${SRC} > ${TGT}', source=js_paths, target='pebble-js-app.js')
|
||||||
|
has_js = True
|
||||||
|
else:
|
||||||
|
has_js = False
|
||||||
|
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
build_worker = os.path.exists('worker_src')
|
||||||
|
binaries = []
|
||||||
|
|
||||||
|
for p in ctx.env.TARGET_PLATFORMS:
|
||||||
|
ctx.set_env(ctx.all_envs[p])
|
||||||
|
ctx.set_group(ctx.env.PLATFORM_NAME)
|
||||||
|
app_elf='{}/pebble-app.elf'.format(p)
|
||||||
|
ctx.pbl_program(source=ctx.path.ant_glob('src/c/**/*.c'),
|
||||||
|
target=app_elf)
|
||||||
|
|
||||||
|
if build_worker:
|
||||||
|
worker_elf='{}/pebble-worker.elf'.format(p)
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
|
||||||
|
ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/c/**/*.c'),
|
||||||
|
target=worker_elf)
|
||||||
|
else:
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf})
|
||||||
|
|
||||||
|
ctx.set_group('bundle')
|
||||||
|
ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if has_js else [])
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example jshint configuration file for Pebble development.
|
||||||
|
*
|
||||||
|
* Check out the full documentation at http://www.jshint.com/docs/options/
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// Declares the existence of the globals available in PebbleKit JS.
|
||||||
|
"globals": {"localStorage": true, "Int16Array": true, "Uint32Array": true, "setTimeout": true, "Uint8ClampedArray": true, "navigator": true, "setInterval": true, "WebSocket": true, "Int32Array": true, "Uint8Array": true, "Float64Array": true, "Int8Array": true, "XMLHttpRequest": true, "Uint16Array": true, "Float32Array": true, "console": true, "Pebble": true},
|
||||||
|
|
||||||
|
// Do not mess with standard JavaScript objects (Array, Date, etc)
|
||||||
|
"freeze": true,
|
||||||
|
|
||||||
|
// Do not use eval! Keep this warning turned on (ie: false)
|
||||||
|
"evil": false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The options below are more style/developer dependent.
|
||||||
|
* Customize to your liking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// All variables should be in camelcase - too specific for CloudPebble builds to fail
|
||||||
|
// "camelcase": true,
|
||||||
|
|
||||||
|
// Do not allow blocks without { } - too specific for CloudPebble builds to fail.
|
||||||
|
// "curly": true,
|
||||||
|
|
||||||
|
// Prohibits the use of immediate function invocations without wrapping them in parentheses
|
||||||
|
"immed": true,
|
||||||
|
|
||||||
|
// Don't enforce indentation, because it's not worth failing builds over
|
||||||
|
// (especially given our somewhat lacklustre support for it)
|
||||||
|
"indent": false,
|
||||||
|
|
||||||
|
// Do not use a variable before it's defined
|
||||||
|
"latedef": "nofunc",
|
||||||
|
|
||||||
|
// Spot undefined variables
|
||||||
|
"undef": "true",
|
||||||
|
|
||||||
|
// Spot unused variables
|
||||||
|
"unused": "true"
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"author": "lastfuture@lastfuture.de",
|
||||||
|
"dependencies": {},
|
||||||
|
"keywords": [],
|
||||||
|
"name": "line-seg",
|
||||||
|
"pebble": {
|
||||||
|
"displayName": "line seg",
|
||||||
|
"enableMultiJS": false,
|
||||||
|
"messageKeys": [],
|
||||||
|
"projectType": "native",
|
||||||
|
"resources": {
|
||||||
|
"media": []
|
||||||
|
},
|
||||||
|
"sdkVersion": "3",
|
||||||
|
"uuid": "3ef2a83a-ba8e-48c5-ad81-f0da09b74649",
|
||||||
|
"watchapp": {
|
||||||
|
"watchface": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
#include <pebble.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GraphicsGems.h
|
||||||
|
* Version 1.0 - Andrew Glassner
|
||||||
|
* from "Graphics Gems", Academic Press, 1990
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GG_H
|
||||||
|
|
||||||
|
#define GG_H 1
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
/* 2d geometry types */
|
||||||
|
/*********************/
|
||||||
|
|
||||||
|
typedef struct Point2Struct { /* 2d point */
|
||||||
|
double x, y;
|
||||||
|
} Point2;
|
||||||
|
typedef Point2 Vector2;
|
||||||
|
|
||||||
|
typedef struct IntPoint2Struct { /* 2d integer point */
|
||||||
|
int x, y;
|
||||||
|
} IntPoint2;
|
||||||
|
|
||||||
|
typedef struct Matrix3Struct { /* 3-by-3 matrix */
|
||||||
|
double element[3][3];
|
||||||
|
} Matrix3;
|
||||||
|
|
||||||
|
typedef struct Box2dStruct { /* 2d box */
|
||||||
|
Point2 min, max;
|
||||||
|
} Box2;
|
||||||
|
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
/* 3d geometry types */
|
||||||
|
/*********************/
|
||||||
|
|
||||||
|
typedef struct Point3Struct { /* 3d point */
|
||||||
|
double x, y, z;
|
||||||
|
} Point3;
|
||||||
|
typedef Point3 Vector3;
|
||||||
|
|
||||||
|
typedef struct IntPoint3Struct { /* 3d integer point */
|
||||||
|
int x, y, z;
|
||||||
|
} IntPoint3;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Matrix4Struct { /* 4-by-4 matrix */
|
||||||
|
double element[4][4];
|
||||||
|
} Matrix4;
|
||||||
|
|
||||||
|
typedef struct Box3dStruct { /* 3d box */
|
||||||
|
Point3 min, max;
|
||||||
|
} Box3;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* one-argument macros */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
/* absolute value of a */
|
||||||
|
#define ABS(a) (((a)<0) ? -(a) : (a))
|
||||||
|
|
||||||
|
/* round a to nearest int */
|
||||||
|
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
|
||||||
|
|
||||||
|
/* take sign of a, either -1, 0, or 1 */
|
||||||
|
#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
|
||||||
|
|
||||||
|
/* take binary sign of a, either -1, or 1 if >= 0 */
|
||||||
|
#define SGN(a) (((a)<0) ? -1 : 1)
|
||||||
|
|
||||||
|
/* shout if something that should be true isn't */
|
||||||
|
#define ASSERT(x) \
|
||||||
|
if (!(x)) fprintf(stderr," Assert failed: x\n");
|
||||||
|
|
||||||
|
/* square a */
|
||||||
|
#define SQR(a) ((a)*(a))
|
||||||
|
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* two-argument macros */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
/* find minimum of a and b */
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
|
||||||
|
/* find maximum of a and b */
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
|
||||||
|
/* swap a and b (see Gem by Wyvill) */
|
||||||
|
#define SWAP(a,b) { a^=b; b^=a; a^=b; }
|
||||||
|
|
||||||
|
/* linear interpolation from l (when a=0) to h (when a=1)*/
|
||||||
|
/* (equal to (a*h)+((1-a)*l) */
|
||||||
|
#define LERP(a,l,h) ((l)+(((h)-(l))*(a)))
|
||||||
|
|
||||||
|
/* clamp the input to the specified range */
|
||||||
|
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
|
||||||
|
|
||||||
|
|
||||||
|
/****************************/
|
||||||
|
/* memory allocation macros */
|
||||||
|
/****************************/
|
||||||
|
|
||||||
|
/* create a new instance of a structure (see Gem by Hultquist) */
|
||||||
|
#define NEWSTRUCT(x) (struct x *)(malloc((unsigned)sizeof(struct x)))
|
||||||
|
|
||||||
|
/* create a new instance of a type */
|
||||||
|
#define NEWTYPE(x) (x *)(malloc((unsigned)sizeof(x)))
|
||||||
|
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
/* useful constants */
|
||||||
|
/********************/
|
||||||
|
|
||||||
|
#define PI 3.141592 /* the venerable pi */
|
||||||
|
#define PITIMES2 6.283185 /* 2 * pi */
|
||||||
|
#define PIOVER2 1.570796 /* pi / 2 */
|
||||||
|
#define E 2.718282 /* the venerable e */
|
||||||
|
#define SQRT2 1.414214 /* sqrt(2) */
|
||||||
|
#define SQRT3 1.732051 /* sqrt(3) */
|
||||||
|
#define GOLDEN 1.618034 /* the golden ratio */
|
||||||
|
#define DTOR 0.017453 /* convert degrees to radians */
|
||||||
|
#define RTOD 57.29578 /* convert radians to degrees */
|
||||||
|
|
||||||
|
|
||||||
|
/************/
|
||||||
|
/* booleans */
|
||||||
|
/************/
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
#define ON 1
|
||||||
|
#define OFF 0
|
||||||
|
typedef int boolean; /* boolean data type */
|
||||||
|
typedef boolean flag; /* flag data type */
|
||||||
|
|
||||||
|
extern double V2SquaredLength(), V2Length();
|
||||||
|
extern double V2Dot(), V2DistanceBetween2Points();
|
||||||
|
extern Vector2 *V2Negate(), *V2Normalize(), *V2Scale(), *V2Add(), *V2Sub();
|
||||||
|
extern Vector2 *V2Lerp(), *V2Combine(), *V2Mul(), *V2MakePerpendicular();
|
||||||
|
extern Vector2 *V2New(), *V2Duplicate();
|
||||||
|
extern Point2 *V2MulPointByMatrix();
|
||||||
|
extern Matrix3 *V2MatMul();
|
||||||
|
|
||||||
|
extern double V3SquaredLength(), V3Length();
|
||||||
|
extern double V3Dot(), V3DistanceBetween2Points();
|
||||||
|
extern Vector3 *V3Normalize(), *V3Scale(), *V3Add(), *V3Sub();
|
||||||
|
extern Vector3 *V3Lerp(), *V3Combine(), *V3Mul(), *V3Cross();
|
||||||
|
extern Vector3 *V3New(), *V3Duplicate();
|
||||||
|
extern Point3 *V3MulPointByMatrix();
|
||||||
|
extern Matrix4 *V3MatMul();
|
||||||
|
|
||||||
|
extern double RegulaFalsi(), NewtonRaphson(), findroot();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <pebble.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fast Circle-Rectangle Intersection Checking
|
||||||
|
by Clifford A. Shaffer
|
||||||
|
from "Graphics Gems", Academic Press, 1990
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GraphicsGems.h"
|
||||||
|
|
||||||
|
boolean Check_Intersect(R, C, Rad)
|
||||||
|
|
||||||
|
/* Return TRUE iff rectangle R intersects circle with centerpoint C and
|
||||||
|
radius Rad. */
|
||||||
|
Box2 *R;
|
||||||
|
Point2 *C;
|
||||||
|
double Rad;
|
||||||
|
{
|
||||||
|
double Rad2;
|
||||||
|
|
||||||
|
Rad2 = Rad * Rad;
|
||||||
|
/* Translate coordinates, placing C at the origin. */
|
||||||
|
R->max.x -= C->x; R->max.y -= C->y;
|
||||||
|
R->min.x -= C->x; R->min.y -= C->y;
|
||||||
|
|
||||||
|
if (R->max.x < 0) /* R to left of circle center */
|
||||||
|
if (R->max.y < 0) /* R in lower left corner */
|
||||||
|
return ((R->max.x * R->max.x + R->max.y * R->max.y) < Rad2);
|
||||||
|
else if (R->min.y > 0) /* R in upper left corner */
|
||||||
|
return ((R->max.x * R->max.x + R->min.y * R->min.y) < Rad2);
|
||||||
|
else /* R due West of circle */
|
||||||
|
return(ABS(R->max.x) < Rad);
|
||||||
|
else if (R->min.x > 0) /* R to right of circle center */
|
||||||
|
if (R->max.y < 0) /* R in lower right corner */
|
||||||
|
return ((R->min.x * R->min.x + R->max.y * R->max.y) < Rad2);
|
||||||
|
else if (R->min.y > 0) /* R in upper right corner */
|
||||||
|
return ((R->min.x * R->min.x + R->min.y * R->min.y) < Rad2);
|
||||||
|
else /* R due East of circle */
|
||||||
|
return (R->min.x < Rad);
|
||||||
|
else /* R on circle vertical centerline */
|
||||||
|
if (R->max.y < 0) /* R due South of circle */
|
||||||
|
return (ABS(R->max.y) < Rad);
|
||||||
|
else if (R->min.y > 0) /* R due North of circle */
|
||||||
|
return (R->min.y < Rad);
|
||||||
|
else /* R contains circle centerpoint */
|
||||||
|
return(TRUE);
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
#include <pebble.h>
|
||||||
|
|
||||||
|
#define DONT_INTERSECT 0
|
||||||
|
#define DO_INTERSECT 1
|
||||||
|
#define COLLINEAR 2
|
||||||
|
|
||||||
|
#define SAME_SIGNS( a, b ) \
|
||||||
|
(((long) ((unsigned long) a ^ (unsigned long) b)) >= 0 )
|
||||||
|
|
||||||
|
int lines_intersect(
|
||||||
|
x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
x3, y3,
|
||||||
|
x4, y4,
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
)
|
||||||
|
|
||||||
|
long x1, y1, x2, y2, x3, y3, x4, y4, *x, *y;
|
||||||
|
|
||||||
|
{
|
||||||
|
long a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */
|
||||||
|
long r1, r2, r3, r4; /* 'Sign' values */
|
||||||
|
long denom, offset, num; /* Intermediate values */
|
||||||
|
|
||||||
|
a1 = y2 - y1;
|
||||||
|
b1 = x1 - x2;
|
||||||
|
c1 = x2 * y1 - x1 * y2;
|
||||||
|
|
||||||
|
r3 = a1 * x3 + b1 * y3 + c1;
|
||||||
|
r4 = a1 * x4 + b1 * y4 + c1;
|
||||||
|
|
||||||
|
if ( r3 != 0 &&
|
||||||
|
r4 != 0 &&
|
||||||
|
SAME_SIGNS( r3, r4 ))
|
||||||
|
return ( DONT_INTERSECT );
|
||||||
|
|
||||||
|
a2 = y4 - y3;
|
||||||
|
b2 = x3 - x4;
|
||||||
|
c2 = x4 * y3 - x3 * y4;
|
||||||
|
|
||||||
|
r1 = a2 * x1 + b2 * y1 + c2;
|
||||||
|
r2 = a2 * x2 + b2 * y2 + c2;
|
||||||
|
|
||||||
|
if ( r1 != 0 &&
|
||||||
|
r2 != 0 &&
|
||||||
|
SAME_SIGNS( r1, r2 ))
|
||||||
|
return ( DONT_INTERSECT );
|
||||||
|
|
||||||
|
denom = a1 * b2 - a2 * b1;
|
||||||
|
if ( denom == 0 )
|
||||||
|
return ( COLLINEAR );
|
||||||
|
offset = denom < 0 ? - denom / 2 : denom / 2;
|
||||||
|
|
||||||
|
num = b1 * c2 - b2 * c1;
|
||||||
|
*x = ( num < 0 ? num - offset : num + offset ) / denom;
|
||||||
|
|
||||||
|
num = a2 * c1 - a1 * c2;
|
||||||
|
*y = ( num < 0 ? num - offset : num + offset ) / denom;
|
||||||
|
|
||||||
|
return ( DO_INTERSECT );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INTERSECTION_NONE 0
|
||||||
|
#define INTERSECTION_PARTIAL 1
|
||||||
|
#define INTERSECTION_FULL 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t success;
|
||||||
|
GPoint p1;
|
||||||
|
GPoint p2;
|
||||||
|
} Intersection;
|
||||||
|
|
||||||
|
Intersection rectintersect(GPoint p1, GPoint p2, GRect rect) {
|
||||||
|
long x,y;
|
||||||
|
long x1=0,y1=0,x2=0,y2=0;
|
||||||
|
bool intersection = false, final_intersection = false;
|
||||||
|
if (lines_intersect(p1.x, p1.y, p2.x, p2.y, rect.origin.x, rect.origin.y, rect.origin.x, rect.origin.y+rect.size.h, &x, &y) == DO_INTERSECT) {
|
||||||
|
x1 = x; y1 = y; intersection = true;
|
||||||
|
}
|
||||||
|
if (lines_intersect(p1.x, p1.y, p2.x, p2.y, rect.origin.x, rect.origin.y, rect.origin.x+rect.size.w, rect.origin.y, &x, &y) == DO_INTERSECT) {
|
||||||
|
if (!intersection) {
|
||||||
|
x1 = x; y1 = y; intersection = true;
|
||||||
|
} else {
|
||||||
|
x2 = x; y2 = y; final_intersection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!final_intersection && lines_intersect(p1.x, p1.y, p2.x, p2.y, rect.origin.x, rect.origin.y+rect.size.h, rect.origin.x+rect.size.w, rect.origin.y+rect.size.h, &x, &y) == DO_INTERSECT) {
|
||||||
|
if (!intersection) {
|
||||||
|
x1 = x; y1 = y; intersection = true;
|
||||||
|
} else {
|
||||||
|
x2 = x; y2 = y; final_intersection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!final_intersection && lines_intersect(p1.x, p1.y, p2.x, p2.y, rect.origin.x+rect.size.w, rect.origin.y, rect.origin.x+rect.size.w, rect.origin.y+rect.size.h, &x, &y) == DO_INTERSECT) {
|
||||||
|
if (!intersection) {
|
||||||
|
x1 = x; y1 = y;
|
||||||
|
} else {
|
||||||
|
x2 = x; y2 = y; final_intersection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(final_intersection) {
|
||||||
|
return (Intersection) { .success = INTERSECTION_FULL, .p1 = (GPoint) { .x = x1, .y = y1 }, .p2 = (GPoint) { .x = x2, .y = y2 } };
|
||||||
|
} else if (intersection) {
|
||||||
|
return (Intersection) { .success = INTERSECTION_PARTIAL, .p1 = (GPoint) { .x = x1, .y = y1 }, .p2 = (GPoint) { .x = x2, .y = y2 } };
|
||||||
|
} else {
|
||||||
|
return (Intersection) { .success = INTERSECTION_NONE, .p1 = (GPoint) { .x = x1, .y = y1 }, .p2 = (GPoint) { .x = x2, .y = y2 } };
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include <pebble.h>
|
||||||
|
#include <intersection.h>
|
||||||
|
|
||||||
|
static Window *s_main_window;
|
||||||
|
static Layer *s_canvas_layer;
|
||||||
|
|
||||||
|
static void canvas_update_proc(Layer *this_layer, GContext *ctx) {
|
||||||
|
//GRect bounds = layer_get_bounds(this_layer);
|
||||||
|
|
||||||
|
GRect rect = GRect(25, 15, 55, 70);
|
||||||
|
|
||||||
|
graphics_context_set_fill_color(ctx, GColorYellow);
|
||||||
|
|
||||||
|
graphics_fill_rect(ctx, rect, 0, GCornerNone);
|
||||||
|
|
||||||
|
graphics_context_set_stroke_width(ctx, 1);
|
||||||
|
graphics_context_set_stroke_color(ctx, GColorRed);
|
||||||
|
|
||||||
|
GPoint line_start = GPoint(50,90);
|
||||||
|
GPoint line_end = GPoint(99,10);
|
||||||
|
|
||||||
|
graphics_draw_line(ctx, line_start, line_end);
|
||||||
|
|
||||||
|
Intersection intersect = rectintersect(line_start, line_end, rect);
|
||||||
|
|
||||||
|
if (intersect.success >= INTERSECTION_FULL) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO, "Intersection");
|
||||||
|
graphics_context_set_stroke_color(ctx, GColorRed);
|
||||||
|
graphics_context_set_stroke_width(ctx, 3);
|
||||||
|
graphics_draw_line(ctx, intersect.p1, intersect.p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_load(Window *window) {
|
||||||
|
Layer *window_layer = window_get_root_layer(window);
|
||||||
|
GRect window_bounds = layer_get_bounds(window_layer);
|
||||||
|
|
||||||
|
// Create Layer
|
||||||
|
s_canvas_layer = layer_create(GRect(0, 0, window_bounds.size.w, window_bounds.size.h));
|
||||||
|
layer_add_child(window_layer, s_canvas_layer);
|
||||||
|
|
||||||
|
// Set the update_proc
|
||||||
|
layer_set_update_proc(s_canvas_layer, canvas_update_proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_unload(Window *window) {
|
||||||
|
// Destroy Layer
|
||||||
|
layer_destroy(s_canvas_layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init(void) {
|
||||||
|
// Create main Window
|
||||||
|
s_main_window = window_create();
|
||||||
|
window_set_window_handlers(s_main_window, (WindowHandlers) {
|
||||||
|
.load = main_window_load,
|
||||||
|
.unload = main_window_unload,
|
||||||
|
});
|
||||||
|
window_stack_push(s_main_window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit(void) {
|
||||||
|
// Destroy main Window
|
||||||
|
window_destroy(s_main_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
init();
|
||||||
|
app_event_loop();
|
||||||
|
deinit();
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file is the default set of rules to compile a Pebble project.
|
||||||
|
#
|
||||||
|
# Feel free to customize this to your needs.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
try:
|
||||||
|
from sh import CommandNotFound, jshint, cat, ErrorReturnCode_2
|
||||||
|
hint = jshint
|
||||||
|
except (ImportError, CommandNotFound):
|
||||||
|
hint = None
|
||||||
|
|
||||||
|
top = '.'
|
||||||
|
out = 'build'
|
||||||
|
|
||||||
|
def options(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def configure(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def build(ctx):
|
||||||
|
if False and hint is not None:
|
||||||
|
try:
|
||||||
|
hint([node.abspath() for node in ctx.path.ant_glob("src/**/*.js")], _tty_out=False) # no tty because there are none in the cloudpebble sandbox.
|
||||||
|
except ErrorReturnCode_2 as e:
|
||||||
|
ctx.fatal("\nJavaScript linting failed (you can disable this in Project Settings):\n" + e.stdout)
|
||||||
|
|
||||||
|
# Concatenate all our JS files (but not recursively), and only if any JS exists in the first place.
|
||||||
|
ctx.path.make_node('src/js/').mkdir()
|
||||||
|
js_paths = ctx.path.ant_glob(['src/*.js', 'src/**/*.js'])
|
||||||
|
if js_paths:
|
||||||
|
ctx(rule='cat ${SRC} > ${TGT}', source=js_paths, target='pebble-js-app.js')
|
||||||
|
has_js = True
|
||||||
|
else:
|
||||||
|
has_js = False
|
||||||
|
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
build_worker = os.path.exists('worker_src')
|
||||||
|
binaries = []
|
||||||
|
|
||||||
|
for p in ctx.env.TARGET_PLATFORMS:
|
||||||
|
ctx.set_env(ctx.all_envs[p])
|
||||||
|
ctx.set_group(ctx.env.PLATFORM_NAME)
|
||||||
|
app_elf='{}/pebble-app.elf'.format(p)
|
||||||
|
ctx.pbl_program(source=ctx.path.ant_glob('src/c/**/*.c'),
|
||||||
|
target=app_elf)
|
||||||
|
|
||||||
|
if build_worker:
|
||||||
|
worker_elf='{}/pebble-worker.elf'.format(p)
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
|
||||||
|
ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/c/**/*.c'),
|
||||||
|
target=worker_elf)
|
||||||
|
else:
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf})
|
||||||
|
|
||||||
|
ctx.set_group('bundle')
|
||||||
|
ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if has_js else [])
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example jshint configuration file for Pebble development.
|
||||||
|
*
|
||||||
|
* Check out the full documentation at http://www.jshint.com/docs/options/
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// Declares the existence of the globals available in PebbleKit JS.
|
||||||
|
"globals": {"localStorage": true, "Int16Array": true, "Uint32Array": true, "setTimeout": true, "Uint8ClampedArray": true, "navigator": true, "setInterval": true, "WebSocket": true, "Int32Array": true, "Uint8Array": true, "Float64Array": true, "Int8Array": true, "XMLHttpRequest": true, "Uint16Array": true, "Float32Array": true, "console": true, "Pebble": true},
|
||||||
|
|
||||||
|
// Do not mess with standard JavaScript objects (Array, Date, etc)
|
||||||
|
"freeze": true,
|
||||||
|
|
||||||
|
// Do not use eval! Keep this warning turned on (ie: false)
|
||||||
|
"evil": false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The options below are more style/developer dependent.
|
||||||
|
* Customize to your liking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// All variables should be in camelcase - too specific for CloudPebble builds to fail
|
||||||
|
// "camelcase": true,
|
||||||
|
|
||||||
|
// Do not allow blocks without { } - too specific for CloudPebble builds to fail.
|
||||||
|
// "curly": true,
|
||||||
|
|
||||||
|
// Prohibits the use of immediate function invocations without wrapping them in parentheses
|
||||||
|
"immed": true,
|
||||||
|
|
||||||
|
// Don't enforce indentation, because it's not worth failing builds over
|
||||||
|
// (especially given our somewhat lacklustre support for it)
|
||||||
|
"indent": false,
|
||||||
|
|
||||||
|
// Do not use a variable before it's defined
|
||||||
|
"latedef": "nofunc",
|
||||||
|
|
||||||
|
// Spot undefined variables
|
||||||
|
"undef": "true",
|
||||||
|
|
||||||
|
// Spot unused variables
|
||||||
|
"unused": "true"
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"author": "lastfuture@lastfuture.de",
|
||||||
|
"dependencies": {},
|
||||||
|
"keywords": [],
|
||||||
|
"name": "pdctest",
|
||||||
|
"pebble": {
|
||||||
|
"displayName": "pdctest",
|
||||||
|
"enableMultiJS": false,
|
||||||
|
"messageKeys": [],
|
||||||
|
"projectType": "native",
|
||||||
|
"resources": {
|
||||||
|
"media": [
|
||||||
|
{
|
||||||
|
"file": "data/moonshape4.pdc",
|
||||||
|
"name": "MOONSHAPE4",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "raw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "data/moonshape3.pdc",
|
||||||
|
"name": "MOONSHAPE3",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "raw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "data/moonshape2.pdc",
|
||||||
|
"name": "MOONSHAPE2",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "raw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "data/moonshape.pdc",
|
||||||
|
"name": "MOONSHAPE",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "raw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "data/image.pdc",
|
||||||
|
"name": "IMAGE",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "raw"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sdkVersion": "3",
|
||||||
|
"uuid": "2d00df02-2c1f-4217-b033-ba2b2024fdae",
|
||||||
|
"watchapp": {
|
||||||
|
"watchface": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* main.c - Sets up a Window and Layer that draws the GDrawCommandImage
|
||||||
|
* in its LayerUpdateProc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pebble.h>
|
||||||
|
|
||||||
|
static Window *s_main_window;
|
||||||
|
static Layer *s_canvas_layer;
|
||||||
|
|
||||||
|
static GDrawCommandImage *s_command_image;
|
||||||
|
|
||||||
|
static void update_proc(Layer *layer, GContext *ctx) {
|
||||||
|
// Place image in the center of the Window
|
||||||
|
GSize img_size = gdraw_command_image_get_bounds_size(s_command_image);
|
||||||
|
GRect bounds = layer_get_bounds(layer);
|
||||||
|
|
||||||
|
const GEdgeInsets frame_insets = {
|
||||||
|
.top = (bounds.size.h - img_size.h) / 2,
|
||||||
|
.left = (bounds.size.w - img_size.w) / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the image was loaded successfully...
|
||||||
|
if (s_command_image) {
|
||||||
|
// Draw it
|
||||||
|
gdraw_command_image_draw(ctx, s_command_image, grect_inset(bounds, frame_insets).origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_load(Window *window) {
|
||||||
|
Layer *window_layer = window_get_root_layer(window);
|
||||||
|
GRect bounds = layer_get_bounds(window_layer);
|
||||||
|
|
||||||
|
// Load the image and check it was succcessful
|
||||||
|
s_command_image = gdraw_command_image_create_with_resource(RESOURCE_ID_MOONSHAPE4);
|
||||||
|
if (!s_command_image) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Image is NULL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create canvas Layer and set up the update procedure
|
||||||
|
s_canvas_layer = layer_create(bounds);
|
||||||
|
layer_set_update_proc(s_canvas_layer, update_proc);
|
||||||
|
layer_add_child(window_layer, s_canvas_layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_unload(Window *window) {
|
||||||
|
// Destroy canvas Layer
|
||||||
|
layer_destroy(s_canvas_layer);
|
||||||
|
|
||||||
|
// Destroy the image
|
||||||
|
gdraw_command_image_destroy(s_command_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// Set up main Window
|
||||||
|
s_main_window = window_create();
|
||||||
|
window_set_background_color(s_main_window, GColorFromHEX(0xbbbbbb));
|
||||||
|
window_set_window_handlers(s_main_window, (WindowHandlers) {
|
||||||
|
.load = window_load,
|
||||||
|
.unload = window_unload,
|
||||||
|
});
|
||||||
|
window_stack_push(s_main_window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit() {
|
||||||
|
// Destroy main Window
|
||||||
|
window_destroy(s_main_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
app_event_loop();
|
||||||
|
deinit();
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file is the default set of rules to compile a Pebble project.
|
||||||
|
#
|
||||||
|
# Feel free to customize this to your needs.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
try:
|
||||||
|
from sh import CommandNotFound, jshint, cat, ErrorReturnCode_2
|
||||||
|
hint = jshint
|
||||||
|
except (ImportError, CommandNotFound):
|
||||||
|
hint = None
|
||||||
|
|
||||||
|
top = '.'
|
||||||
|
out = 'build'
|
||||||
|
|
||||||
|
def options(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def configure(ctx):
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
def build(ctx):
|
||||||
|
if False and hint is not None:
|
||||||
|
try:
|
||||||
|
hint([node.abspath() for node in ctx.path.ant_glob("src/**/*.js")], _tty_out=False) # no tty because there are none in the cloudpebble sandbox.
|
||||||
|
except ErrorReturnCode_2 as e:
|
||||||
|
ctx.fatal("\nJavaScript linting failed (you can disable this in Project Settings):\n" + e.stdout)
|
||||||
|
|
||||||
|
# Concatenate all our JS files (but not recursively), and only if any JS exists in the first place.
|
||||||
|
ctx.path.make_node('src/js/').mkdir()
|
||||||
|
js_paths = ctx.path.ant_glob(['src/*.js', 'src/**/*.js'])
|
||||||
|
if js_paths:
|
||||||
|
ctx(rule='cat ${SRC} > ${TGT}', source=js_paths, target='pebble-js-app.js')
|
||||||
|
has_js = True
|
||||||
|
else:
|
||||||
|
has_js = False
|
||||||
|
|
||||||
|
ctx.load('pebble_sdk')
|
||||||
|
|
||||||
|
build_worker = os.path.exists('worker_src')
|
||||||
|
binaries = []
|
||||||
|
|
||||||
|
for p in ctx.env.TARGET_PLATFORMS:
|
||||||
|
ctx.set_env(ctx.all_envs[p])
|
||||||
|
ctx.set_group(ctx.env.PLATFORM_NAME)
|
||||||
|
app_elf='{}/pebble-app.elf'.format(p)
|
||||||
|
ctx.pbl_program(source=ctx.path.ant_glob('src/c/**/*.c'),
|
||||||
|
target=app_elf)
|
||||||
|
|
||||||
|
if build_worker:
|
||||||
|
worker_elf='{}/pebble-worker.elf'.format(p)
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
|
||||||
|
ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/c/**/*.c'),
|
||||||
|
target=worker_elf)
|
||||||
|
else:
|
||||||
|
binaries.append({'platform': p, 'app_elf': app_elf})
|
||||||
|
|
||||||
|
ctx.set_group('bundle')
|
||||||
|
ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if has_js else [])
|
||||||
|
|
Loading…
Reference in New Issue