Blob Blame Raw

#include <math.h>
#include <stdio.h>
#include <helianthus.h>


unsigned long long prevMonotonicMs;

int hours, minutes, seconds;
int mills;

int started;
int alarm;

Sound alarmSound;


void init() {
  alarmSound = createSound("data/sound/alarmclock.ogg");
}


void draw() {
  unsigned long long monotonicMs = windowGetMonotonicMilliseconds();
  int timeMs = (int)(monotonicMs - prevMonotonicMs);
  prevMonotonicMs = monotonicMs;

  if (started) {
    if (alarm) {
      mills += timeMs;
      while(mills >= 1000) mills -= 1000;
    } else {
      mills += timeMs;
      while(mills >= 1000) { mills -= 1000; --seconds; }
      while(seconds < 0) { --minutes; seconds += 60; }
      while(minutes < 0) { --hours; minutes += 60; }
      if (hours < 0 || (hours == 0 && minutes == 0 && seconds == 0)) {
        hours = 0;
        minutes = 0;
        seconds = 0;
        alarm = TRUE;
        soundPlay(alarmSound, TRUE);
      }
    }
  }

  saveState();
  translate( windowGetWidth()/2.0, windowGetHeight()/2.0 );

  textAlign(HALIGN_CENTER, VALIGN_CENTER);

  double size = 100;
  int *values[3] = { &hours, &minutes, &seconds };
  for(int i = 0; i < 3; ++i) {
    int *value = values[i];

    saveState();
    translate( (i-1)*size, 0 );
    textSize(64);
    if (alarm) stroke(colorByRGBA(0, 0, 0, mills*0.001));

    double mx = mouseTransformedX();
    double my = mouseTransformedY();
    if (fabs(mx) <= 0.45*size && fabs(my) <= 0.45*size) {
      *value += mouseScrolledY();
      while(*value <   0) *value += 60;
      while(*value >= 60) *value -= 60;
      if (mouseWentDown("left")) *value = 0;
      if (mouseWentDown("right")) *value = 30;
    }

    textf(-0.2*size, 0, "%d", *value / 10);
    textf( 0.2*size, 0, "%d", *value % 10);

    if (i > 0) {
      translate( -size/2, 0 );
      text(0, 0, ":");
    }

    restoreState();
  }

  if (started) {
    saveState();
    strokeWidth(0.1*size);
    if (alarm) stroke(colorByRGBA(0, 0, 0, mills*0.001)); else rotate(-60*0.001*mills);
    for(int i = 0; i < 12; ++i) {
      point(2*size, 0);
      rotate(-30);
    }
    restoreState();
  }

  saveState();
  {
    noFill();
    textSize(24);
    double buttonWidth = size*1.5;
    double buttonHeight = size*0.5;
    translate(-0.5*buttonWidth, 0.75*size);

    double mx = mouseTransformedX();
    double my = mouseTransformedY();
    int click = mouseWentDown("left") && fabs(mx) <= 0.4*buttonWidth && fabs(my) <= 0.4*buttonHeight;
    rect(-0.4*buttonWidth, -0.4*buttonHeight, 0.8*buttonWidth, 0.8*buttonHeight);
    if (started) {
      text(0, 0, "pause");
      if (click) {
        soundStop(alarmSound);
        started = alarm = FALSE;
      }
    } else {
      text(0, 0, "start");
      if (click) { mills = 0; started = TRUE; }
    }

    translate(buttonWidth, 0);
    mx -= buttonWidth;
    click = mouseWentDown("left") && fabs(mx) <= 0.4*buttonWidth && fabs(my) <= 0.4*buttonHeight;
    rect(-0.4*buttonWidth, -0.4*buttonHeight, 0.8*buttonWidth, 0.8*buttonHeight);
    text(0, 0, "reset");
    if (click) {
      soundStop(alarmSound);
      started = alarm = FALSE;
      hours = minutes= seconds = 0;
    }
  }
  restoreState();

  restoreState();
}


int main() {
  windowSetTitle("Timer");
  windowSetVariableFrameRate();
  windowSetInit(&init);
  windowSetDraw(&draw);
  windowRun();
  return 0;
}