commit 3cf894b67fadc9c83791e2b08944d80dea4e8750
Author: Alina Marquardt <lastfuture@lastfuture.de>
Date:   Tue Apr 4 20:48:51 2023 +0200

    initial commit

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..883196c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Pebble tests
+Various tests and experiments for the Pebble smartwatch platforms
diff --git a/colortest-290905/jshintrc b/colortest-290905/jshintrc
new file mode 100644
index 0000000..8c6328d
--- /dev/null
+++ b/colortest-290905/jshintrc
@@ -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"
+}
diff --git a/colortest-290905/package.json b/colortest-290905/package.json
new file mode 100644
index 0000000..0042f45
--- /dev/null
+++ b/colortest-290905/package.json
@@ -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"
+}
diff --git a/colortest-290905/src/c/main.c b/colortest-290905/src/c/main.c
new file mode 100644
index 0000000..80366af
--- /dev/null
+++ b/colortest-290905/src/c/main.c
@@ -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();
+}
\ No newline at end of file
diff --git a/colortest-290905/wscript b/colortest-290905/wscript
new file mode 100644
index 0000000..ce05875
--- /dev/null
+++ b/colortest-290905/wscript
@@ -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 [])
+    
\ No newline at end of file
diff --git a/line_seg-295810/jshintrc b/line_seg-295810/jshintrc
new file mode 100644
index 0000000..8c6328d
--- /dev/null
+++ b/line_seg-295810/jshintrc
@@ -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"
+}
diff --git a/line_seg-295810/package.json b/line_seg-295810/package.json
new file mode 100644
index 0000000..3dbfc5f
--- /dev/null
+++ b/line_seg-295810/package.json
@@ -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"
+}
diff --git a/line_seg-295810/src/c/GraphicsGems.h b/line_seg-295810/src/c/GraphicsGems.h
new file mode 100644
index 0000000..49c93a6
--- /dev/null
+++ b/line_seg-295810/src/c/GraphicsGems.h
@@ -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
\ No newline at end of file
diff --git a/line_seg-295810/src/c/circlerect.h b/line_seg-295810/src/c/circlerect.h
new file mode 100644
index 0000000..9fece1c
--- /dev/null
+++ b/line_seg-295810/src/c/circlerect.h
@@ -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);
+    } 	
\ No newline at end of file
diff --git a/line_seg-295810/src/c/intersection.h b/line_seg-295810/src/c/intersection.h
new file mode 100644
index 0000000..c865113
--- /dev/null
+++ b/line_seg-295810/src/c/intersection.h
@@ -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 } };
+  }
+}
\ No newline at end of file
diff --git a/line_seg-295810/src/c/main.c b/line_seg-295810/src/c/main.c
new file mode 100644
index 0000000..89774d5
--- /dev/null
+++ b/line_seg-295810/src/c/main.c
@@ -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();
+}
diff --git a/line_seg-295810/wscript b/line_seg-295810/wscript
new file mode 100644
index 0000000..ce05875
--- /dev/null
+++ b/line_seg-295810/wscript
@@ -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 [])
+    
\ No newline at end of file
diff --git a/pdctest-281063/jshintrc b/pdctest-281063/jshintrc
new file mode 100644
index 0000000..8c6328d
--- /dev/null
+++ b/pdctest-281063/jshintrc
@@ -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"
+}
diff --git a/pdctest-281063/package.json b/pdctest-281063/package.json
new file mode 100644
index 0000000..1dc270a
--- /dev/null
+++ b/pdctest-281063/package.json
@@ -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"
+}
diff --git a/pdctest-281063/resources/data/image.pdc b/pdctest-281063/resources/data/image.pdc
new file mode 100644
index 0000000..adb4e24
Binary files /dev/null and b/pdctest-281063/resources/data/image.pdc differ
diff --git a/pdctest-281063/resources/data/moonshape.pdc b/pdctest-281063/resources/data/moonshape.pdc
new file mode 100644
index 0000000..3a0c180
Binary files /dev/null and b/pdctest-281063/resources/data/moonshape.pdc differ
diff --git a/pdctest-281063/resources/data/moonshape2.pdc b/pdctest-281063/resources/data/moonshape2.pdc
new file mode 100644
index 0000000..7bd1fc4
Binary files /dev/null and b/pdctest-281063/resources/data/moonshape2.pdc differ
diff --git a/pdctest-281063/resources/data/moonshape3.pdc b/pdctest-281063/resources/data/moonshape3.pdc
new file mode 100644
index 0000000..a09835a
Binary files /dev/null and b/pdctest-281063/resources/data/moonshape3.pdc differ
diff --git a/pdctest-281063/resources/data/moonshape4.pdc b/pdctest-281063/resources/data/moonshape4.pdc
new file mode 100644
index 0000000..ae16606
Binary files /dev/null and b/pdctest-281063/resources/data/moonshape4.pdc differ
diff --git a/pdctest-281063/src/c/main.c b/pdctest-281063/src/c/main.c
new file mode 100644
index 0000000..4c6b23c
--- /dev/null
+++ b/pdctest-281063/src/c/main.c
@@ -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();
+}
\ No newline at end of file
diff --git a/pdctest-281063/wscript b/pdctest-281063/wscript
new file mode 100644
index 0000000..ce05875
--- /dev/null
+++ b/pdctest-281063/wscript
@@ -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 [])
+    
\ No newline at end of file