|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
#include "game.h"
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void gameFree(Game *gm) {
|
|
Ivan Mahonin |
fdbd7d |
puzzleFree(&gm->pz);
|
|
Ivan Mahonin |
fdbd7d |
if (gm->pz.image) animationDestroy(gm->pz.image);
|
|
Ivan Mahonin |
fdbd7d |
free(gm->path);
|
|
Ivan Mahonin |
fdbd7d |
free(gm->imgname);
|
|
Ivan Mahonin |
fdbd7d |
memset(gm, 0, sizeof(*gm));
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int gameCreate(Game *gm, const char *path, const char *imgname, int rows, int cols, int turn, int seed) {
|
|
Ivan Mahonin |
fdbd7d |
gameFree(gm);
|
|
Ivan Mahonin |
fdbd7d |
char* imgpath = findImage(imgname);
|
|
Ivan Mahonin |
fdbd7d |
if (!imgpath) return ERR("gameCreate: cannot find image: %s", imgname);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
gm->pz.image = createAnimationEx(imgpath, TRUE, FALSE, FALSE);
|
|
Ivan Mahonin |
fdbd7d |
free(imgpath);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int iw = animationGetOrigWidth(gm->pz.image);
|
|
Ivan Mahonin |
fdbd7d |
int ih = animationGetOrigHeight(gm->pz.image);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (rows < 1 || cols < 1 || rows*cols < 2) {
|
|
Ivan Mahonin |
fdbd7d |
int count = rows;
|
|
Ivan Mahonin |
fdbd7d |
if (count < 4) count = 4;
|
|
Ivan Mahonin |
fdbd7d |
double s = sqrt(iw*ih/(double)count);
|
|
Ivan Mahonin |
fdbd7d |
cols = (int)round(iw/s);
|
|
Ivan Mahonin |
fdbd7d |
if (cols < 1) cols = 1;
|
|
Ivan Mahonin |
fdbd7d |
rows = (int)round(ih/s);
|
|
Ivan Mahonin |
fdbd7d |
if (rows < 1) rows = 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
double cw = iw/(double)cols;
|
|
Ivan Mahonin |
fdbd7d |
double ch = ih/(double)rows;
|
|
Ivan Mahonin |
fdbd7d |
if (cw > ch) { ch /= cw; cw = 1; }
|
|
Ivan Mahonin |
fdbd7d |
else { cw /= ch; ch = 1; }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int px = (int)exp2(round(log2(1024/cols)));
|
|
Ivan Mahonin |
fdbd7d |
if (px < 8) px = 8;
|
|
Ivan Mahonin |
fdbd7d |
if (px > 1024) px = 1024;
|
|
Ivan Mahonin |
fdbd7d |
DBG("iw %d, ih %d, cols %d, rows %d, px %d, cw %g, ch %g", iw, ih, cols, rows, px, cw , ch);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int prevseed = rand();
|
|
Ivan Mahonin |
fdbd7d |
gm->pz.turn = !!turn;
|
|
Ivan Mahonin |
fdbd7d |
gm->path = strprintf("%s", path);
|
|
Ivan Mahonin |
fdbd7d |
gm->imgname = strprintf("%s", imgname);
|
|
Ivan Mahonin |
fdbd7d |
gm->seed = seed;
|
|
Ivan Mahonin |
fdbd7d |
while(!gm->seed) gm->seed = rand();
|
|
Ivan Mahonin |
fdbd7d |
srand(gm->seed);
|
|
Ivan Mahonin |
fdbd7d |
puzzleAlloc(&gm->pz, rows, cols);
|
|
Ivan Mahonin |
fdbd7d |
puzzleGenLines(&gm->pz, cw, ch, 0.05, 1/5.0);
|
|
Ivan Mahonin |
fdbd7d |
puzzleGenChunks(&gm->pz);
|
|
Ivan Mahonin |
fdbd7d |
puzzleRenderChunks(&gm->pz, px, 0.3);
|
|
Ivan Mahonin |
fdbd7d |
srand(prevseed);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
gameSave(gm);
|
|
Ivan Mahonin |
fdbd7d |
return 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int gameSave(Game *gm) {
|
|
Ivan Mahonin |
fdbd7d |
char *tmp = strprintf("%s.tmp", gm->path);
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = fopen(tmp, "w");
|
|
Ivan Mahonin |
fdbd7d |
if (!f) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("gameSave: cannot open file for write: %s", tmp);
|
|
Ivan Mahonin |
fdbd7d |
free(tmp);
|
|
Ivan Mahonin |
fdbd7d |
return 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
puzzleRecalcGroups(&gm->pz);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
// puzzle1
|
|
Ivan Mahonin |
dcf1b6 |
// <[img-file]>
|
|
Ivan Mahonin |
dcf1b6 |
// <rows <cols> <groups> <seed>
|
|
Ivan Mahonin |
dcf1b6 |
// <gid> [<order> <x> <y> <angle>]...
|
|
Ivan Mahonin |
dcf1b6 |
fprintf(f, "puzzle1.0\n[%s]\n%d %d %d %d %d\n", gm->imgname, gm->pz.rows, gm->pz.cols, !!gm->pz.turn, gm->pz.groups, gm->seed);
|
|
Ivan Mahonin |
fdbd7d |
Chunk *chunks = gm->pz.chunks[0];
|
|
Ivan Mahonin |
fdbd7d |
int cnt = gm->pz.rows * gm->pz.cols;
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
int *orders = (int*)alloc(cnt*ASIZEOF(int));
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = cnt-1; i >= 0; --i) orders[ chunkGid(gm->pz.chunksOrder[i]) ] = i;
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < cnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
Chunk *c = &chunks[i];
|
|
Ivan Mahonin |
fdbd7d |
PhGroup *g = c->parent;
|
|
Ivan Mahonin |
dcf1b6 |
int gid = chunkGid(c);
|
|
Ivan Mahonin |
dcf1b6 |
if (i == gid) fprintf(f, "%d %d %g %g %g\n", gid, orders[gid], g->o.x, g->o.y, vangled(g->dx));
|
|
Ivan Mahonin |
dcf1b6 |
else fprintf(f, "%d\n", gid);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
dcf1b6 |
free(orders);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
fflush(f);
|
|
Ivan Mahonin |
fdbd7d |
int err = ferror(f);
|
|
Ivan Mahonin |
fdbd7d |
if (err) ERR("gameSave: cannot write to file: %s", tmp);
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (!err) {
|
|
Ivan Mahonin |
fdbd7d |
err = rename(tmp, gm->path);
|
|
Ivan Mahonin |
fdbd7d |
if (err) ERR("gameSave: cannot rename file: [%s] -> [%s]", tmp, gm->path);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
if (err) remove(tmp);
|
|
Ivan Mahonin |
fdbd7d |
free(tmp);
|
|
Ivan Mahonin |
fdbd7d |
return !err;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
static FILE* internalLoadGameInfo(GameInfo *gi, const char *path) {
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = fopen(path, "r");
|
|
Ivan Mahonin |
fdbd7d |
if (!f) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("loadGameInfo: cannot open file for read: %s", path);
|
|
Ivan Mahonin |
fdbd7d |
return NULL;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
dcf1b6 |
char *l = trim(readline(f));
|
|
Ivan Mahonin |
dcf1b6 |
if (strcmp(l, "puzzle1.0")) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("loadGameInfo: wrong file version (expected: puzzle1): %s", l);
|
|
Ivan Mahonin |
fdbd7d |
free(l); fclose(f); return NULL;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
l = unquote(readline(f), '[', ']');
|
|
Ivan Mahonin |
fdbd7d |
fscanf(f, "%d%d%d%d%d", &gi->rows, &gi->cols, &gi->turn, &gi->groups, &gi->seed);
|
|
Ivan Mahonin |
fdbd7d |
if ( gi->rows < 1 || gi->cols < 1 || gi->rows*gi->cols < 2
|
|
Ivan Mahonin |
fdbd7d |
|| gi->turn < 0 || gi->turn > 1
|
|
Ivan Mahonin |
fdbd7d |
|| gi->groups < 1 || gi->groups > gi->rows*gi->cols )
|
|
Ivan Mahonin |
fdbd7d |
{
|
|
Ivan Mahonin |
fdbd7d |
ERR("loadGameInfo: bad data in file: %s, [%dx%d, %d], %d", path, gi->rows, gi->cols, gi->turn, gi->groups);
|
|
Ivan Mahonin |
fdbd7d |
free(l); fclose(f); return NULL;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
if (ferror(f)) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("loadGameInfo: cannot read from file: %s", path);
|
|
Ivan Mahonin |
fdbd7d |
free(l); fclose(f); return NULL;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
fdbd7d |
gi->imgname = l;
|
|
Ivan Mahonin |
fdbd7d |
return f;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
GameInfo* loadGameInfo(const char *path) {
|
|
Ivan Mahonin |
fdbd7d |
GameInfo gi = { .t = filetime(path) };
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = internalLoadGameInfo(&gi, path);
|
|
Ivan Mahonin |
fdbd7d |
if (!f) return NULL;
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
GameInfo *r = alloc(ASIZEOF(*r) + strlen(gi.imgname) + 1);
|
|
Ivan Mahonin |
fdbd7d |
memcpy(r, &gi, sizeof(*r));
|
|
Ivan Mahonin |
fdbd7d |
r->imgname = strcpy((char*)(r+1), gi.imgname);
|
|
Ivan Mahonin |
fdbd7d |
return r;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int gameLoad(Game *gm, const char *path) {
|
|
Ivan Mahonin |
fdbd7d |
gameFree(gm);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
GameInfo gi = {};
|
|
Ivan Mahonin |
fdbd7d |
FILE *f = internalLoadGameInfo(&gi, path);
|
|
Ivan Mahonin |
fdbd7d |
if (!f) return ERR("gameLoad: cannot load game info: %s", path);
|
|
Ivan Mahonin |
fdbd7d |
if (!gameCreate(gm, path, gi.imgname, gi.rows, gi.cols, gi.turn, gi.seed)) {
|
|
Ivan Mahonin |
fdbd7d |
ERR("gameLoad: cannot create game: %s, %s, %dx%d, seed %d", path, gi.imgname, gi.rows, gi.cols, gi.seed);
|
|
Ivan Mahonin |
fdbd7d |
free(gi.imgname);
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
fdbd7d |
return 0;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int cnt = gm->pz.rows * gm->pz.cols;
|
|
Ivan Mahonin |
fdbd7d |
Chunk *chunks = gm->pz.chunks[0];
|
|
Ivan Mahonin |
dcf1b6 |
int *orders = (int*)alloc(2*cnt*ASIZEOF(int));
|
|
Ivan Mahonin |
dcf1b6 |
int *groups = orders + cnt;
|
|
Ivan Mahonin |
dcf1b6 |
double *coords = (double*)alloc(cnt*3*ASIZEOF(double));
|
|
Ivan Mahonin |
dcf1b6 |
int processed = 0;
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = 0; i < cnt && !feof(f); ++i, ++processed) {
|
|
Ivan Mahonin |
fdbd7d |
int gid = -1;
|
|
Ivan Mahonin |
fdbd7d |
fscanf(f, "%d", &gid);
|
|
Ivan Mahonin |
dcf1b6 |
if (gid < 0 || gid >= cnt) {
|
|
Ivan Mahonin |
dcf1b6 |
WRN("gameLoad: invalid group");
|
|
Ivan Mahonin |
dcf1b6 |
break;
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Chunk *c = &chunks[i];
|
|
Ivan Mahonin |
fdbd7d |
Chunk *p = &chunks[gid];
|
|
Ivan Mahonin |
fdbd7d |
if (i == gid) {
|
|
Ivan Mahonin |
fdbd7d |
double v[3] = {};
|
|
Ivan Mahonin |
dcf1b6 |
fscanf(f, "%d%lg%lg%lg", &groups[gid], v+0, v+1, v+2);
|
|
Ivan Mahonin |
fdbd7d |
if (!(v[0] == v[0]) || !(v[1] == v[1]) || !(v[2] == v[2])) {
|
|
Ivan Mahonin |
dcf1b6 |
WRN("gameLoad: invalid chunk data");
|
|
Ivan Mahonin |
fdbd7d |
break;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
memcpy(coords + i*3, v, sizeof(v));
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
chunkMerge(p, c);
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
fclose(f);
|
|
Ivan Mahonin |
dcf1b6 |
|
|
Ivan Mahonin |
dcf1b6 |
int orderIsValid = 1;
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = 0; i < cnt; ++i) orders[i] = -1;
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = 0; i < cnt; ++i) {
|
|
Ivan Mahonin |
dcf1b6 |
int order = groups[ chunkGid(&chunks[i]) ]++;
|
|
Ivan Mahonin |
dcf1b6 |
if (order >= 0 && order < cnt) orders[order] = i; else
|
|
Ivan Mahonin |
dcf1b6 |
WRN("gameLoad: invalid order");
|
|
Ivan Mahonin |
dcf1b6 |
}
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = 0; i < cnt; ++i) if (orders[i] < 0)
|
|
Ivan Mahonin |
dcf1b6 |
orderIsValid = 0;
|
|
Ivan Mahonin |
dcf1b6 |
if (!orderIsValid) WRN("gameLoad: invalid order"); else
|
|
Ivan Mahonin |
dcf1b6 |
for(int i = 0; i < cnt; ++i) gm->pz.chunksOrder[i] = &chunks[orders[i]];
|
|
Ivan Mahonin |
dcf1b6 |
free(orders);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
for(int i = 0; i < cnt; ++i) {
|
|
Ivan Mahonin |
fdbd7d |
Chunk *c = &chunks[i];
|
|
Ivan Mahonin |
fdbd7d |
if (c->parent != &c->group) continue;
|
|
Ivan Mahonin |
fdbd7d |
PhGroup *g = c->parent;
|
|
Ivan Mahonin |
fdbd7d |
g->o.x = coords[3*i + 0];
|
|
Ivan Mahonin |
fdbd7d |
g->o.y = coords[3*i + 1];
|
|
Ivan Mahonin |
fdbd7d |
g->dx = gm->pz.turn ? vcossind(coords[3*i + 2]) : vec(1,0);
|
|
Ivan Mahonin |
fdbd7d |
phGroupPlaceNodes(g);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
free(coords);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
return 1;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void gameDraw(Game *gm) {
|
|
Ivan Mahonin |
fdbd7d |
int w = windowGetWidth();
|
|
Ivan Mahonin |
fdbd7d |
int h = windowGetHeight();
|
|
Ivan Mahonin |
fdbd7d |
Vec s = { w, h };
|
|
Ivan Mahonin |
fdbd7d |
saveState();
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
translate(w/2, h/2);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
double pw = gm->pz.cols*gm->pz.cs.x;
|
|
Ivan Mahonin |
fdbd7d |
double ph = gm->pz.rows*gm->pz.cs.y;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
double k = mind(w/pw, h/ph);
|
|
Ivan Mahonin |
fdbd7d |
double kwin = k*0.9;
|
|
Ivan Mahonin |
fdbd7d |
k /= 1.5;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (gameWon(gm)) {
|
|
Ivan Mahonin |
fdbd7d |
double dt = windowGetFrameTime();
|
|
Ivan Mahonin |
fdbd7d |
gm->winTransition += dt;
|
|
Ivan Mahonin |
fdbd7d |
if (gm->winTransition > 1) gm->winTransition = 1;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
PhGroup *g0 = gm->pz.ph.first;
|
|
Ivan Mahonin |
fdbd7d |
k = lintr(k, kwin, gm->winTransition);
|
|
Ivan Mahonin |
fdbd7d |
Vec o = vlintr(g0->o, vzero(), gm->winTransition);
|
|
Ivan Mahonin |
fdbd7d |
double a = lintr(vangled(g0->dx), 0, gm->winTransition);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
zoom(k);
|
|
Ivan Mahonin |
fdbd7d |
strokeWidth(3/k);
|
|
Ivan Mahonin |
fdbd7d |
translate(o.x, o.y);
|
|
Ivan Mahonin |
fdbd7d |
rotate(a);
|
|
Ivan Mahonin |
fdbd7d |
rectTextured(gm->pz.image, -pw/2, -ph/2, pw, ph);
|
|
Ivan Mahonin |
fdbd7d |
} else {
|
|
Ivan Mahonin |
fdbd7d |
zoom(k);
|
|
Ivan Mahonin |
fdbd7d |
strokeWidth(3/k);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
Vec mouse = { mouseTransformedX(), mouseTransformedY() };
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentDown("left"))
|
|
Ivan Mahonin |
fdbd7d |
puzzleChooseChunks(&gm->pz, mouse);
|
|
Ivan Mahonin |
fdbd7d |
if (mouseWentUp("left"))
|
|
Ivan Mahonin |
fdbd7d |
puzzleReleaseChunks(&gm->pz);
|
|
Ivan Mahonin |
fdbd7d |
puzzleUpdate(&gm->pz, vdiv(s, 2*k), mouse);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
int cnt = gm->pz.cols*gm->pz.rows;
|
|
Ivan Mahonin |
fdbd7d |
for(int i = cnt-1; i >= 0; --i) {
|
|
Ivan Mahonin |
fdbd7d |
chunkDraw(gm->pz.chunksOrder[i]);
|
|
Ivan Mahonin |
fdbd7d |
//chunkDrawDebug(gm->pz.chunksOrder[i]);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
//physicsDrawDebug(&gm->pz.ph);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
restoreState();
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
/*saveState();
|
|
Ivan Mahonin |
fdbd7d |
noFill();
|
|
Ivan Mahonin |
fdbd7d |
stroke(COLOR_WHITE);
|
|
Ivan Mahonin |
fdbd7d |
textf(10, 10, "fps: %f", 1/windowGetFrameTime());
|
|
Ivan Mahonin |
fdbd7d |
restoreState();*/
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|