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