Blame onefile/pixelfont.c

Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#include <stdio.h>
Ivan Mahonin 0ff1e5
#include <helianthus.h>
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define CW 4
Ivan Mahonin 0ff1e5
#define CH 5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define MAXW 1024
Ivan Mahonin 0ff1e5
#define MAXH 1024
Ivan Mahonin 0ff1e5
#define BORDER 1
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define ROWS   8
Ivan Mahonin 0ff1e5
#define COLS  12
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define WIDTH  (COLS*(CW + BORDER) + BORDER)
Ivan Mahonin 0ff1e5
#define HEIGHT (ROWS*(CH + BORDER) + BORDER)
Ivan Mahonin 0ff1e5
#define CS ((MAXW/WIDTH) < (MAXH/HEIGHT) ? (MAXW/WIDTH) : (MAXH/HEIGHT))
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define IW 512
Ivan Mahonin 0ff1e5
#define IH 512
Ivan Mahonin 0ff1e5
#define IB 16
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define BCOLOR COLOR_BLACK
Ivan Mahonin 0ff1e5
#define FCOLOR COLOR_WHITE
Ivan Mahonin 0ff1e5
#define SCOLOR COLOR_YELLOW
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define QUOTES2(x) #x
Ivan Mahonin 0ff1e5
#define QUOTES(x) QUOTES2(x)
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
#define PREFIX  "data/output/pixelfont" QUOTES(CW) QUOTES(CH)
Ivan Mahonin 0ff1e5
#define MAPFILE PREFIX ".map"
Ivan Mahonin 0ff1e5
#define IMGFILE PREFIX ".png"
Ivan Mahonin 0ff1e5
#define CFILE   PREFIX ".c"
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
int map[HEIGHT][WIDTH];
Ivan Mahonin 0ff1e5
unsigned int img[IH][IW];
Ivan Mahonin 0ff1e5
Animation imgAnim;
Ivan Mahonin 0ff1e5
int k = 1;
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
const char demoText[] =
Ivan Mahonin 0ff1e5
  "THE QUICK BROWN FOX JUMPS OVER A LAZY DOG.\n"
Ivan Mahonin 0ff1e5
  "the quick brown fox jumps over a lazy dog.\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "`~!@#$%^&*()-_+=\\|[]{};:'\",.<>/?\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "\"Free software\" means software that respects users' freedom and community.\n"
Ivan Mahonin 0ff1e5
  "Roughly, it means that the users have the freedom to run, copy, distribute,\n"
Ivan Mahonin 0ff1e5
  "study, change and improve the software. Thus, \"free software\" is a matter\n"
Ivan Mahonin 0ff1e5
  "of liberty, not price. To understand the concept, you should think of \"free\"\n"
Ivan Mahonin 0ff1e5
  "as in \"free speech\", not as in \"free beer\". We sometimes call it \"libre\n"
Ivan Mahonin 0ff1e5
  "software,\" borrowing the French or Spanish word for \"free\" as in freedom,\n"
Ivan Mahonin 0ff1e5
  "to show we do not mean the software is gratis.\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "12+(34-56)*67/890\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "2^3=8\n"
Ivan Mahonin 0ff1e5
  "3/100=3%\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "e-mail of Richard Stallman: rms@gnu.org\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "`reverse apostrophe`, ~tilda, array[12], {scope}\n"
Ivan Mahonin 0ff1e5
  "price is $100\n"
Ivan Mahonin 0ff1e5
  "\n"
Ivan Mahonin 0ff1e5
  "#include <stdio.h>\n"
Ivan Mahonin 0ff1e5
  "int x = IB, y = IB;\n"
Ivan Mahonin 0ff1e5
  "for(const char *c = demoText; *c; ++c) {\n"
Ivan Mahonin 0ff1e5
  "  if (*c == '\\n') { x = IB, y += CH+BORDER; continue; }\n"
Ivan Mahonin 0ff1e5
  "  if (*c >= 32 && *c < 128) {\n"
Ivan Mahonin 0ff1e5
  "    int mx = ((int)*c - 32)%COLS*(CW + BORDER) + BORDER;\n"
Ivan Mahonin 0ff1e5
  "    int my = ((int)*c - 32)/COLS*(CH + BORDER) + BORDER;\n"
Ivan Mahonin 0ff1e5
  "    for(int yy = 0; yy < CH; ++yy)\n"
Ivan Mahonin 0ff1e5
  "    for(int xx = 0; xx < CW; ++xx)\n"
Ivan Mahonin 0ff1e5
  "      if (map[my + yy][mx + xx])\n"
Ivan Mahonin 0ff1e5
  "        img[y + yy][x + xx] = FCOLOR;\n"
Ivan Mahonin 0ff1e5
  "  }\n"
Ivan Mahonin 0ff1e5
  "  x += CW+BORDER;\n"
Ivan Mahonin 0ff1e5
  "}\n";
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
void buildDemoImage() {
Ivan Mahonin 0ff1e5
  for(int y = 0; y < IH; ++y)
Ivan Mahonin 0ff1e5
  for(int x = 0; x < IW; ++x)
Ivan Mahonin 0ff1e5
    imageSetPixel(IW, IH, img, x, y, BCOLOR);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  int x = IB, y = IB;
Ivan Mahonin 0ff1e5
  for(const char *c = demoText; *c; ++c) {
Ivan Mahonin 0ff1e5
    if (*c == '\n') { x = IB, y += CH+BORDER; continue; }
Ivan Mahonin 0ff1e5
    if (*c >= 32 && *c < 128) {
Ivan Mahonin 0ff1e5
      int mx = ((int)*c - 32)%COLS*(CW + BORDER) + BORDER;
Ivan Mahonin 0ff1e5
      int my = ((int)*c - 32)/COLS*(CH + BORDER) + BORDER;
Ivan Mahonin 0ff1e5
      for(int yy = 0; yy < CH; ++yy)
Ivan Mahonin 0ff1e5
      for(int xx = 0; xx < CW; ++xx)
Ivan Mahonin 0ff1e5
        if (map[my + yy][mx + xx])
Ivan Mahonin 0ff1e5
          imageSetPixel(IW, IH, img, x + xx, y + yy, FCOLOR);
Ivan Mahonin 0ff1e5
    }
Ivan Mahonin 0ff1e5
    x += CW+BORDER;
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  if (imgAnim) animationDestroy(imgAnim);
Ivan Mahonin 0ff1e5
  imgAnim = createAnimationFromImageEx(IW, IH, img, FALSE, FALSE, FALSE, FALSE);
Ivan Mahonin 0ff1e5
}
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
void save() {
Ivan Mahonin 0ff1e5
  FILE *f = fopen(MAPFILE, "w");
Ivan Mahonin 0ff1e5
  if (!f)
Ivan Mahonin 0ff1e5
    { printf("cannot write to file: %s\n", MAPFILE); return; }
Ivan Mahonin 0ff1e5
  for(int y = 0; y < HEIGHT; ++y) {
Ivan Mahonin 0ff1e5
    for(int x = 0; x < WIDTH; ++x)
Ivan Mahonin 0ff1e5
      fputc(map[y][x] ? '#' : ' ', f);
Ivan Mahonin 0ff1e5
    fputc('\n', f);
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
  fclose(f);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  imageSave(IMGFILE, IW, IH, img);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  f = fopen(CFILE, "w");
Ivan Mahonin 0ff1e5
  if (!f)
Ivan Mahonin 0ff1e5
    { printf("cannot write to file: %s\n", CFILE); return; }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  int bits = CW*CH;
Ivan Mahonin 0ff1e5
  char format[] = " 0x%00llx,";
Ivan Mahonin 0ff1e5
  format[5] = '0' + (bits-1)/4 + 1;
Ivan Mahonin 0ff1e5
  unsigned long long bit = 1ull << (bits-1);
Ivan Mahonin 0ff1e5
  const char *itype = bits <=  8 ? "char"
Ivan Mahonin 0ff1e5
                    : bits <= 16 ? "short"
Ivan Mahonin 0ff1e5
                    : bits <= 32 ? "int"
Ivan Mahonin 0ff1e5
                    : "long long";
Ivan Mahonin 0ff1e5
Ivan Mahonin 3d3812
  fprintf(f, "unsigned %s font%dx%d_data[] = {\n", itype, CW, CH);
Ivan Mahonin 0ff1e5
  for(int r = 0; r < COLS; ++r) {
Ivan Mahonin 0ff1e5
    fprintf(f, " ");
Ivan Mahonin 0ff1e5
    for(int c = 0; c < ROWS; ++c) {
Ivan Mahonin 0ff1e5
      int i = r*ROWS + c;
Ivan Mahonin 0ff1e5
      int x = i%COLS*(CW+BORDER) + BORDER;
Ivan Mahonin 0ff1e5
      int y = i/COLS*(CH+BORDER) + BORDER;
Ivan Mahonin 0ff1e5
      unsigned long long d = 0;
Ivan Mahonin 0ff1e5
      for(int yy = 0; yy < CH; ++yy)
Ivan Mahonin 0ff1e5
      for(int xx = 0; xx < CW; ++xx)
Ivan Mahonin 0ff1e5
        d = (d >> 1) | (map[y + yy][x + xx] ? bit : 0);
Ivan Mahonin 0ff1e5
      fprintf(f, format, d);
Ivan Mahonin 0ff1e5
    }
Ivan Mahonin 0ff1e5
    fprintf(f, "\n");
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
  fprintf(f, "};\n");
Ivan Mahonin 0ff1e5
  fclose(f);
Ivan Mahonin 0ff1e5
}
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
void load() {
Ivan Mahonin 0ff1e5
  for(int y = 0; y < HEIGHT; ++y)
Ivan Mahonin 0ff1e5
  for(int x = 0; x < WIDTH; ++x)
Ivan Mahonin 0ff1e5
    map[y][x] = 0;
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  FILE *f = fopen(MAPFILE, "r");
Ivan Mahonin 0ff1e5
  if (!f)
Ivan Mahonin 0ff1e5
    { printf("cannot read from file: %s\n", MAPFILE); return; }
Ivan Mahonin 0ff1e5
  int x = 0, y = 0;
Ivan Mahonin 0ff1e5
  while(!feof(f)) {
Ivan Mahonin 0ff1e5
    int c = fgetc(f);
Ivan Mahonin 0ff1e5
    if (c == '\n') { x = 0; ++y; continue; }
Ivan Mahonin 0ff1e5
    if (c == '#' && x < WIDTH && y < HEIGHT)
Ivan Mahonin 0ff1e5
      map[y][x] = 1;
Ivan Mahonin 0ff1e5
    ++x;
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
}
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
void init() {
Ivan Mahonin 0ff1e5
  background(BCOLOR);
Ivan Mahonin 0ff1e5
  load();
Ivan Mahonin 0ff1e5
  buildDemoImage();
Ivan Mahonin 0ff1e5
}
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
void draw() {
Ivan Mahonin 0ff1e5
  saveState();
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  int imx = (int)(mouseX()/CS);
Ivan Mahonin 0ff1e5
  int imy = (int)(mouseY()/CS);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  double o = CS/2.0;
Ivan Mahonin 0ff1e5
  stroke(colorWithAlpha(FCOLOR, 0.25));
Ivan Mahonin 0ff1e5
  strokeWidth(1);
Ivan Mahonin 0ff1e5
  for(int r = 0; r <= ROWS; ++r)
Ivan Mahonin 0ff1e5
    line(o, o + r*(CH+BORDER)*CS, CS*WIDTH - o, o + r*(CH+BORDER)*CS);
Ivan Mahonin 0ff1e5
  for(int c = 0; c <= COLS; ++c)
Ivan Mahonin 0ff1e5
    line(o + c*(CW+BORDER)*CS, o, o + c*(CW+BORDER)*CS, CS*HEIGHT - o);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  noFill();
Ivan Mahonin 0ff1e5
  textAlign(HALIGN_CENTER, VALIGN_CENTER);
Ivan Mahonin 0ff1e5
  textSize(CH*CS*0.5);
Ivan Mahonin 0ff1e5
  for(int i = 0; i < 96; ++i) {
Ivan Mahonin 0ff1e5
    double x = ((i%COLS + 0.5)*(CW+BORDER) + BORDER)*CS;
Ivan Mahonin 0ff1e5
    double y = ((i/COLS + 0.5)*(CH+BORDER) + BORDER)*CS;
Ivan Mahonin 0ff1e5
    char t[2] = { i+32, 0 };
Ivan Mahonin 0ff1e5
    text(x, y, t);
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  fill(COLOR_WHITE);
Ivan Mahonin 0ff1e5
  rectTextured(imgAnim, WIDTH*CS + o, o, IW*k, IH*k);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  noStroke();
Ivan Mahonin 0ff1e5
  fill(FCOLOR);
Ivan Mahonin 0ff1e5
  for(int y = 0; y < HEIGHT; ++y)
Ivan Mahonin 0ff1e5
  for(int x = 0; x < WIDTH; ++x)
Ivan Mahonin 0ff1e5
    if (map[y][x]) rect(x*CS, y*CS, CS, CS);
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  if ( imx >= BORDER && imx < WIDTH
Ivan Mahonin 0ff1e5
    && imy >= BORDER && imy < HEIGHT
Ivan Mahonin 0ff1e5
    && (imx-BORDER)%(CW+BORDER) < CW
Ivan Mahonin 0ff1e5
    && (imy-BORDER)%(CH+BORDER) < CH )
Ivan Mahonin 0ff1e5
  {
Ivan Mahonin 0ff1e5
    fill(colorWithAlpha(SCOLOR, 0.25));
Ivan Mahonin 0ff1e5
    rect(imx*CS, imy*CS, CS, CS);
Ivan Mahonin 0ff1e5
    if (mouseDown("left"))  { map[imy][imx] = 1; buildDemoImage(); }
Ivan Mahonin 0ff1e5
    if (mouseDown("right")) { map[imy][imx] = 0; buildDemoImage(); }
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  if (keyWentDown("s")) {
Ivan Mahonin 0ff1e5
    printf("saving\n");
Ivan Mahonin 0ff1e5
    save();
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  if (keyWentDown("any +")) {
Ivan Mahonin 0ff1e5
    k = k == 1 ? 2 : 1;
Ivan Mahonin 0ff1e5
  }
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
  restoreState();
Ivan Mahonin 0ff1e5
}
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
Ivan Mahonin 0ff1e5
int main() {
Ivan Mahonin 0ff1e5
  windowSetResizable(TRUE);
Ivan Mahonin 0ff1e5
  windowSetVariableFrameRate();
Ivan Mahonin 0ff1e5
  windowSetInit(&init);
Ivan Mahonin 0ff1e5
  windowSetDraw(&draw);
Ivan Mahonin 0ff1e5
  windowRun();
Ivan Mahonin 0ff1e5
  return 0;
Ivan Mahonin 0ff1e5
}