|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
#include "menu.h"
|
|
Ivan Mahonin |
fdbd7d |
#include "icons.h"
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
61089c |
static int parseImgName(const char *imgname, int *rows, int *cols) {
|
|
Ivan Mahonin |
61089c |
if (rows) *rows = 0;
|
|
Ivan Mahonin |
61089c |
if (cols) *cols = 0;
|
|
Ivan Mahonin |
61089c |
char* p = strrchr(imgname, '.');
|
|
Ivan Mahonin |
61089c |
if (!p) return 0;
|
|
Ivan Mahonin |
61089c |
int r = 0, c = 0;
|
|
Ivan Mahonin |
61089c |
if ( 2 != sscanf(p, ".pz%dx%d", &c, &r)
|
|
Ivan Mahonin |
61089c |
|| r > 100 || c > 100 || r*c > 200
|
|
Ivan Mahonin |
61089c |
|| r < 1 || c < 1 || r*c < 2 ) return 0;
|
|
Ivan Mahonin |
61089c |
if (rows) *rows = r;
|
|
Ivan Mahonin |
61089c |
if (cols) *cols = c;
|
|
Ivan Mahonin |
61089c |
return 1;
|
|
Ivan Mahonin |
61089c |
}
|
|
Ivan Mahonin |
61089c |
|
|
Ivan Mahonin |
61089c |
|
|
Ivan Mahonin |
fdbd7d |
static Animation loadThumb(const char *imgname, Framebuffer fb, int w, int h) {
|
|
Ivan Mahonin |
fdbd7d |
char *imgpath = findImage(imgname);
|
|
Ivan Mahonin |
fdbd7d |
if (!imgpath)
|
|
Ivan Mahonin |
fdbd7d |
{ ERR("loadThumb: image not found: %s", imgname); return NULL; }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (w < 1) w = 1;
|
|
Ivan Mahonin |
fdbd7d |
if (h < 1) h = 1;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
char *tpath = strprintf("%s/%s", thumbsPath(), filename(imgpath));
|
|
Ivan Mahonin |
fdbd7d |
if (fileExists(tpath) && filetime(imgpath) < filetime(tpath)) {
|
|
Ivan Mahonin |
fdbd7d |
Animation thumb = createAnimationEx(tpath, TRUE, FALSE, FALSE);
|
|
Ivan Mahonin |
fdbd7d |
if (abs(animationGetOrigWidth(thumb) - w) <= 2 || abs(animationGetOrigHeight(thumb) - h) <= 2) {
|
|
Ivan Mahonin |
fdbd7d |
free(tpath);
|
|
Ivan Mahonin |
fdbd7d |
free(imgpath);
|
|
Ivan Mahonin |
fdbd7d |
return thumb;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
animationDestroy(thumb);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
INF("loadThumb: create thumbnail: %s -> %s", imgpath, tpath);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Animation full = createAnimationEx(imgpath, TRUE, FALSE, FALSE);
|
|
Ivan Mahonin |
fdbd7d |
int fw = animationGetOrigWidth(full);
|
|
Ivan Mahonin |
fdbd7d |
int fh = animationGetOrigHeight(full);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int tw = w, th = h;
|
|
Ivan Mahonin |
fdbd7d |
if (fw*(double)h > fh*(double)w) th = (int)round(w/(double)fw*fh);
|
|
Ivan Mahonin |
fdbd7d |
else tw = (int)round(h/(double)fh*fw);
|
|
Ivan Mahonin |
fdbd7d |
if (tw < 1) tw = 1; else if (tw > w) tw = w;
|
|
Ivan Mahonin |
fdbd7d |
if (th < 1) th = 1; else if (th > h) th = h;
|
|
Ivan Mahonin |
f8c4ae |
DBG("[%dx%d] -> [%dx%d]", fw, fh, tw, th);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
resetState();
|
|
Ivan Mahonin |
fdbd7d |
target(fb);
|
|
Ivan Mahonin |
fdbd7d |
background(COLOR_TRANSPARENT);
|
|
Ivan Mahonin |
fdbd7d |
clear();
|
|
Ivan Mahonin |
fdbd7d |
noStroke();
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(full, 0, 0, tw, th);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int iw, ih;
|
|
Ivan Mahonin |
fdbd7d |
unsigned char *pixels;
|
|
Ivan Mahonin |
fdbd7d |
Animation thumb = NULL;
|
|
Ivan Mahonin |
fdbd7d |
if (imageFromViewport(&iw, &ih, &pixels)) {
|
|
Ivan Mahonin |
fdbd7d |
if (ih > th) ih = th;
|
|
Ivan Mahonin |
fdbd7d |
if (iw > tw) {
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 1; i < ih; ++i) memmove(pixels + i*tw*4, pixels + i*iw*4, tw*4);
|
|
Ivan Mahonin |
fdbd7d |
iw = tw;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
if (iw != tw || ih != th) {
|
|
Ivan Mahonin |
fdbd7d |
WRN("loadThumb: thumbnail was truncated: %s, [%dx%d] -> [%dx%d]", imgpath, tw, th, iw, ih);
|
|
Ivan Mahonin |
fdbd7d |
} else
|
|
Ivan Mahonin |
fdbd7d |
if (!imageSave(tpath, iw, ih, pixels)) {
|
|
Ivan Mahonin |
fdbd7d |
WRN("loadThumb: cannot save thumbnail to: %s", tpath);
|
|
Ivan Mahonin |
f8c4ae |
thumb = createAnimationFromImageEx(iw, ih, pixels, FALSE, FALSE, TRUE, TRUE);
|
|
Ivan Mahonin |
f8c4ae |
} else {
|
|
Ivan Mahonin |
f8c4ae |
thumb = createAnimationEx(tpath, TRUE, FALSE, FALSE);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
free(pixels);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
WRN("loadThumb: cannot capture vieport: %s", imgpath);
|
|
Ivan Mahonin |
fdbd7d |
unsigned char px[4*4*4] = {};
|
|
Ivan Mahonin |
fdbd7d |
thumb = createAnimationFromImageEx(4, 4, px, FALSE, FALSE, TRUE, TRUE);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
free(tpath);
|
|
Ivan Mahonin |
fdbd7d |
free(imgpath);
|
|
Ivan Mahonin |
fdbd7d |
return thumb;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int menuItemInit(MenuItem *mi, const char *path, const char *imgname, Vec p0, Vec p1, Framebuffer fb, int w, int h) {
|
|
Ivan Mahonin |
fdbd7d |
memset(mi, 0, sizeof(*mi));
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
DBG("%s, %s", path ? path : "null", imgname ? imgname : "null");
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Vec d = vsub(p1, p0);
|
|
Ivan Mahonin |
fdbd7d |
if (!(fabs(d.x) > PRECISION) || !(fabs(d.y) > PRECISION)) return 0;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (path) {
|
|
Ivan Mahonin |
fdbd7d |
GameInfo *gi = loadGameInfo(path);
|
|
Ivan Mahonin |
fdbd7d |
if (!gi) return 0;
|
|
Ivan Mahonin |
fdbd7d |
mi->image = loadThumb(gi->imgname, fb, w, h);
|
|
Ivan Mahonin |
fdbd7d |
if (!mi->image) { free(gi); return 0; }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int cnt = gi->rows*gi->cols;
|
|
Ivan Mahonin |
fdbd7d |
mi->path = strprintf("%s", path);
|
|
Ivan Mahonin |
fdbd7d |
mi->imgname = strprintf("%s", gi->imgname);
|
|
Ivan Mahonin |
fdbd7d |
mi->percent = (cnt - gi->groups)/(cnt - 1.0);
|
|
Ivan Mahonin |
fdbd7d |
mi->t = filetime(path);
|
|
Ivan Mahonin |
fdbd7d |
free(gi);
|
|
Ivan Mahonin |
fdbd7d |
} else
|
|
Ivan Mahonin |
fdbd7d |
if (imgname) {
|
|
Ivan Mahonin |
fdbd7d |
mi->image = loadThumb(imgname, fb, w, h);
|
|
Ivan Mahonin |
fdbd7d |
if (!mi->image) return 0;
|
|
Ivan Mahonin |
fdbd7d |
mi->imgname = strprintf("%s", imgname);
|
|
Ivan Mahonin |
61089c |
parseImgName(mi->imgname, &mi->rows, &mi->cols);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
return 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Vec is = { animationGetOrigWidth(mi->image), animationGetOrigHeight(mi->image) };
|
|
Ivan Mahonin |
fdbd7d |
if (is.x < 1) is.x = 1;
|
|
Ivan Mahonin |
fdbd7d |
if (is.y < 1) is.y = 1;
|
|
Ivan Mahonin |
fdbd7d |
Vec k = vabs(vdivv(is, d));
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (k.x > k.y) {
|
|
Ivan Mahonin |
fdbd7d |
double l = (1 - k.y/k.x)/2;
|
|
Ivan Mahonin |
fdbd7d |
mi->p0 = vec(p0.x, lintr(p0.y, p1.y, l));
|
|
Ivan Mahonin |
fdbd7d |
mi->p1 = vec(p1.x, lintr(p0.y, p1.y, 1-l));
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
double l = (1 - k.x/k.y)/2;
|
|
Ivan Mahonin |
fdbd7d |
mi->p0 = vec(lintr(p0.x, p1.x, l), p0.y);
|
|
Ivan Mahonin |
fdbd7d |
mi->p1 = vec(lintr(p0.x, p1.x, 1-l), p1.y);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
return 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuItemFree(MenuItem *mi) {
|
|
Ivan Mahonin |
fdbd7d |
free(mi->path);
|
|
Ivan Mahonin |
fdbd7d |
free(mi->imgname);
|
|
Ivan Mahonin |
fdbd7d |
if (mi->image) animationDestroy(mi->image);
|
|
Ivan Mahonin |
fdbd7d |
memset(mi, 0, sizeof(*mi));
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
static void splitRect(Vec p0, Vec p1, double percent, Vec *v0, int *v0c, Vec *v1, int *v1c) {
|
|
Ivan Mahonin |
fdbd7d |
Vec s = vabs(vsub(p1, p0));
|
|
Ivan Mahonin |
fdbd7d |
if (s.x < s.y) {
|
|
Ivan Mahonin |
fdbd7d |
splitRect(vtranspose(p0), vtranspose(p1), percent, v0, v0c, v1, v1c);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < *v0c; ++i) v0[i] = vtranspose(v0[i]);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < *v1c; ++i) v1[i] = vtranspose(v1[i]);
|
|
Ivan Mahonin |
fdbd7d |
return;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
if (percent > 0.5) {
|
|
Ivan Mahonin |
fdbd7d |
splitRect(p1, p0, 1 - percent - PRECISION, v1, v1c, v0, v0c);
|
|
Ivan Mahonin |
fdbd7d |
return;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (!(percent > PRECISION) || !(s.x > PRECISION) || !(s.y > PRECISION))
|
|
Ivan Mahonin |
fdbd7d |
{ v0[0] = p0; v0[1] = vec(p1.x, p0.y); v0[2] = p1; v0[3] = vec(p0.x, p1.y); *v0c = 4; *v1c = 0; return; }
|
|
Ivan Mahonin |
fdbd7d |
if (!(percent < 1-PRECISION))
|
|
Ivan Mahonin |
fdbd7d |
{ v1[0] = p1; v1[1] = vec(p0.x, p1.y); v1[2] = p0; v1[3] = vec(p1.x, p0.y); *v0c = 0; *v1c = 4; return; }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
*v0c = *v1c = 0;
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = p0;
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = p1;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
double af = s.x*s.y;
|
|
Ivan Mahonin |
fdbd7d |
double ap = af*percent;
|
|
Ivan Mahonin |
fdbd7d |
double ac = s.y*s.y/2;
|
|
Ivan Mahonin |
fdbd7d |
if (ap < ac) {
|
|
Ivan Mahonin |
fdbd7d |
double ky = sqrt(ap/ac);
|
|
Ivan Mahonin |
fdbd7d |
Vec a = { lintr(p0.x, p1.x, ky*s.y/s.x), p0.y };
|
|
Ivan Mahonin |
fdbd7d |
Vec b = { p0.x, lintr(p0.y, p1.y, ky) };
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = a;
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = b;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = vec(p0.x, p1.y);
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = b;
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = a;
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = vec(p1.x, p0.y);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
double kx = (ap-ac)/(af-2*ac)*(s.x-s.y)/s.x;
|
|
Ivan Mahonin |
fdbd7d |
Vec b = { lintr(p0.x, p1.x, kx), p1.y };
|
|
Ivan Mahonin |
fdbd7d |
Vec a = { b.x + p1.y - p0.y, p0.y };
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = a;
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = b;
|
|
Ivan Mahonin |
fdbd7d |
v0[(*v0c)++] = vec(p0.x, p1.y);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = b;
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = a;
|
|
Ivan Mahonin |
fdbd7d |
v1[(*v1c)++] = vec(p1.x, p0.y);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuItemDraw(MenuItem *mi) {
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
Vec d = vsub(mi->p1, mi->p0);
|
|
Ivan Mahonin |
fdbd7d |
if (mi->path) {
|
|
Ivan Mahonin |
fdbd7d |
noStroke();
|
|
Ivan Mahonin |
fdbd7d |
Vec v[2][5] = {};
|
|
Ivan Mahonin |
fdbd7d |
int vc[2] = {};
|
|
Ivan Mahonin |
fdbd7d |
splitRect(mi->p0, mi->p1, mi->percent, v[0], &vc[0], v[1], &vc[1]);
|
|
Ivan Mahonin |
fdbd7d |
noStroke();
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < 2; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
fill(colorByRGBA(1, 1, 1, (2-i)*0.5));
|
|
Ivan Mahonin |
fdbd7d |
fillTexture(mi->image, mi->p0.x, mi->p0.y, d.x, d.y, FALSE);
|
|
Ivan Mahonin |
fdbd7d |
moveTo(v[i][0].x, v[i][0].y);
|
|
Ivan Mahonin |
fdbd7d |
for(int j = 1; j < vc[i]; ++j) lineTo(v[i][j].x, v[i][j].y);
|
|
Ivan Mahonin |
fdbd7d |
closePath();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
noFill();
|
|
Ivan Mahonin |
fdbd7d |
stroke(COLOR_BLUE);
|
|
Ivan Mahonin |
fdbd7d |
rect(mi->p0.x, mi->p0.y, d.x, d.y);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
stroke(COLOR_BLACK);
|
|
Ivan Mahonin |
fdbd7d |
fill(COLOR_WHITE);
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(mi->image, mi->p0.x, mi->p0.y, d.x, d.y);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
static Animation loadIcon(const void *data, size_t size) {
|
|
Ivan Mahonin |
fdbd7d |
unsigned char *p = NULL; int w = 0, h = 0;
|
|
Ivan Mahonin |
fdbd7d |
if (!imageLoadFromMemory(data, size, &w, &h, &p))
|
|
Ivan Mahonin |
fdbd7d |
return createAnimationEmpty();
|
|
Ivan Mahonin |
fdbd7d |
Animation a = createAnimationFromImageEx(w, h, p, FALSE, FALSE, TRUE, TRUE);
|
|
Ivan Mahonin |
fdbd7d |
free(p);
|
|
Ivan Mahonin |
fdbd7d |
return a;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuInit(Menu *m) {
|
|
Ivan Mahonin |
fdbd7d |
memset(m, 0, sizeof(*m));
|
|
Ivan Mahonin |
fdbd7d |
m->contentSize = vone();
|
|
Ivan Mahonin |
fdbd7d |
#define LOADICON(x) loadIcon(dataIcon ## x, dataIcon ## x ## Size)
|
|
Ivan Mahonin |
fdbd7d |
m->iconBack = LOADICON(Back);
|
|
Ivan Mahonin |
fdbd7d |
m->iconCount[0] = LOADICON(Count1);
|
|
Ivan Mahonin |
fdbd7d |
m->iconCount[1] = LOADICON(Count2);
|
|
Ivan Mahonin |
fdbd7d |
m->iconCount[2] = LOADICON(Count3);
|
|
Ivan Mahonin |
fdbd7d |
m->iconCount[3] = LOADICON(Count4);
|
|
Ivan Mahonin |
fdbd7d |
m->iconTurn[0] = LOADICON(Noturn);
|
|
Ivan Mahonin |
fdbd7d |
m->iconTurn[1] = LOADICON(Turn);
|
|
Ivan Mahonin |
fdbd7d |
#undef LOADICON
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuFree(Menu *m) {
|
|
Ivan Mahonin |
fdbd7d |
if (gameStarted(&m->gm)) gameFree(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < m->itemsCnt; ++i) menuItemFree(&m->items[i]);
|
|
Ivan Mahonin |
fdbd7d |
free(m->items);
|
|
Ivan Mahonin |
fdbd7d |
if (m->iconBack) animationDestroy(m->iconBack);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < COUNTOF(m->iconCount); ++i)
|
|
Ivan Mahonin |
fdbd7d |
if (m->iconCount[i]) animationDestroy(m->iconCount[i]);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < COUNTOF(m->iconTurn); ++i)
|
|
Ivan Mahonin |
fdbd7d |
if (m->iconTurn[i]) animationDestroy(m->iconTurn[i]);
|
|
Ivan Mahonin |
fdbd7d |
memset(m, 0, sizeof(*m));
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuUpdateItems(Menu* m) {
|
|
Ivan Mahonin |
fdbd7d |
// remove old items, but copy images to keep them in memory
|
|
Ivan Mahonin |
fdbd7d |
Animation animCopy = createAnimationEmpty();
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < m->itemsCnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
animationInsert(animCopy, -1, m->items[i].image);
|
|
Ivan Mahonin |
fdbd7d |
menuItemFree(&m->items[i]);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
free(m->items);
|
|
Ivan Mahonin |
fdbd7d |
m->itemsCnt = 0;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Vec border = {1, 1};
|
|
Ivan Mahonin |
fdbd7d |
Vec spacing = {1, 1};
|
|
Ivan Mahonin |
fdbd7d |
Vec thumb = {16, 12};
|
|
Ivan Mahonin |
fdbd7d |
int cols = 4;
|
|
Ivan Mahonin |
fdbd7d |
int tw = 256;
|
|
Ivan Mahonin |
fdbd7d |
int th = tw/4*3;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Framebuffer fb = createFramebuffer(tw, tw);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
PathList *pls = saveFiles();
|
|
Ivan Mahonin |
fdbd7d |
PathList *pli = imageFiles();
|
|
Ivan Mahonin |
fdbd7d |
m->items = alloc((pls->cnt + pli->cnt)*ASIZEOF(*m->items));
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int c = 0;
|
|
Ivan Mahonin |
fdbd7d |
double y = border.y, ly = y;
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < pls->cnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
Vec p0 = { border.x + (thumb.x + spacing.x)*c, y };
|
|
Ivan Mahonin |
fdbd7d |
Vec p1 = vadd(p0, thumb);
|
|
Ivan Mahonin |
fdbd7d |
if (menuItemInit(&m->items[m->itemsCnt], pls->l[i], NULL, p0, p1, fb, tw, th)) {
|
|
Ivan Mahonin |
fdbd7d |
if (++c >= cols) { c = 0; y += thumb.y + spacing.y; }
|
|
Ivan Mahonin |
fdbd7d |
++m->itemsCnt; ly = p1.y;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (c) { c = 0; y += thumb.y + spacing.y; }
|
|
Ivan Mahonin |
fdbd7d |
if (m->itemsCnt) y += spacing.y;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < pli->cnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
Vec p0 = { border.x + (thumb.x + spacing.x)*c, y };
|
|
Ivan Mahonin |
fdbd7d |
Vec p1 = vadd(p0, thumb);
|
|
Ivan Mahonin |
fdbd7d |
char *imgname = filebase(pli->l[i]);
|
|
Ivan Mahonin |
fdbd7d |
if (menuItemInit(&m->items[m->itemsCnt], NULL, imgname, p0, p1, fb, tw, th)) {
|
|
Ivan Mahonin |
fdbd7d |
if (++c >= cols) { c = 0; y += thumb.y + spacing.y; }
|
|
Ivan Mahonin |
fdbd7d |
++m->itemsCnt; ly = p1.y;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
free(imgname);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
animationDestroy(animCopy);
|
|
Ivan Mahonin |
fdbd7d |
free(pls);
|
|
Ivan Mahonin |
fdbd7d |
free(pli);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
framebufferDestroy(fb);
|
|
Ivan Mahonin |
fdbd7d |
m->contentSize = vec( 2*border.x + thumb.x*cols + spacing.x*(cols-1), ly + border.y );
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int menuSave(Menu *m) {
|
|
Ivan Mahonin |
fdbd7d |
makeDirectoryRecursive(savesPath());
|
|
Ivan Mahonin |
fdbd7d |
const char *fn = settingsFile();
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = fopen(fn, "w");
|
|
Ivan Mahonin |
fdbd7d |
if (!f) return ERR("menuSave: cannnot open file for write: %s", fn);
|
|
Ivan Mahonin |
fdbd7d |
fprintf(f, "puzzle1\n[%s]\n%d %d\n", m->gm.path ? m->gm.path : "", m->countMode, m->turnMode);
|
|
Ivan Mahonin |
fdbd7d |
fflush(f);
|
|
Ivan Mahonin |
fdbd7d |
if (ferror(f)) ERR("menuSave: cannnot write to file: %s", fn);
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
fdbd7d |
return 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int menuLoad(Menu *m) {
|
|
Ivan Mahonin |
fdbd7d |
const char *fn = settingsFile();
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = fopen(fn, "r");
|
|
Ivan Mahonin |
fdbd7d |
if (!f) return 0;
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
char *l = trim(readline(f));
|
|
Ivan Mahonin |
fdbd7d |
if (strcmp(l, "puzzle1")) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("menuLoad: wrong file version (expected: puzzle1): %s", l);
|
|
Ivan Mahonin |
fdbd7d |
free(l); fclose(f); return 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
dcf1b6 |
l = unquote(readline(f), '[', ']');
|
|
Ivan Mahonin |
fdbd7d |
int cm = -1, tm = -1;
|
|
Ivan Mahonin |
fdbd7d |
fscanf(f, "%d %d", &cm, &tm);
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
if ( cm < 0 || cm > COUNTOF(m->iconCount) || tm < 0 || tm > COUNTOF(m->iconTurn))
|
|
Ivan Mahonin |
fdbd7d |
{ ERR("menuLoad: cannot parse file: %s", fn); free(l); return 0; }
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
m->countMode = cm;
|
|
Ivan Mahonin |
fdbd7d |
m->turnMode = tm;
|
|
Ivan Mahonin |
fdbd7d |
if (*l) gameLoad(&m->gm, l);
|
|
Ivan Mahonin |
fdbd7d |
free(l);
|
|
Ivan Mahonin |
fdbd7d |
return 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
dcf1b6 |
void menuChooseItem(Menu *m, MenuItem *mi) {
|
|
Ivan Mahonin |
dcf1b6 |
if (mi->path) {
|
|
Ivan Mahonin |
dcf1b6 |
gameLoad(&m->gm, mi->path);
|
|
Ivan Mahonin |
dcf1b6 |
return;
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
61089c |
|
|
Ivan Mahonin |
dcf1b6 |
int cnt = m->countMode == 0 ? 12
|
|
Ivan Mahonin |
dcf1b6 |
: m->countMode == 1 ? 24
|
|
Ivan Mahonin |
dcf1b6 |
: m->countMode == 2 ? 48 : 96;
|
|
Ivan Mahonin |
61089c |
int rows = mi->rows;
|
|
Ivan Mahonin |
61089c |
int cols = mi->cols;
|
|
Ivan Mahonin |
ab2a4e |
if (!mi->rows || !mi->cols) { rows = cnt; cols = 0; }
|
|
Ivan Mahonin |
61089c |
|
|
Ivan Mahonin |
dcf1b6 |
char *path = NULL;
|
|
Ivan Mahonin |
dcf1b6 |
for(int j = 0; j < 10000; ++j) {
|
|
Ivan Mahonin |
dcf1b6 |
path = strprintf("%s/%s_%04d.puzzle", savesPath(), mi->imgname, j);
|
|
Ivan Mahonin |
dcf1b6 |
if (fileExists(path)) { free(path); continue; }
|
|
Ivan Mahonin |
61089c |
gameCreate(&m->gm, path, mi->imgname, rows, cols, m->turnMode, 0);
|
|
Ivan Mahonin |
dcf1b6 |
free(path);
|
|
Ivan Mahonin |
dcf1b6 |
break;
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
void menuClick(Menu *m, Vec screenSize, double cornerSize) {
|
|
Ivan Mahonin |
fdbd7d |
double cs2 = cornerSize*cornerSize;
|
|
Ivan Mahonin |
fdbd7d |
if (vlen2(vsub(vec(screenSize.x, 0), m->mouseDownPos)) <= cs2)
|
|
Ivan Mahonin |
fdbd7d |
{ m->countMode = (m->countMode+1) % COUNTOF(m->iconCount); return; }
|
|
Ivan Mahonin |
fdbd7d |
if (vlen2(vsub(screenSize, m->mouseDownPos)) <= cs2)
|
|
Ivan Mahonin |
fdbd7d |
{ m->turnMode = (m->turnMode+1) % COUNTOF(m->iconTurn); return; }
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
Vec p = m->mouseDownPos;
|
|
Ivan Mahonin |
fdbd7d |
p.y += m->scrollPos;
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < m->itemsCnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
MenuItem *mi = &m->items[i];
|
|
Ivan Mahonin |
fdbd7d |
if ( !(p.x >= mi->p0.x) || !(p.x <= mi->p1.x)
|
|
Ivan Mahonin |
fdbd7d |
|| !(p.y >= mi->p0.y) || !(p.y <= mi->p1.y) ) continue;
|
|
Ivan Mahonin |
dcf1b6 |
m->choosingItem = mi;
|
|
Ivan Mahonin |
dcf1b6 |
m->choosingItemFrames = 4;
|
|
Ivan Mahonin |
dcf1b6 |
return;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void menuDraw(Menu *m) {
|
|
Ivan Mahonin |
dcf1b6 |
if (m->choosingItem) {
|
|
Ivan Mahonin |
dcf1b6 |
if (--m->choosingItemFrames > 0) return;
|
|
Ivan Mahonin |
dcf1b6 |
MenuItem *mi = m->choosingItem;
|
|
Ivan Mahonin |
dcf1b6 |
m->choosingItem = NULL;
|
|
Ivan Mahonin |
dcf1b6 |
m->choosingItemFrames = 0;
|
|
Ivan Mahonin |
dcf1b6 |
menuChooseItem(m, mi);
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
int w = windowGetWidth();
|
|
Ivan Mahonin |
fdbd7d |
int h = windowGetHeight();
|
|
Ivan Mahonin |
fdbd7d |
double dt = windowGetFrameTime();
|
|
Ivan Mahonin |
fdbd7d |
double k = w/m->contentSize.x;
|
|
Ivan Mahonin |
fdbd7d |
Vec screenSize = { w/k, h/k };
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
a649ba |
double maxPath = m->contentSize.x*0.1;
|
|
Ivan Mahonin |
fdbd7d |
double scrollMax = m->contentSize.y - screenSize.y;
|
|
Ivan Mahonin |
fdbd7d |
double scrollBase = m->contentSize.x*dt*2;
|
|
Ivan Mahonin |
fdbd7d |
double scrollDecc = m->contentSize.x*dt*2;
|
|
Ivan Mahonin |
fdbd7d |
double scrollOver = m->contentSize.x*0.2;
|
|
Ivan Mahonin |
fdbd7d |
if (!(scrollMax > 0)) scrollMax = 0;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
zoom(k);
|
|
Ivan Mahonin |
fdbd7d |
strokeWidth(1/k);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
double cornerSizeX = screenSize.x/8;
|
|
Ivan Mahonin |
fdbd7d |
double cornerSizeY = screenSize.y/4;
|
|
Ivan Mahonin |
fdbd7d |
double cornerSize = cornerSizeX < cornerSizeY ? cornerSizeX : cornerSizeY;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Vec mouse = { mouseTransformedX(), mouseTransformedY() };
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentDown("left")) {
|
|
Ivan Mahonin |
fdbd7d |
m->mouseDownPos = mouse;
|
|
Ivan Mahonin |
fdbd7d |
m->mouseDownTime = 0;
|
|
Ivan Mahonin |
fdbd7d |
m->mousePath = 0;
|
|
Ivan Mahonin |
fdbd7d |
m->mouseScroll = m->scrollPos;
|
|
Ivan Mahonin |
fdbd7d |
if (vlen2(mouse) <= cornerSize*cornerSize || gameWon(&m->gm))
|
|
Ivan Mahonin |
fdbd7d |
{
|
|
Ivan Mahonin |
fdbd7d |
if (gameStarted(&m->gm) && !gameWon(&m->gm)) gameSave(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
m->closing = 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentUp("left")) m->closing = 0;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (mouseDown("left")) {
|
|
Ivan Mahonin |
fdbd7d |
m->mousePath += vlen(vsub(mouse, m->mouse));
|
|
Ivan Mahonin |
fdbd7d |
m->mouseDownTime += dt;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->mousePath < maxPath)) m->closing = 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (!gameStarted(&m->gm)) {
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentDown("left"))
|
|
Ivan Mahonin |
fdbd7d |
memset(m->scrollHist, 0, sizeof(m->scrollHist));
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentUp("left")) {
|
|
Ivan Mahonin |
fdbd7d |
if ( m->mousePath < maxPath
|
|
Ivan Mahonin |
a649ba |
&& m->mouseDownTime < 1
|
|
Ivan Mahonin |
fdbd7d |
&& vlen(vsub(mouse, m->mouseDownPos)) < maxPath )
|
|
Ivan Mahonin |
fdbd7d |
{
|
|
Ivan Mahonin |
fdbd7d |
m->scrollVel = 0;
|
|
Ivan Mahonin |
fdbd7d |
menuClick(m, screenSize, cornerSize);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
double p1 = m->scrollPos, p0 = p1, t = 0;
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < MS_CNT; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollHist[i][1] > PRECISION) {
|
|
Ivan Mahonin |
fdbd7d |
p0 = m->scrollHist[i][0];
|
|
Ivan Mahonin |
fdbd7d |
t += m->scrollHist[i][1];
|
|
Ivan Mahonin |
fdbd7d |
if (i >= 3 && t > 0.2) break;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
m->scrollVel = t > PRECISION ? (p1 - p0)/t : 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (mouseDown("left")) {
|
|
Ivan Mahonin |
fdbd7d |
m->scrollPos = m->mouseScroll + m->mouseDownPos.y - mouse.y;
|
|
Ivan Mahonin |
fdbd7d |
memmove(m->scrollHist + 1, m->scrollHist, (MS_CNT-1)*sizeof(*m->scrollHist));
|
|
Ivan Mahonin |
fdbd7d |
m->scrollHist[0][0] = m->scrollPos;
|
|
Ivan Mahonin |
fdbd7d |
m->scrollHist[0][1] = dt;
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollPos < -scrollOver && m->scrollVel < 0) m->scrollVel = 0;
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollPos > scrollMax+scrollOver && m->scrollVel > 0) m->scrollVel = 0;
|
|
Ivan Mahonin |
fdbd7d |
m->scrollPos += m->scrollVel*dt;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollVel < 0) {
|
|
Ivan Mahonin |
fdbd7d |
m->scrollVel += scrollDecc;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->scrollVel < 0)) m->scrollVel = 0;
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
m->scrollVel -= scrollDecc;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->scrollVel > 0)) m->scrollVel = 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollPos < 0) {
|
|
Ivan Mahonin |
fdbd7d |
m->scrollPos += scrollBase;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->scrollPos < 0)) m->scrollPos = 0;
|
|
Ivan Mahonin |
fdbd7d |
} else
|
|
Ivan Mahonin |
fdbd7d |
if (m->scrollPos > scrollMax) {
|
|
Ivan Mahonin |
fdbd7d |
m->scrollPos -= scrollBase;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->scrollPos > scrollMax)) m->scrollPos = scrollMax;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
translate(0, -m->scrollPos);
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < m->itemsCnt; ++i)
|
|
Ivan Mahonin |
fdbd7d |
menuItemDraw(&m->items[i]);
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
m->mouse = mouse;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (gameStarted(&m->gm)) {
|
|
Ivan Mahonin |
fdbd7d |
int wasGroups = m->gm.pz.groups;
|
|
Ivan Mahonin |
fdbd7d |
int wasWon = gameWon(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
zoom(1/k);
|
|
Ivan Mahonin |
fdbd7d |
gameDraw(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (wasGroups != m->gm.pz.groups && !gameWon(&m->gm))
|
|
Ivan Mahonin |
fdbd7d |
gameSave(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
if (wasWon && gameWon(&m->gm) && fileExists(m->gm.path) && remove(m->gm.path))
|
|
Ivan Mahonin |
fdbd7d |
ERR("cannot remove save-file for the won game: %s", m->gm.path);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
noStroke();
|
|
Ivan Mahonin |
fdbd7d |
fill(colorByRGBA(1, 1, 1, 0.25));
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(m->iconBack, 0, 0, cornerSize, cornerSize);
|
|
Ivan Mahonin |
fdbd7d |
if (!gameStarted(&m->gm)) {
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(m->iconCount[m->countMode], screenSize.x-cornerSize, 0, cornerSize, cornerSize);
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(m->iconTurn[m->turnMode], screenSize.x-cornerSize, screenSize.y-cornerSize, cornerSize, cornerSize);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (m->closing) {
|
|
Ivan Mahonin |
fdbd7d |
m->closingTransition += dt;
|
|
Ivan Mahonin |
fdbd7d |
if (m->closingTransition > 1) {
|
|
Ivan Mahonin |
fdbd7d |
if (gameStarted(&m->gm)) {
|
|
Ivan Mahonin |
fdbd7d |
gameFree(&m->gm);
|
|
Ivan Mahonin |
fdbd7d |
m->closing = 0;
|
|
Ivan Mahonin |
fdbd7d |
m->closingTransition = 0;
|
|
Ivan Mahonin |
fdbd7d |
menuUpdateItems(m);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
m->closingTransition = 1;
|
|
Ivan Mahonin |
fdbd7d |
windowStop();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
m->closingTransition -= dt;
|
|
Ivan Mahonin |
fdbd7d |
if (!(m->closingTransition > 0)) m->closingTransition = 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (m->closingTransition > 0) {
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
noStroke();
|
|
Ivan Mahonin |
fdbd7d |
fill(gameStarted(&m->gm) ? colorByRGBA(0.05, 0.05, 0.05, 1) : COLOR_BLACK);
|
|
Ivan Mahonin |
fdbd7d |
Vec c = m->mouseDownPos;
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
Vec d = vsub(screenSize, c);
|
|
Ivan Mahonin |
dcf1b6 |
double rmax2 = maxd( maxd(vlen2(vec(c.x, d.y)), vlen2(c)),
|
|
Ivan Mahonin |
dcf1b6 |
maxd(vlen2(vec(d.x, c.y)), vlen2(d)) );
|
|
Ivan Mahonin |
dcf1b6 |
double r0 = sqrt(rmax2) * (1 - m->closingTransition);
|
|
Ivan Mahonin |
fdbd7d |
double r1 = r0 + vlen(screenSize);
|
|
Ivan Mahonin |
fdbd7d |
arcPath(c.x-r0, c.y-r0, 2*r0, 2*r0, 180, -180);
|
|
Ivan Mahonin |
fdbd7d |
arcPath(c.x-r1, c.y-r1, 2*r1, 2*r1, -180, 180);
|
|
Ivan Mahonin |
fdbd7d |
closePath();
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|