Blame onefile/history-dates.c

Ivan Mahonin 261920
Ivan Mahonin 261920
#include <helianthus.h>
Ivan Mahonin 261920
#include <stdio.h>
Ivan Mahonin 261920
#include <string.h>
Ivan Mahonin 261920
#include <ctype.h>
Ivan Mahonin 261920
#include <math.h>
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
#define MAXREC       1000
Ivan Mahonin 261920
#define MARGINX      30.0
Ivan Mahonin 261920
#define MARGINY      15.0
Ivan Mahonin 261920
#define MARGINLINE0  30.0
Ivan Mahonin 261920
#define MARGINLINE1  40.0
Ivan Mahonin 261920
#define BASELINE     22.0
Ivan Mahonin 261920
#define PADDING      15.0
Ivan Mahonin 261920
#define SEPARATOR    15.0
Ivan Mahonin 261920
#define TEXTWIDTH   300.0
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  char text[128];
Ivan Mahonin 261920
  double w;
Ivan Mahonin 261920
  double h;
Ivan Mahonin 261920
} Date;
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  char text[1024];
Ivan Mahonin 261920
  double w;
Ivan Mahonin 261920
  double h;
Ivan Mahonin 261920
} Text;
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  char text[128];
Ivan Mahonin 261920
  int index;
Ivan Mahonin 261920
  int begin;
Ivan Mahonin 261920
  int end;
Ivan Mahonin 261920
  double w;
Ivan Mahonin 261920
  double y0;
Ivan Mahonin 261920
  double y1;
Ivan Mahonin 261920
} Part;
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  double x, w;
Ivan Mahonin 261920
} Column;
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  Date date;
Ivan Mahonin 261920
  Text text;
Ivan Mahonin 261920
  Part part;
Ivan Mahonin 261920
} BaseRecord;
Ivan Mahonin 261920
Ivan Mahonin 261920
typedef struct {
Ivan Mahonin 261920
  Date *date;
Ivan Mahonin 261920
  Text *text;
Ivan Mahonin 261920
  Part *part;
Ivan Mahonin 261920
  double y;
Ivan Mahonin 261920
} Record;
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
BaseRecord recordsSrc[MAXREC];
Ivan Mahonin 261920
Record records[MAXREC];
Ivan Mahonin 261920
Part *parts[MAXREC];
Ivan Mahonin 261920
Date *dates[MAXREC];
Ivan Mahonin 261920
Column columns[MAXREC];
Ivan Mahonin 261920
int partCount;
Ivan Mahonin 261920
int dateCount;
Ivan Mahonin 261920
int recCount;
Ivan Mahonin 261920
int colCount;
Ivan Mahonin 261920
double datesWidth;
Ivan Mahonin 261920
double fullWidth, fullHeight;
Ivan Mahonin 261920
Ivan Mahonin 261920
double dx, dy;
Ivan Mahonin 261920
double mx, my;
Ivan Mahonin 261920
double zm = 1;
Ivan Mahonin 261920
Ivan Mahonin 261920
int curRec;
Ivan Mahonin 261920
double curFade;
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void updateLayout();
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
double calcWidth(char *b, char *e) {
Ivan Mahonin 261920
  char c = *e;
Ivan Mahonin 261920
  *e = 0;
Ivan Mahonin 261920
  TextLayout tl = createTextLayout(b);
Ivan Mahonin 261920
  *e = c;
Ivan Mahonin 261920
  double w = textLayoutGetWidth(tl);
Ivan Mahonin 261920
  textLayoutDestroy(tl);
Ivan Mahonin 261920
  return w;
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
void wordWrap(char *buf, double maxWidth) {
Ivan Mahonin 261920
  int len = strlen(buf);
Ivan Mahonin 261920
  if (calcWidth(buf, buf + len) <= maxWidth) return;
Ivan Mahonin 261920
Ivan Mahonin 261920
  char *last = NULL;
Ivan Mahonin 261920
  for(char *p = buf + len - 1; p > buf; --p) {
Ivan Mahonin 261920
    if (isspace(*p)) {
Ivan Mahonin 261920
      last = p;
Ivan Mahonin 261920
      if (calcWidth(buf, p) < maxWidth)
Ivan Mahonin 261920
        { *p = '\n'; wordWrap(p+1, maxWidth); return; }
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
  if (!last) return;
Ivan Mahonin 261920
Ivan Mahonin 261920
  *last = '\n';
Ivan Mahonin 261920
  wordWrap(last+1, maxWidth);
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void load(const char *filename) {
Ivan Mahonin 261920
  curRec = 0;
Ivan Mahonin 261920
  curFade = 0;
Ivan Mahonin 261920
  recCount = 0;
Ivan Mahonin 261920
  partCount = 0;
Ivan Mahonin 261920
  dateCount = 0;
Ivan Mahonin 261920
  colCount = 0;
Ivan Mahonin 261920
  datesWidth = 0;
Ivan Mahonin 261920
  memset(recordsSrc, 0, sizeof(recordsSrc));
Ivan Mahonin 261920
  memset(records, 0, sizeof(records));
Ivan Mahonin 261920
  memset(parts, 0, sizeof(parts));
Ivan Mahonin 261920
  memset(dates, 0, sizeof(dates));
Ivan Mahonin 261920
  memset(columns, 0, sizeof(columns));
Ivan Mahonin 261920
Ivan Mahonin 261920
  FILE *f = fopen(filename, "r");
Ivan Mahonin 261920
  if (!f) {
Ivan Mahonin 261920
    printf("cannot open file for read: %s\n", filename);
Ivan Mahonin 261920
    return;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  int mode = 0;
Ivan Mahonin 261920
  BaseRecord *rs = recordsSrc;
Ivan Mahonin 261920
  char *p = rs->date.text;
Ivan Mahonin 261920
  char *e = p + sizeof(rs->date.text);
Ivan Mahonin 261920
  while(1) {
Ivan Mahonin 261920
    int c = fgetc(f);
Ivan Mahonin 261920
    if (c <= 0 || c >= 256) break;
Ivan Mahonin 261920
    if (c == '\t') {
Ivan Mahonin 261920
      if (mode == 0) {
Ivan Mahonin 261920
        mode = 1; p = rs->text.text; e = p + sizeof(rs->text.text);
Ivan Mahonin 261920
      } else
Ivan Mahonin 261920
      if (mode == 1) {
Ivan Mahonin 261920
        mode = 2; p = rs->part.text; e = p + sizeof(rs->part.text);
Ivan Mahonin 261920
      } else
Ivan Mahonin 261920
      if (mode == 2) {
Ivan Mahonin 261920
        mode = 3;
Ivan Mahonin 261920
      }
Ivan Mahonin 261920
    } else
Ivan Mahonin 261920
    if (c == '\n') {
Ivan Mahonin 261920
        if (rs->date.text[0] || rs->text.text[0] || rs->part.text[0]) {
Ivan Mahonin 261920
          ++recCount; ++rs;
Ivan Mahonin 261920
          if (recCount >= MAXREC) break;
Ivan Mahonin 261920
        }
Ivan Mahonin 261920
        mode = 0; p = rs->date.text; e = p + sizeof(rs->date.text);
Ivan Mahonin 261920
    } else
Ivan Mahonin 261920
    if (c != '\r' && p+1 < e) {
Ivan Mahonin 261920
      *p++ = c;
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
  fclose(f);
Ivan Mahonin 261920
Ivan Mahonin 261920
  if (recCount < MAXREC)
Ivan Mahonin 261920
    if (rs->date.text[0] || rs->text.text[0] || rs->part.text[0])
Ivan Mahonin 261920
      ++recCount;
Ivan Mahonin 261920
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    BaseRecord *rs = &recordsSrc[i];
Ivan Mahonin 261920
    wordWrap(rs->text.text, TEXTWIDTH);
Ivan Mahonin 261920
Ivan Mahonin 261920
    for(int j = 0; j <= i; ++j) {
Ivan Mahonin 261920
      BaseRecord *rrs = &recordsSrc[j];
Ivan Mahonin 261920
      if (!r->date && !strcmp(rs->date.text, rrs->date.text)) r->date = &rrs->date;
Ivan Mahonin 261920
      if (!r->text && !strcmp(rs->text.text, rrs->text.text)) r->text = &rrs->text;
Ivan Mahonin 261920
      if (!r->part && !strcmp(rs->part.text, rrs->part.text)) r->part = &rrs->part;
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
    if (r->part == &rs->part)
Ivan Mahonin 261920
      parts[partCount++] = r->part;
Ivan Mahonin 261920
    if (r->date == &rs->date)
Ivan Mahonin 261920
      dates[dateCount++] = r->date;
Ivan Mahonin 261920
Ivan Mahonin 261920
    TextLayout tl = createTextLayout(r->text->text);
Ivan Mahonin 261920
    r->text->w = textLayoutGetWidth(tl);
Ivan Mahonin 261920
    r->text->h = textLayoutGetHeight(tl);
Ivan Mahonin 261920
    textLayoutDestroy(tl);
Ivan Mahonin 261920
Ivan Mahonin 261920
    tl = createTextLayout(r->date->text);
Ivan Mahonin 261920
    r->date->w = textLayoutGetWidth(tl);
Ivan Mahonin 261920
    r->date->h = textLayoutGetHeight(tl);
Ivan Mahonin 261920
    textLayoutDestroy(tl);
Ivan Mahonin 261920
Ivan Mahonin 261920
    if (r->part->w < r->text->w)
Ivan Mahonin 261920
      r->part->w = r->text->w;
Ivan Mahonin 261920
    if (datesWidth < r->date->w)
Ivan Mahonin 261920
      datesWidth = r->date->w;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  updateLayout();
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void writeUnwrapped(const char *buf, FILE *f) {
Ivan Mahonin 261920
  while(*buf) {
Ivan Mahonin 261920
    fputc(*buf == '\n' ? ' ' : *buf, f);
Ivan Mahonin 261920
    ++buf;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void save(const char *filename) {
Ivan Mahonin 261920
  FILE *f = fopen(filename, "w");
Ivan Mahonin 261920
  if (!f) {
Ivan Mahonin 261920
    printf("cannot open file for write: %s\n", filename);
Ivan Mahonin 261920
    return;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    writeUnwrapped(r->date->text, f); fputc('\t', f);
Ivan Mahonin 261920
    writeUnwrapped(r->text->text, f); fputc('\t', f);
Ivan Mahonin 261920
    writeUnwrapped(r->part->text, f); fputc('\n', f);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  fclose(f);
Ivan Mahonin 261920
  printf("saved into: %s\n", filename);
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void updateLayout() {
Ivan Mahonin 261920
  colCount = 0;
Ivan Mahonin 261920
  for(int i = 0; i < partCount; ++i) {
Ivan Mahonin 261920
    parts[i]->index = -1;
Ivan Mahonin 261920
    columns[i].w = 0;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  double y = MARGINY + PADDING;
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    Part *p = r->part;
Ivan Mahonin 261920
    if (p->index < 0) {
Ivan Mahonin 261920
      int idx = 0;
Ivan Mahonin 261920
      while(p->text[idx] == '~') ++idx;
Ivan Mahonin 261920
      while(1) {
Ivan Mahonin 261920
        int found = TRUE;
Ivan Mahonin 261920
        for(int j = i+1; j < recCount; ++j)
Ivan Mahonin 261920
          if (records[j].part->index == idx)
Ivan Mahonin 261920
            found = FALSE;
Ivan Mahonin 261920
        if (found) break;
Ivan Mahonin 261920
        ++idx;
Ivan Mahonin 261920
      }
Ivan Mahonin 261920
      p->index = idx;
Ivan Mahonin 261920
      p->begin = i;
Ivan Mahonin 261920
      p->y0 = y;
Ivan Mahonin 261920
Ivan Mahonin 261920
      if (colCount <= idx) colCount = idx + 1;
Ivan Mahonin 261920
      if (columns[idx].w < p->w) columns[idx].w = p->w;
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
Ivan Mahonin 261920
    if (i > 0) {
Ivan Mahonin 261920
      if (p == records[i-1].part) {
Ivan Mahonin 261920
        y += SEPARATOR;
Ivan Mahonin 261920
      } else {
Ivan Mahonin 261920
        for(int j = i-1; j >= 0; --j) {
Ivan Mahonin 261920
          if (records[j].part->index == p->index) {
Ivan Mahonin 261920
            double py = records[j].part->y1 + 2*PADDING + MARGINY;
Ivan Mahonin 261920
            if (y < py) y = py;
Ivan Mahonin 261920
          }
Ivan Mahonin 261920
        }
Ivan Mahonin 261920
      }
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
Ivan Mahonin 261920
    r->y = y;
Ivan Mahonin 261920
    p->end = i + 1;
Ivan Mahonin 261920
    if (p->begin == i) p->y0 = r->y;
Ivan Mahonin 261920
    p->y1 = y + r->text->h;
Ivan Mahonin 261920
Ivan Mahonin 261920
    y = p->y1;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  double x = MARGINX + PADDING + datesWidth + PADDING + MARGINLINE0 + MARGINLINE1 + MARGINX;
Ivan Mahonin 261920
  for(int i = 0; i < colCount; ++i) {
Ivan Mahonin 261920
    columns[i].x = x;
Ivan Mahonin 261920
    x += columns[i].w + 2*PADDING + MARGINX;
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
  fullWidth = x;
Ivan Mahonin 261920
  fullHeight = y + PADDING + MARGINY;
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void drawRect(double x, double y, double w, double h) {
Ivan Mahonin 261920
  noFill();
Ivan Mahonin 261920
  stroke(COLOR_WHITE);
Ivan Mahonin 261920
  strokeWidth(4);
Ivan Mahonin 261920
  rectRounded( x - PADDING, y - PADDING, w + 2*PADDING, h + 2*PADDING, PADDING );
Ivan Mahonin 261920
  fill(colorByRGBA(1, 1, 1, 0.75));
Ivan Mahonin 261920
  stroke(COLOR_BLUE);
Ivan Mahonin 261920
  strokeWidth(2);
Ivan Mahonin 261920
  rectRounded( x - PADDING, y - PADDING, w + 2*PADDING, h + 2*PADDING, PADDING );
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void drawRecords() {
Ivan Mahonin 261920
  saveState();
Ivan Mahonin 261920
Ivan Mahonin 261920
  strokeWidth(2);
Ivan Mahonin 261920
  stroke(COLOR_BLUE);
Ivan Mahonin 261920
Ivan Mahonin 261920
  double mr = PADDING/4.0;
Ivan Mahonin 261920
Ivan Mahonin 261920
  // lines
Ivan Mahonin 261920
  double xl = MARGINX + PADDING + datesWidth + PADDING + MARGINLINE0;
Ivan Mahonin 261920
  double xd = xl - MARGINLINE0;
Ivan Mahonin 261920
  double h = 0;
Ivan Mahonin 261920
  if (recCount > 0)
Ivan Mahonin 261920
    h = records[recCount-1].y + records[recCount-1].text->h + MARGINY + PADDING;
Ivan Mahonin 261920
  line(xl, 0, xl, h);
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    double x = columns[ r->part->index ].x;
Ivan Mahonin 261920
    double y = r->y + BASELINE;
Ivan Mahonin 261920
    line(xd, y, x, y);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  // text rects
Ivan Mahonin 261920
  for(int i = 0; i < partCount; ++i) {
Ivan Mahonin 261920
    Part *p = parts[i];
Ivan Mahonin 261920
    Column *c = &columns[p->index];
Ivan Mahonin 261920
    drawRect(c->x + PADDING, p->y0, p->w, p->y1 - p->y0);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  // circles
Ivan Mahonin 261920
  fill(COLOR_WHITE);
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    double x = columns[ r->part->index ].x;
Ivan Mahonin 261920
    double y = r->y + BASELINE;
Ivan Mahonin 261920
    double mrr = i == curRec ? mr + curFade*mr : mr;
Ivan Mahonin 261920
    circle(xl, y, mrr);
Ivan Mahonin 261920
    circle(x, y, mrr);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  // texts
Ivan Mahonin 261920
  noFill();
Ivan Mahonin 261920
  stroke(COLOR_BLACK);
Ivan Mahonin 261920
  for(int i = 0; i < recCount; ++i) {
Ivan Mahonin 261920
    Record *r = &records[i];
Ivan Mahonin 261920
    Part *p = r->part;
Ivan Mahonin 261920
    Date *d = r->date;
Ivan Mahonin 261920
    double x = columns[ p->index ].x + PADDING;
Ivan Mahonin 261920
    double y = r->y;
Ivan Mahonin 261920
    text(x, y, r->text->text);
Ivan Mahonin 261920
    text(xd - PADDING - d->w, y, d->text);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  restoreState();
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void saveImage(const char *filename) {
Ivan Mahonin 261920
  double s = 1;
Ivan Mahonin 261920
  Framebuffer fb = createFramebuffer((int)(fullWidth*s) + 1, (int)(fullHeight*s) + 1);
Ivan Mahonin 261920
Ivan Mahonin 261920
  saveState();
Ivan Mahonin 261920
  target(fb);
Ivan Mahonin 261920
  clear();
Ivan Mahonin 261920
  zoom(s);
Ivan Mahonin 261920
  drawRecords();
Ivan Mahonin 261920
  if (viewportSave(filename))
Ivan Mahonin 261920
    printf("image saved into: %s\n", filename);
Ivan Mahonin 261920
  restoreState();
Ivan Mahonin 261920
Ivan Mahonin 261920
  framebufferDestroy(fb);
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void init() {
Ivan Mahonin 261920
  if (fileExists("data/output/history/ancient-dates.txt"))
Ivan Mahonin 261920
    load("data/output/history/ancient-dates.txt");
Ivan Mahonin 261920
  else
Ivan Mahonin 261920
    load("data/history/ancient-dates.txt");
Ivan Mahonin 261920
Ivan Mahonin 261920
  dx = -fullWidth/2;
Ivan Mahonin 261920
  dy = -450;
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
void draw() {
Ivan Mahonin 261920
  double w = windowGetWidth();
Ivan Mahonin 261920
  double h = windowGetHeight();
Ivan Mahonin 261920
Ivan Mahonin 261920
  double pmx = mx, pmy = my;
Ivan Mahonin 261920
  mx = mouseX(), my = mouseY();
Ivan Mahonin 261920
Ivan Mahonin 261920
  if (mouseDown("left")) {
Ivan Mahonin 261920
    dx += (mx - pmx)/zm;
Ivan Mahonin 261920
    dy += (my - pmy)/zm;
Ivan Mahonin 261920
  } else
Ivan Mahonin 261920
  if (mouseDown("right")) {
Ivan Mahonin 261920
    zm *= pow(2.0, -(my - pmy)/500.0);
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  if (keyEventGetCount(KEYEVENT_KEY_DOWN))
Ivan Mahonin 261920
    curFade = 1;
Ivan Mahonin 261920
Ivan Mahonin 261920
  if (keyWentDown("up") && curRec > 0) {
Ivan Mahonin 261920
    if (keyDown("any ctrl")) {
Ivan Mahonin 261920
      Record r;
Ivan Mahonin 261920
      memcpy(&r, &records[curRec], sizeof(r));
Ivan Mahonin 261920
      memcpy(&records[curRec], &records[curRec-1], sizeof(r));
Ivan Mahonin 261920
      memcpy(&records[curRec-1], &r, sizeof(r));
Ivan Mahonin 261920
      updateLayout();
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
    --curRec;
Ivan Mahonin 261920
  } else
Ivan Mahonin 261920
  if (keyWentDown("down") && curRec < recCount-1) {
Ivan Mahonin 261920
    if (keyDown("any ctrl")) {
Ivan Mahonin 261920
      Record r;
Ivan Mahonin 261920
      memcpy(&r, &records[curRec], sizeof(r));
Ivan Mahonin 261920
      memcpy(&records[curRec], &records[curRec+1], sizeof(r));
Ivan Mahonin 261920
      memcpy(&records[curRec+1], &r, sizeof(r));
Ivan Mahonin 261920
      updateLayout();
Ivan Mahonin 261920
    }
Ivan Mahonin 261920
    ++curRec;
Ivan Mahonin 261920
  } else
Ivan Mahonin 261920
  if (keyWentDown("s")) {
Ivan Mahonin 261920
    save("data/output/history/ancient-dates.txt");
Ivan Mahonin 261920
  } else
Ivan Mahonin 261920
  if (keyWentDown("i")) {
Ivan Mahonin 261920
    curFade = 0;
Ivan Mahonin 261920
    saveImage("data/output/history/ancient-dates.png");
Ivan Mahonin 261920
  }
Ivan Mahonin 261920
Ivan Mahonin 261920
  saveState();
Ivan Mahonin 261920
  translate(w/2, h/2);
Ivan Mahonin 261920
  zoom(zm);
Ivan Mahonin 261920
  translate(dx, dy);
Ivan Mahonin 261920
Ivan Mahonin 261920
  drawRecords();
Ivan Mahonin 261920
  restoreState();
Ivan Mahonin 261920
Ivan Mahonin 261920
  curFade -= windowGetFrameTime()*2;
Ivan Mahonin 261920
  if (curFade < 0) curFade = 0;
Ivan Mahonin 261920
}
Ivan Mahonin 261920
Ivan Mahonin 261920
Ivan Mahonin 261920
int main() {
Ivan Mahonin 261920
  windowSetResizable(TRUE);
Ivan Mahonin 261920
  windowSetVariableFrameRate();
Ivan Mahonin 261920
  windowSetInit(&init);
Ivan Mahonin 261920
  windowSetDraw(&draw);
Ivan Mahonin 261920
  windowRun();
Ivan Mahonin 261920
  return 0;
Ivan Mahonin 261920
}
Ivan Mahonin 261920