Ejemplo n.º 1
0
/*!
 * Asks for data from the accelerometer, and schedules itself for the future
 */
void accel_timer_callback()
{
    AccelData accel = {0, 0, 0, 0, 0};
    accel_service_peek(&accel);
    accel_handler(&accel, 1);
    accel_timer = app_timer_register(20, accel_timer_callback, NULL);
}
Layer* virtual_screen_init( GRect screen_bounds, GSize virtual_size,
                            VirutalScreenMode virtual_screen_mode) {
  s_max_point = GPoint(virtual_size.w-screen_bounds.size.w, virtual_size.h-screen_bounds.size.h);
  s_center_point = GPoint(s_max_point.x/2, s_max_point.y/2);
  
  switch(virtual_screen_mode) {
    case VIRTUAL_SCREEN_MODE_DIRECT: {
      s_accel_point = s_center_point;
    
      AccelData accel_data;
      accel_service_peek(&accel_data);
      s_reference_point = GPoint(accel_data.x, accel_data.y);
      
      s_timer = app_timer_register(VIRTUAL_SCREEN_UPDATE_TIMEOUT_MS, prv_direct_callback, NULL);
      break;
    }
    case VIRTUAL_SCREEN_MODE_AUTO: {
      s_timer = app_timer_register(VIRTUAL_SCREEN_UPDATE_AUTO_TIMEOUT_MS, prv_auto_callback, NULL);
      break;
    }
    case VIRTUAL_SCREEN_MODE_CENTERED:
    case VIRTUAL_SCREEN_MODE_TOP_LEFT:
    case VIRTUAL_SCREEN_MODE_TOP_RIGHT:
    case VIRTUAL_SCREEN_MODE_BOTTOM_LEFT:
    case VIRTUAL_SCREEN_MODE_BOTTOM_RIGHT: {
      s_timer = app_timer_register(10, prv_corner_callback, (void*)virtual_screen_mode);
      break;
    }
  }
  s_layer = layer_create(GRect(0, 0, virtual_size.w, virtual_size.h));
  return s_layer;
}
static void prv_direct_callback(void* data) {
  static AccelData last_accel_data;
  AccelData accel_data;
  accel_service_peek(&accel_data);
  if(   ABS(accel_data.x, last_accel_data.x) > VIRTUAL_SCREEN_UPDATE_THRESHOLD
     || ABS(accel_data.y, last_accel_data.y) > VIRTUAL_SCREEN_UPDATE_THRESHOLD) {
    s_accel_point = GPoint(
      s_center_point.x-(s_reference_point.x - accel_data.x)/VIRTUAL_SCREEN_UPDATE_SENSITIVITY,
      s_center_point.x+(s_reference_point.y - accel_data.y)/VIRTUAL_SCREEN_UPDATE_SENSITIVITY);
    if(s_accel_point.x > s_max_point.x) s_accel_point.x = s_max_point.x;
    if(s_accel_point.x < 0) s_accel_point.x = 0;
    if(s_accel_point.y > s_max_point.y) s_accel_point.y = s_max_point.y;
    if(s_accel_point.y < 0) s_accel_point.y = 0;
    GRect bounds = layer_get_bounds(s_layer);
    bounds.origin = GPoint(-s_accel_point.x, -s_accel_point.y);
    layer_set_bounds(s_layer, bounds);
    layer_mark_dirty(s_layer);
  }
  last_accel_data = accel_data;
  s_timer = app_timer_register(VIRTUAL_SCREEN_UPDATE_TIMEOUT_MS, prv_direct_callback, data);
}
Ejemplo n.º 4
0
// Advance the display by one tick
static void tick()
{
    AccelData accel;
    accel_service_peek(&accel);
    int16_t movement = 0;
    movement += abs_int16t(accel.x - old_accel.x);
    movement += abs_int16t(accel.y - old_accel.y);
    movement += abs_int16t(accel.z - old_accel.z);
    movement = deadzone_int16t(movement, 150);
    old_accel = accel;
    
    if (movement > 0)
    {
        level = level - STATUS_RECHARGE;
    }
    else
    {
        level = level + STATUS_CLOAK;
    }
    level = clamp(level, 0, STATUS_MAX);
    
    app_log(APP_LOG_LEVEL_DEBUG, __FILE__, __LINE__, "Accel: %d, Level: %d, Status: %d", movement, level, level / (STATUS_MAX / 10));
}
Ejemplo n.º 5
0
static void updateScreen(Layer *layer, GContext* ctx) {
	AccelData a;
	SnowFlake *s;
	int i, d, w;
	
	graphics_context_set_stroke_color(ctx, GColorWhite);
	graphics_context_set_fill_color(ctx, GColorWhite);

	if (accel_service_peek(&a) < 0) {
		w = 0;
	} else {
		w = a.x/250;
	}
  	
	for (i=0; i<NUMSNOWFLAKES; i++) {
		s = &snowflakes[i];
		if (s->p.y >= h[s->p.x]) {
			newSnowFlake(i, false);
			for (d=s->p.x-s->r; d<=s->p.x+s->r; d++) {
				stackSnowFlake(d);
			}
		}
		
		s->c++;
		if (s->c < MAXSTEPS) {
			d = 0;
		} else {
			s->c = 0;
			d = rand()%FUZZYNESS;
			if (rand()%2) d = -d;
		}
		
		s->p.x += d + w;
		if (s->p.x < 0) {
			s->p.x += WIDTH;
		}
		
		if (s->p.x >= WIDTH) {
			s->p.x -= WIDTH;
		}

		s->p.y += s->vs;
		
		graphics_fill_circle(ctx, s->p, s->r);
	}
	
	for (i=0; i<WIDTH; i++) {
		graphics_draw_line(ctx, GPoint(i, h[i]), GPoint(i, HEIGHT));
	}
	
	graphics_context_set_text_color(ctx, GColorBlack);
	for (i=0; i<4; i++) {
		graphics_draw_text(ctx, hourText, fontHour, bgHourRect[i], GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
#if defined(SHOWDATE)
    graphics_draw_text(ctx, dateText, fontDate, bgDateRect[i], GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
#endif
	}
	graphics_context_set_text_color(ctx, GColorWhite);
	graphics_draw_text(ctx, hourText, fontHour, hourRect, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
#if defined(SHOWDATE)
  graphics_draw_text(ctx, dateText, fontDate, dateRect, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
#endif
}
Ejemplo n.º 6
0
static void layer_update_callback(Layer *me, GContext* ctx) {

  // preparations
  GRect bounds = layer_get_bounds(me);
  uint16_t width = bounds.size.w;
  uint16_t height = bounds.size.h;
  uint16_t stride = (bounds.size.w + 31) / 32 * 32;
  uint16_t max = (height - 1) * stride + width;
  uint16_t shake = stride - width;
  uint16_t shake_stride = shake * stride;

  // handle shake
  if (do_shake) {
    do_shake = false;
    light_enable_interaction();
    for (uint16_t i = 0, j = rand(); i < NUM_FLAKES; i++, j+=31) {
      for (uint16_t k = 0; k < 2; k++, j+=31) {
        uint16_t next = flakes[i] + j % (max * 2) - max;
        if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) {
          flakes[i] = next;
          break;
        }
      }
    }
    last_time = 0;
  }

  // update time text
  time_t t = time(NULL);
  if (t / UPDATE_S > last_time) {
    last_time = t / UPDATE_S;
    char time_text[6];
    clock_copy_time_string(time_text, sizeof(time_text));

    graphics_context_set_fill_color(ctx, GColorBlack);
    graphics_fill_rect(ctx, bounds, 0, GCornerNone);

    GRect rect = (GRect) {{0, 60}, {width, 50}};
    GFont font = fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD);
    graphics_draw_text(ctx, time_text, font, rect, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL);

    graphics_context_set_stroke_color(ctx, GColorWhite);
    for (uint16_t i = 0, j = rand(); i < NUM_FLAKES; i++) {
      if (get_pixel(ctx, flakes[i]) == GColorBlack) {
        graphics_draw_pixel(ctx, GPoint(flakes[i] % stride, flakes[i] / stride));
      } else {
        for (uint16_t k = 0; k < 8; k++, j++) {
          uint16_t next = flakes[i] + (j % 9 / 3 - 1) * shake_stride + (j % 3 - 1) * shake;
          if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) {
            flakes[i] = next;
            graphics_draw_pixel(ctx, GPoint(flakes[i] % stride, flakes[i] / stride));
            break;
          }
        }
      }
    }
  }

  // apply physics
  AccelData accel = {.x = 0, .y = 0, .z = 0};
  accel_service_peek(&accel);
  uint16_t absx = accel.x < 0 ? -accel.x : accel.x;
  uint16_t absy = accel.y < 0 ? -accel.y : accel.y;
  uint16_t span = (absx + absy + 10) * SPEED;

  for (uint16_t i = 0, j = rand(), k = rand(), l = rand(); i < span; i++, j++, k++, l++) {
    uint16_t index = j % NUM_FLAKES;
    uint16_t next = flakes[index];

    int16_t sideway = k % 3 == 0 ? l % 5 - 2 : 0;
    int16_t accx = accel.x + accel.y * sideway;
    int16_t accy = accel.y - accel.x * sideway;
    absx = accx < 0 ? -accx : accx;
    absy = accy < 0 ? -accy : accy;

    if (absx > absy || k % absy < absx) {
      if (accx > 0) {
        next++;
      } else {
        next--;
      }
    }
    if (absy > absx || l % absx < absy) {
      if (accy > 0) {
        next -= stride;
      } else {
        next += stride;
      }
    }
    if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) {
      graphics_context_set_stroke_color(ctx, GColorBlack);
      graphics_draw_pixel(ctx, GPoint(flakes[index] % stride, flakes[index] / stride));
      graphics_context_set_stroke_color(ctx, GColorWhite);
      graphics_draw_pixel(ctx, GPoint(next % stride, next / stride));
      flakes[index] = next;
    }
  }

  if (!timer) timer = app_timer_register(UPDATE_MS, timer_callback, NULL);
}

static void handle_accel(AccelData *accel_data, uint32_t num_samples) {
  // or else I will crash
}

static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
  do_shake = true;
}

static void root_update_callback(Layer *me, GContext* ctx) {
  // hack to prevent screen cleaning
}

static void window_load(Window *window) {
  Layer *window_layer = window_get_root_layer(window);
  layer_set_update_proc(window_layer, root_update_callback);
  GRect bounds = layer_get_bounds(window_layer);

  layer = layer_create(bounds);
  layer_set_update_proc(layer, layer_update_callback);
  layer_add_child(window_layer, layer);

  uint16_t width = bounds.size.w;
  uint16_t height = bounds.size.h;
  uint16_t stride = (bounds.size.w + 31) / 32 * 32;
  for (uint16_t i = 0; i < NUM_FLAKES; i++) {
    flakes[i] = rand() % height * stride + rand() % width;
  }
}
Ejemplo n.º 7
0
void simply_accel_peek(SimplyAccel *self, AccelData *data) {
  if (self->data_subscribed) {
    return;
  }
  accel_service_peek(data);
}
Ejemplo n.º 8
0
static void data_handler(void* out) {
  app_timer_register(30, data_handler, NULL);
  layer_mark_dirty(s_player_layer);
  
  
  //you win
  if (playerY == mazeHeight-1 && playerX == mazeWidth-1 && dx==0 && dy==0){
    vibes_short_pulse();
    load(mazeWidth,mazeHeight,corridorSize);
    return;
  }
  
  int speed = difficulty==1?2:1;
  if(dx!=0 || dy!=0) {
    if(dx<0) dx+=speed;
    if(dx>0) dx-=speed;
    if(dy<0) dy+=speed;
    if(dy>0) dy-=speed;
    
    return;
  }
  
  AccelData* data = malloc(sizeof(*data));
  accel_service_peek(data);
  

  if(data->x*data->x + data->y*data->y > 150*150) {
    //left, right, up, down, just like maze.c
    int xopts[4] = {-1,1,0,0};
    int yopts[4] = {0,0,-1,1};
    int bestopt=0, bestscore=0;
    int xmag = abs(data->x),
        ymag = abs(data->y);
    //app_log(APP_LOG_LEVEL_INFO,"main.c",1337,"mag %i %i",xmag,ymag);
    for(int i=0; i<4; i++) {
      int newx = playerX+xopts[i],
          newy = playerY+yopts[i];
      //bounds checking
      int curscore = (newx>=0 && newy>=0 && newx<mazeWidth && newy < mazeHeight) ? 1 : 0;
      //wall checking
      if(i<2) {//x
        curscore *= 1-maze[getPOS(playerY,(xopts[i]==1?playerX:newx),mazeWidth)].r;
        curscore *= xmag<50?0:xopts[i]*data->x;
      } else {//y
        curscore *= 1-maze[getPOS((yopts[i]==1?playerY:newy),playerX,mazeWidth)].b;
        curscore *= ymag<50?0:-yopts[i]*data->y;
      }
      //app_log(APP_LOG_LEVEL_INFO,"main.c",1338,"score %i %i",i,curscore);
      if(curscore > bestscore) {
        bestopt = i;
        bestscore = curscore;
      }
    }
    if(bestscore>0) {
      lightup();
      playerX += xopts[bestopt];
      playerY += yopts[bestopt];
      dx -= xopts[bestopt]*(corridorSize-speed);
      dy -= yopts[bestopt]*(corridorSize-speed);
    }
  }
  free(data);
}