@@ 1,845 0,0 @@
-#include <SDL2/SDL.h>
-#include <stdio.h>
-#include <math.h>
-
-/*
-Copyright (c) 2020 Devine Lu Linvega
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE.
-*/
-
-#define HOR 0x3c
-#define VER 0x22
-#define SZ (HOR * VER * 16)
-
-#define VLIMIT 256
-#define ELIMIT 512
-#define MLIMIT 128
-#define PI 3.14159265358979323846
-
-#define VIEWFRONT Pt3d(180, 0, 0)
-#define VIEWTOP Pt3d(90, 0, 0)
-#define VIEWSIDE Pt3d(90, 90, 0)
-
-typedef struct {
- double x, y;
-} Point2d;
-
-typedef struct {
- double x, y, z;
-} Point3d;
-
-typedef struct {
- int color;
- Point3d *a, *b;
-} Edge;
-
-typedef struct {
- int verticeslen, edgeslen;
- Point3d position, vertices[VLIMIT];
- Edge edges[ELIMIT];
-} Mesh;
-
-typedef struct {
- int len;
- Point3d position, scale, rotation;
- Mesh meshes[MLIMIT];
-} Scene;
-
-typedef enum {
- ISOMETRIC,
- PERSPECTIVE
-} Projection;
-
-typedef struct {
- double range;
- Point3d origin, rotation, torigin, trotation;
- Projection projection;
-} Camera;
-
-typedef struct {
- Uint8 down;
- double x, y;
-} Mouse;
-
-static int WIDTH = 8 * HOR;
-static int HEIGHT = 8 * (VER + 2);
-static int FPS = 30, GUIDES = 1, ZOOM = 1;
-
-static Scene scn;
-static Camera cam;
-static Mouse mouse;
-
-/* interface */
-
-static Uint32 theme[] = {
- 0x000000,
- 0XFFFFFF,
- 0x72DEC2,
- 0x666666,
- 0x222222};
-
-static SDL_Window *gWindow = NULL;
-static SDL_Renderer *gRenderer = NULL;
-static SDL_Texture *gTexture = NULL;
-static Uint32 *pixels;
-
-/* helpers */
-
-static Point2d
-Pt2d(double x, double y)
-{
- Point2d p;
- p.x = x;
- p.y = y;
- return p;
-}
-
-static Point3d *
-set3d(Point3d *v, double x, double y, double z)
-{
- v->x = x;
- v->y = y;
- v->z = z;
- return v;
-}
-
-static Point3d
-Pt3d(double x, double y, double z)
-{
- Point3d p;
- set3d(&p, x, y, z);
- return p;
-}
-
-static Scene
-Sc3d(void)
-{
- Scene s;
- s.len = 0;
- set3d(&s.position, 0, 0, 0);
- set3d(&s.scale, 1, 1, 1);
- set3d(&s.rotation, 0, 0, 0);
- return s;
-}
-
-static Camera
-Cm3d(double pitch, double yaw, double roll, double range)
-{
- Camera c;
- set3d(&c.rotation, pitch, yaw, roll);
- set3d(&c.trotation, pitch, yaw, roll);
- c.projection = PERSPECTIVE;
- c.range = range;
- return c;
-}
-
-/* geometry */
-
-static double
-interpolate(double a, double b, double speed, double range)
-{
- if(a < b - range || a > b + range)
- a += (b - a) / speed;
- else
- a = b;
- return a;
-}
-
-static Point2d
-rot2d(Point2d a, Point2d b, double deg)
-{
- double radian = deg * (PI / 180);
- double angle = atan2(b.y - a.y, b.x - a.x) + radian;
- double r = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
- return Pt2d(a.x + r * cos(angle), a.y + r * sin(angle));
-}
-
-static int
-equpt3d(Point3d p0, Point3d p1)
-{
- return p0.x == p1.x && p0.y == p1.y && p0.z == p1.z;
-}
-
-static Point3d *
-addpt3d(Point3d *p, double x, double y, double z)
-{
- return set3d(p, p->x + x, p->y + y, p->z + z);
-}
-
-static Point3d
-add3d(Point3d *a, Point3d *b)
-{
- return Pt3d(a->x + b->x, a->y + b->y, a->z + b->z);
-}
-
-static Point3d
-mul3d(Point3d *a, Point3d *b)
-{
- return Pt3d(a->x * b->x, a->y * b->y, a->z * b->z);
-}
-
-/* scene */
-
-static Point3d *
-translate3d(Point3d *p, Point3d *t)
-{
- *p = add3d(p, t);
- return p;
-}
-
-static Point3d *
-scale3d(Point3d *p, Point3d *t)
-{
- *p = mul3d(p, t);
- return p;
-}
-
-static Point3d *
-rotate3d(Point3d *p, Point3d *o, Point3d *t)
-{
- if(t->x) {
- Point2d r = rot2d(Pt2d(o->y, o->z), Pt2d(p->y, p->z), t->x);
- p->y = r.x;
- p->z = r.y;
- }
- if(t->y) {
- Point2d r = rot2d(Pt2d(o->x, o->z), Pt2d(p->x, p->z), t->y);
- p->x = r.x;
- p->z = r.y;
- }
- if(t->z) {
- Point2d r = rot2d(Pt2d(o->x, o->y), Pt2d(p->x, p->y), t->z);
- p->x = r.x;
- p->y = r.y;
- }
- return p;
-}
-
-static Scene *
-moveto(Scene *s, double x, double y, double z)
-{
- set3d(&s->position, x, y, z);
- return s;
-}
-
-static Scene *
-scaleto(Scene *s, double x, double y, double z)
-{
- set3d(&s->scale, x, y, z);
- return s;
-}
-
-static Scene *
-rotateto(Scene *s, double x, double y, double z)
-{
- set3d(&s->rotation, x, y, z);
- return s;
-}
-
-static Scene *
-reset(Scene *s)
-{
- moveto(scaleto(rotateto(s, 0, 0, 0), 1, 1, 1), 0, 0, 0);
- return s;
-}
-
-static Point3d *
-addvertex(Mesh *m, double x, double y, double z)
-{
- int i;
- Point3d v = Pt3d(x, y, z);
- if(m->verticeslen == VLIMIT) {
- printf("Warning: Reached vertex limit\n");
- return NULL;
- }
- translate3d(&v, &scn.position);
- scale3d(&v, &scn.scale);
- rotate3d(&v, &scn.position, &scn.rotation);
- for(i = 0; i < m->verticeslen; ++i)
- if(equpt3d(m->vertices[i], v))
- return &m->vertices[i];
- return set3d(&m->vertices[m->verticeslen++], v.x, v.y, v.z);
-}
-
-static Edge *
-addedge(Mesh *m, Point3d *a, Point3d *b, int color)
-{
- if(m->edgeslen == ELIMIT) {
- printf("Warning: Reached edge limit\n");
- return NULL;
- }
- m->edges[m->edgeslen].a = a;
- m->edges[m->edgeslen].b = b;
- m->edges[m->edgeslen].color = color;
- return &m->edges[m->edgeslen++];
-}
-
-static Mesh *
-addmesh(Scene *s)
-{
- if(s->len == MLIMIT) {
- printf("Warning: Reached mesh limit\n");
- return NULL;
- }
- return &s->meshes[s->len++];
-}
-
-/* Primitives */
-
-static Mesh *
-addpoly(Mesh *m, int a, int b, int c, int color)
-{
- addedge(m, &m->vertices[a], &m->vertices[b], color);
- addedge(m, &m->vertices[b], &m->vertices[c], color);
- addedge(m, &m->vertices[c], &m->vertices[a], color);
- return m;
-}
-
-static Mesh *
-addline(Mesh *m, Point3d a, Point3d b, int color)
-{
- addedge(m, addvertex(m, a.x, a.y, a.z), addvertex(m, b.x, b.y, b.z), color);
- return m;
-}
-
-static Mesh *
-addarc(Mesh *m, double radius, double segs, double angle, int color)
-{
- int i;
- double arc = 2 * PI * angle / 360 / segs;
- Point3d b;
- for(i = 0; i < segs + 1; i++) {
- Point3d a = Pt3d(radius * cos(i * arc), radius * sin(i * arc), 0);
- if(i > 0)
- addline(m, a, b, color);
- b = a;
- }
- return m;
-}
-
-static Mesh *
-addshape(Mesh *m, double radius, int segs, int color)
-{
- return addarc(m, radius, segs, 360, color);
-}
-
-/* draw */
-
-static void
-clear(Uint32 *dst)
-{
- int i;
- for(i = 0; i < WIDTH * HEIGHT; i++)
- dst[i] = theme[0];
-}
-
-static void
-putpixel(Uint32 *dst, int x, int y, Uint32 color)
-{
- if(x > 0 && y > 0 && x < WIDTH && y < HEIGHT)
- dst[y * WIDTH + x] = color;
-}
-
-static Uint32
-getpixel(Uint32 *src, int x, int y)
-{
- if(x > 0 && y > 0 && x < WIDTH && y < HEIGHT)
- return src[y * WIDTH + x];
- return 0;
-}
-
-static void
-line(Uint32 *dst, Point2d p0, Point2d p1, Uint32 color)
-{
- int p0x = (int)p0.x, p0y = (int)p0.y;
- int p1x = (int)p1.x, p1y = (int)p1.y;
- int dx = abs(p1x - p0x), sx = p0x < p1x ? 1 : -1;
- int dy = -abs(p1y - p0y), sy = p0y < p1y ? 1 : -1;
- int err = dx + dy, e2;
- for(;;) {
- putpixel(dst, p0x, p0y, color);
- if(p0x == p1x && p0y == p1y)
- break;
- e2 = 2 * err;
- if(e2 >= dy) {
- err += dy;
- p0x += sx;
- }
- if(e2 <= dx) {
- err += dx;
- p0y += sy;
- }
- }
-}
-
-static Point2d
-project(Camera *c, Point3d v)
-{
- double r;
- if(c->projection == ISOMETRIC)
- return Pt2d(
- (WIDTH / 2) + v.x * (10 - c->range / 10),
- (HEIGHT / 2) + v.y * (10 - c->range / 10));
- r = 200 / (v.z + c->range);
- return Pt2d(WIDTH / 2 + r * v.x, HEIGHT / 2 + r * v.y);
-}
-
-static void
-redraw(Uint32 *dst)
-{
- int i, j;
- clear(dst);
- for(i = 0; i < scn.len; i++) {
- Mesh *m = &scn.meshes[i];
- for(j = 0; j < m->edgeslen; j++) {
- Edge *edge = &m->edges[j];
- Point3d a = add3d(edge->a, &m->position);
- Point3d b = add3d(edge->b, &m->position);
- rotate3d(&a, &cam.origin, &cam.rotation);
- rotate3d(&b, &cam.origin, &cam.rotation);
- line(dst,
- project(&cam, add3d(&cam.origin, &a)),
- project(&cam, add3d(&cam.origin, &b)),
- theme[edge->color]);
- }
- }
- SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32));
- SDL_RenderClear(gRenderer);
- SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
- SDL_RenderPresent(gRenderer);
-}
-
-/* options */
-
-static int
-error(char *msg, const char *err)
-{
- printf("Error %s: %s\n", msg, err);
- return 0;
-}
-
-static void
-update(Camera *c, double speed)
-{
- if(!equpt3d(c->rotation, c->trotation) || !equpt3d(c->origin, c->torigin)) {
- set3d(&c->rotation,
- interpolate(c->rotation.x, c->trotation.x, speed, 1),
- interpolate(c->rotation.y, c->trotation.y, speed, 1),
- interpolate(c->rotation.z, c->trotation.z, speed, 1));
- set3d(&c->origin,
- interpolate(c->origin.x, c->torigin.x, speed, 1),
- interpolate(c->origin.y, c->torigin.y, speed, 1),
- interpolate(c->origin.z, c->torigin.z, speed, 1));
- redraw(pixels);
- }
-}
-
-static void
-modzoom(int mod)
-{
- if((mod > 0 && ZOOM < 4) || (mod < 0 && ZOOM > 1))
- ZOOM += mod;
- SDL_SetWindowSize(gWindow, WIDTH * ZOOM, HEIGHT * ZOOM);
- redraw(pixels);
-}
-
-static void
-toggleprojection(Camera *c)
-{
- c->projection = c->projection == ISOMETRIC ? PERSPECTIVE : ISOMETRIC;
- redraw(pixels);
-}
-
-static void
-setguides(int v)
-{
- GUIDES = v;
- redraw(pixels);
-}
-
-static void
-modrange(int mod)
-{
- int res = cam.range + mod;
- if(res > 0 && res < 90)
- cam.range = res;
- redraw(pixels);
-}
-
-static void
-export_icn(Uint32 *src, int width, int height, char *filename)
-{
- int i, x, y;
- Uint8 icnbuf[SZ];
- FILE *f = fopen(filename, "wb");
- /* clean */
- for(i = 0; i < SZ; ++i)
- icnbuf[i] = 0;
- /* write pixels */
- for(y = 0; y < height; ++y) {
- for(x = 0; x < width; ++x) {
- int color = getpixel(src, x, y);
- if(color) {
- int col = x & 7, row = y & 7;
- int byte = (x & ~7) + (y & ~7) * width / 8 + row;
- icnbuf[byte] |= 1 << (7 - col);
- }
- }
- }
- /* save */
- if(!fwrite(icnbuf, sizeof(icnbuf), 1, f))
- fprintf(stderr, "Failed: %s!\n", filename);
- fclose(f);
- fprintf(stderr, "Export: %s\n", filename);
-}
-
-static void
-renderbmp(void)
-{
- SDL_Surface *surface = SDL_GetWindowSurface(gWindow);
- setguides(0);
- SDL_RenderReadPixels(gRenderer,
- NULL,
- SDL_PIXELFORMAT_ARGB8888,
- surface->pixels,
- surface->pitch);
- if(SDL_SaveBMP(surface, "moogle-render.bmp"))
- printf("SDL_SaveBMP failed: %s\n", SDL_GetError());
- else
- puts("Rendered moogle-render.bmp");
- SDL_FreeSurface(surface);
-}
-
-static void
-quit(void)
-{
- free(pixels);
- SDL_DestroyTexture(gTexture);
- gTexture = NULL;
- SDL_DestroyRenderer(gRenderer);
- gRenderer = NULL;
- SDL_DestroyWindow(gWindow);
- gWindow = NULL;
- SDL_Quit();
- exit(0);
-}
-
-static void
-dokey(SDL_Event *event)
-{
- int shift = SDL_GetModState() & KMOD_LSHIFT || SDL_GetModState() & KMOD_RSHIFT;
- switch(event->key.keysym.sym) {
- case SDLK_EQUALS:
- case SDLK_PLUS: modzoom(1); break;
- case SDLK_UNDERSCORE:
- case SDLK_MINUS: modzoom(-1); break;
- case SDLK_TAB: toggleprojection(&cam); break;
- case SDLK_1: set3d(&cam.trotation, VIEWFRONT.x, VIEWFRONT.y, VIEWFRONT.z); break;
- case SDLK_2: set3d(&cam.trotation, VIEWTOP.x, VIEWTOP.y, VIEWTOP.z); break;
- case SDLK_3: set3d(&cam.trotation, VIEWSIDE.x, VIEWSIDE.y, VIEWSIDE.z); break;
- case SDLK_e: export_icn(pixels, WIDTH, HEIGHT, "untitled.icn"); break;
- case SDLK_r: renderbmp(); break;
- case SDLK_h: setguides(!GUIDES); break;
- case SDLK_UP:
- case SDLK_w:
- if(shift)
- addpt3d(&cam.torigin, 0, 2.5, 0);
- else
- addpt3d(&cam.trotation, 5, 0, 0);
- break;
- case SDLK_LEFT:
- case SDLK_a:
- if(shift)
- addpt3d(&cam.torigin, 2.5, 0, 0);
- else
- addpt3d(&cam.trotation, 0, -5, 0);
- break;
- case SDLK_DOWN:
- case SDLK_s:
- if(shift)
- addpt3d(&cam.torigin, 0, -2.5, 0);
- else
- addpt3d(&cam.trotation, -5, 0, 0);
- break;
- case SDLK_RIGHT:
- case SDLK_d:
- if(shift)
- addpt3d(&cam.torigin, -2.5, 0, 0);
- else
- addpt3d(&cam.trotation, 0, 3.0, 0);
- break;
- case SDLK_f:
- set3d(&cam.torigin, 0, 0, 0);
- set3d(&cam.trotation, VIEWFRONT.x, VIEWFRONT.y, VIEWFRONT.z);
- break;
- case SDLK_z:
- if(shift)
- addpt3d(&cam.torigin, 0, 0, 2.5);
- else
- modrange(3.0);
- break;
- case SDLK_x:
- if(shift)
- addpt3d(&cam.torigin, 0, 0, -2.5);
- else
- modrange(-3.0);
- break;
- }
- redraw(pixels);
-}
-
-static int
-init(void)
-{
- if(SDL_Init(SDL_INIT_VIDEO) < 0)
- return error("Init", SDL_GetError());
- gWindow = SDL_CreateWindow("Moogle",
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- WIDTH * ZOOM,
- HEIGHT * ZOOM,
- SDL_WINDOW_SHOWN);
- if(gWindow == NULL)
- return error("Window", SDL_GetError());
- gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
- if(gRenderer == NULL)
- return error("Renderer", SDL_GetError());
- gTexture = SDL_CreateTexture(gRenderer,
- SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_STATIC,
- WIDTH,
- HEIGHT);
- if(gTexture == NULL)
- return error("Texture", SDL_GetError());
- pixels = (Uint32 *)malloc(WIDTH * HEIGHT * sizeof(Uint32));
- if(pixels == NULL)
- return error("Pixels", "Failed to allocate memory");
- clear(pixels);
- return 1;
-}
-
-/* transforms */
-
-Mesh *
-translate(Mesh *m, double x, double y, double z)
-{
- int i;
- Point3d t = Pt3d(x, y, z);
- for(i = 0; i < m->verticeslen; i++)
- translate3d(&m->vertices[i], &t);
- return m;
-}
-
-Mesh *
-scale(Mesh *m, double x, double y, double z)
-{
- int i;
- Point3d t = Pt3d(x, y, z);
- for(i = 0; i < m->verticeslen; i++)
- scale3d(&m->vertices[i], &t);
- return m;
-}
-
-Mesh *
-rotate(Mesh *m, double pitch, double yaw, double roll)
-{
- int i;
- Point3d t = Pt3d(pitch, yaw, roll);
- for(i = 0; i < m->verticeslen; i++)
- rotate3d(&m->vertices[i], &m->position, &t);
- return m;
-}
-
-Mesh *
-extrude(Mesh *m, Point3d t, int color)
-{
- int i, j, vl = m->verticeslen, el = m->edgeslen;
- for(i = 0; i < vl; i++) {
- Point3d *a = &m->vertices[i];
- addedge(m, &m->vertices[i], addvertex(m, a->x + t.x, a->y + t.y, a->z + t.z), color);
- }
- for(i = 0; i < el; i++) {
- Edge *e0 = &m->edges[i];
- Edge *e1 = addedge(m, e0->a, e0->b, e0->color);
- for(j = 0; j < vl; j++) {
- if(e0->a == &m->vertices[j])
- e1->a = &m->vertices[vl + j];
- else if(e0->b == &m->vertices[j])
- e1->b = &m->vertices[vl + j];
- }
- }
- return m;
-}
-
-/* Primitives */
-
-Mesh *
-createfrustum(Scene *s, double radius, int segs, double depth, double cap, int color)
-{
- int i;
- Mesh *m = addmesh(s);
- addshape(m, cap, segs, color);
- translate(m, 0, 0, depth);
- addshape(m, radius, segs, color);
- for(i = 0; i < segs + 1; i++)
- addedge(m, &m->vertices[i], &m->vertices[segs + i + 1], color);
- return m;
-}
-
-Mesh *
-createpyramid(Scene *s, double radius, int segs, double depth, int color)
-{
- int i;
- Mesh *m = addmesh(s);
- Point3d *p = addvertex(m, 0, 0, depth);
- addshape(m, radius, segs, color);
- for(i = 0; i < segs + 1; i++)
- addedge(m, &m->vertices[i], p, color);
- return m;
-}
-
-Mesh *
-createprism(Scene *s, double radius, int segs, double depth, int color)
-{
- return createfrustum(s, radius, segs, depth, radius, color);
-}
-
-Mesh *
-createplane(Scene *s, double width, double height, double xsegs, double ysegs, int color)
-{
- int ix, iy;
- Mesh *m = addmesh(s);
- for(ix = 0; ix < xsegs + 1; ix++)
- addline(m,
- Pt3d(ix * (width / xsegs) - width / 2, height / 2, 0),
- Pt3d(ix * (width / xsegs) - width / 2, -height / 2, 0),
- color);
- for(iy = 0; iy < ysegs + 1; iy++)
- addline(m,
- Pt3d(width / 2, iy * (height / ysegs) - height / 2, 0),
- Pt3d(-width / 2, iy * (height / ysegs) - height / 2, 0),
- color);
- return m;
-}
-
-Mesh *
-createbox(Scene *s, double width, double height, double depth, int color)
-{
- Mesh *m = createplane(s, width, height, 1, 1, color);
- extrude(m, Pt3d(0, 0, depth), color);
- return m;
-}
-
-Mesh *
-createicosaedron(Scene *s, double radius, int color)
-{
- Mesh *m = addmesh(s);
- double t = (1.0 + sqrt(5.0)) / 2.0;
- addvertex(m, -1, t, 0);
- addvertex(m, 1, t, 0);
- addvertex(m, -1, -t, 0);
- addvertex(m, 1, -t, 0);
- addvertex(m, 0, -1, t);
- addvertex(m, 0, 1, t);
- addvertex(m, 0, -1, -t);
- addvertex(m, 0, 1, -t);
- addvertex(m, t, 0, -1);
- addvertex(m, t, 0, 1);
- addvertex(m, -t, 0, -1);
- addvertex(m, -t, 0, 1);
- addpoly(m, 0, 11, 5, color); /* - */
- addpoly(m, 0, 5, 1, color);
- addpoly(m, 0, 1, 7, color);
- addpoly(m, 0, 7, 10, color);
- addpoly(m, 0, 10, 11, color);
- addpoly(m, 1, 5, 9, color); /* - */
- addpoly(m, 5, 11, 4, color);
- addpoly(m, 11, 10, 2, color);
- addpoly(m, 10, 7, 6, color);
- addpoly(m, 7, 1, 8, color);
- addpoly(m, 3, 9, 4, color); /* - */
- addpoly(m, 3, 4, 2, color);
- addpoly(m, 3, 2, 6, color);
- addpoly(m, 3, 6, 8, color);
- addpoly(m, 3, 8, 9, color);
- addpoly(m, 4, 9, 5, color); /* - */
- addpoly(m, 2, 4, 11, color);
- addpoly(m, 6, 2, 10, color);
- addpoly(m, 8, 6, 7, color);
- addpoly(m, 9, 8, 1, color);
- scale(m, radius / 2, radius / 2, radius / 2);
- return m;
-}
-
-Mesh *
-createumbrella(Scene *s)
-{
- int i;
- Mesh *umbrella = addmesh(s);
- reset(s);
- for(i = 0; i < 5; ++i) {
- addarc(umbrella, 10, 8, 180, 2);
- rotateto(s, 0, 45 * i, 0);
- }
- rotateto(s, 90, 0, 0);
- addshape(umbrella, 10, 8, 1);
- translate(scale(umbrella, 1, 0.6, 1), 0, 2, 0);
- addline(umbrella, Pt3d(0, 0, -10), Pt3d(0, 0, 8), 1);
- rotateto(moveto(s, 0, -8, 2), 90, 90, 90);
- addarc(umbrella, 2, 8, 180, 2);
- reset(s);
- return umbrella;
-}
-
-int
-main(void)
-{
- int ticknext = 0;
- scn = Sc3d();
- cam = Cm3d(180, 0, 0, 30);
- if(!init())
- return error("Init", "Failure");
- createumbrella(&scn);
- redraw(pixels);
- while(1) {
- int tick = SDL_GetTicks();
- SDL_Event event;
- if(tick < ticknext)
- SDL_Delay(ticknext - tick);
- ticknext = tick + (1000 / FPS);
- update(&cam, 5);
- while(SDL_PollEvent(&event) != 0) {
- switch(event.type) {
- case SDL_QUIT: quit(); break;
- case SDL_MOUSEWHEEL:
- modrange(event.wheel.y / -1);
- break;
- case SDL_MOUSEBUTTONUP:
- mouse.down = 0;
- break;
- case SDL_MOUSEBUTTONDOWN:
- mouse.down = 1;
- mouse.x = event.motion.x;
- mouse.y = event.motion.y;
- break;
- case SDL_MOUSEMOTION:
- if(mouse.down)
- addpt3d(&cam.trotation, (event.motion.y - mouse.y) / 4, (event.motion.x - mouse.x) / 4, 0);
- break;
- case SDL_KEYDOWN: dokey(&event); break;
- case SDL_WINDOWEVENT:
- if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
- redraw(pixels);
- break;
- }
- }
- }
- quit();
- return 0;
-}