demosys
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 27 Dec 2021 16:57:15 +0000 (18:57 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 27 Dec 2021 16:57:15 +0000 (18:57 +0200)
src/android/main.c
src/demo.c
src/demo.h
src/demosys.c [new file with mode: 0644]
src/demosys.h [new file with mode: 0644]
src/pc/main_glut.c
src/scr/testa.c [new file with mode: 0644]

index 8c12596..4921087 100644 (file)
@@ -1,16 +1,21 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include "demo.h"
 #include "android_native_app_glue.h"
 #include "logger.h"
+#include "demosys.h"
 
 static void handle_command(struct android_app *app, int32_t cmd);
 static int handle_input(struct android_app *app, AInputEvent *ev);
 static int handle_touch_input(struct android_app *app, AInputEvent *ev);
 static int init_gl(void);
 static void destroy_gl(void);
+static unsigned long get_time_msec(void);
 
 struct android_app *app;
 
@@ -21,6 +26,8 @@ static int init_done, paused;
 
 static int width, height;
 
+static long start_time;
+
 
 void android_main(struct android_app *app_ptr)
 {
@@ -45,12 +52,18 @@ void android_main(struct android_app *app_ptr)
                        return;
                }
                if(init_done && !paused) {
+                       time_msec = (long)get_time_msec() - start_time;
                        demo_display();
                        eglSwapBuffers(dpy, surf);
                }
        }
 }
 
+void swap_buffers(void)
+{
+       eglSwapBuffers(dpy, surf);
+}
+
 static void handle_command(struct android_app *app, int32_t cmd)
 {
        int xsz, ysz;
@@ -58,9 +71,11 @@ static void handle_command(struct android_app *app, int32_t cmd)
        switch(cmd) {
        case APP_CMD_PAUSE:
                paused = 1;     /* TODO: handle timers */
+               dsys_stop();
                break;
        case APP_CMD_RESUME:
                paused = 0;
+               dsys_run();
                break;
 
        case APP_CMD_INIT_WINDOW:
@@ -71,7 +86,9 @@ static void handle_command(struct android_app *app, int32_t cmd)
                        exit(1);
                }
                demo_reshape(width, height);
+               start_time = (long)get_time_msec();
                init_done = 1;
+               dsys_run();
                break;
 
        case APP_CMD_TERM_WINDOW:
@@ -236,3 +253,16 @@ static void destroy_gl(void)
        eglTerminate(dpy);
        dpy = 0;
 }
+
+static unsigned long get_time_msec(void)
+{
+       struct timespec ts;
+       static struct timespec ts0;
+
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       if(ts0.tv_sec == 0 && ts0.tv_nsec == 0) {
+               ts0 = ts;
+               return 0;
+       }
+       return (ts.tv_sec - ts0.tv_sec) * 1000 + (ts.tv_nsec - ts0.tv_nsec) / 1000000;
+}
index 1614426..5023275 100644 (file)
@@ -3,6 +3,7 @@
 #include "opengl.h"
 #include "sanegl.h"
 #include "assman.h"
+#include "demosys.h"
 
 static unsigned int sdr_foo;
 static unsigned int tex_logo;
@@ -19,17 +20,6 @@ int demo_init(void)
        if(!(tex_logo = get_tex2d("data/ml_logo_old.png"))) {
                return -1;
        }
-       return 0;
-}
-
-void demo_cleanup(void)
-{
-}
-
-void demo_display(void)
-{
-       glClear(GL_COLOR_BUFFER_BIT);
-
        glUseProgram(sdr_foo);
        gl_begin(GL_QUADS);
        gl_texcoord2f(0, 1);
@@ -41,21 +31,106 @@ void demo_display(void)
        gl_texcoord2f(0, 0);
        gl_vertex2f(-1, 1);
        gl_end();
+       swap_buffers();
+
+       if(dsys_init("data/demoscript") == -1) {
+               return -1;
+       }
+
+       return 0;
+}
+
+void demo_cleanup(void)
+{
+       dsys_destroy();
+}
+
+void demo_display(void)
+{
+       struct demoscreen *scr;
+
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+       scr = dsys_act_scr;
+       while(scr) {
+               if(scr->update) {
+                       scr->update(dsys_time);
+               }
+               scr->draw();
+               scr = scr->next;
+       }
 }
 
 void demo_reshape(int x, int y)
 {
+       int i;
+
        glViewport(0, 0, x, y);
+
+       for(i=0; i<dsys_num_screens; i++) {
+               if(dsys_screens[i]->reshape) {
+                       dsys_screens[i]->reshape(x, y);
+               }
+       }
 }
 
 void demo_keyboard(int key, int pressed)
 {
+       if(!pressed) return;
+
+       switch(key) {
+       case ' ':
+               if(dsys_running) {
+                       dsys_stop();
+               } else {
+                       dsys_run();
+               }
+               break;
+
+       case '\b':
+               dsys_seek_abs(0);
+               break;
+
+       default:
+               if(key >= '0' && key <= '9') {
+                       dsys_seek_rel((float)(key - '0') / 9.0f);
+
+               } else if(key >= KEY_F1 && key <= KEY_F12) {
+                       int idx = key - KEY_F1;
+                       if(idx < dsys_num_screens) {
+                               dsys_run_screen(dsys_screens[idx]);
+                       }
+
+               } else {
+                       struct demoscreen *scr = dsys_act_scr;
+                       while(scr) {
+                               if(scr->keyboard) {
+                                       scr->keyboard(key, pressed);
+                               }
+                               scr = scr->next;
+                       }
+               }
+       }
 }
 
 void demo_mouse(int bn, int pressed, int x, int y)
 {
+       struct demoscreen *scr = dsys_act_scr;
+       while(scr) {
+               if(scr->mouse) {
+                       scr->mouse(bn, pressed, x, y);
+               }
+               scr = scr->next;
+       }
 }
 
 void demo_motion(int x, int y)
 {
+       struct demoscreen *scr = dsys_act_scr;
+       while(scr) {
+               if(scr->motion) {
+                       scr->motion(x, y);
+               }
+               scr = scr->next;
+       }
 }
index f57a01c..275c552 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef DEMO_H_
 #define DEMO_H_
 
-long demo_time_msec;
+enum {
+       KEY_F1 = 128,
+       KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
+       KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN,
+       KEY_PGUP, KEY_PGDOWN
+};
+
+long time_msec;
 
 int demo_init(void);
 void demo_cleanup(void);
@@ -12,4 +19,6 @@ void demo_keyboard(int key, int pressed);
 void demo_mouse(int bn, int pressed, int x, int y);
 void demo_motion(int x, int y);
 
+void swap_buffers(void);
+
 #endif /* DEMO_H_ */
diff --git a/src/demosys.c b/src/demosys.c
new file mode 100644 (file)
index 0000000..66b4f5f
--- /dev/null
@@ -0,0 +1,93 @@
+#include "demosys.h"
+
+static struct demoscreen *act_tail;
+
+void regscr_testa(void);
+void regscr_testb(void);
+
+int dsys_init(const char *fname)
+{
+       int i;
+
+       regscr_testa();
+       regscr_testb();
+
+       for(i=0; i<dsys_num_screens; i++) {
+               if(dsys_screens[i]->init() == -1) {
+                       fprintf(stderr, "failed to initialize demo screen: %s\n", dsys_screens[i]->name);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+void dsys_destroy(void)
+{
+       int i;
+
+       for(i=0; i<dsys_num_screens; i++) {
+               if(dsys_screens[i]->destroy) {
+                       dsys_screens[i]->destroy();
+               }
+       }
+       dsys_num_screens = 0;
+}
+
+struct demoscreen *dsys_find_screen(const char *name)
+{
+       int i;
+
+       for(i=0; i<dsys_num_screens; i++) {
+               if(strcmp(dsys_screens[i]->name, name) == 0) {
+                       return dsys_screens[i];
+               }
+       }
+       return 0;
+}
+
+void dsys_run_screen(struct demoscreen *scr)
+{
+       struct demoscreen *act;
+
+       if(!scr) return;
+       if(dsys_act_scr == scr && act_tail == scr) return;
+
+       act = dsys_act_scr;
+       while(act) {
+               if(act->stop) act->stop();
+               act = act->next;
+       }
+       dsys_act_scr = act_tail = scr;
+       if(scr->start) scr->start();
+}
+
+void dsys_run(void)
+{
+}
+
+void dsys_stop(void)
+{
+}
+
+void dsys_seek_abs(long tm)
+{
+}
+
+void dsys_seek_rel(long dt)
+{
+}
+
+void dsys_seek_norm(float t)
+{
+}
+
+int dsys_add_screen(struct demoscreen *scr)
+{
+       if(!scr->name || !scr->init || !scr->draw) {
+               fprintf(stderr, "dsys_add_screen: invalid screen\n");
+               return -1;
+       }
+       dsys_screens[dsys_num_screens++] = scr;
+       return 0;
+}
diff --git a/src/demosys.h b/src/demosys.h
new file mode 100644 (file)
index 0000000..e369771
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef DEMOSYS_H_
+#define DEMOSYS_H_
+
+#include "anim/track.h"
+
+struct demoscreen {
+       char *name;
+
+       struct anm_track track;
+
+       int (*init)(void);
+       void (*destroy)(void);
+       void (*reshape)(int x, int y);
+
+       void (*start)(void);
+       void (*stop)(void);
+
+       void (*update)(long tmsec);
+       void (*draw)(void);
+
+       void (*keyboard)(int key, int pressed);
+       void (*mouse)(int bn, int pressed, int x, int y);
+       void (*motion)(int x, int y);
+
+       struct demoscreen *next;
+};
+
+/* global demo state */
+int dsys_running;      /* run/stop state */
+int dsys_eof;          /* end of demo flag, seek back to reset */
+long dsys_time;                /* demo time in milliseconds */
+
+#define MAX_DSYS_SCREENS       64
+struct demoscreen *dsys_screens[MAX_DSYS_SCREENS];
+int dsys_num_screens;
+struct demoscreen *dsys_act_scr;       /* linked list of active screens */
+
+
+int dsys_init(const char *fname);
+void dsys_destroy(void);
+
+/* overrides the demo sequence, and runs a single screen */
+struct demoscreen *dsys_find_screen(const char *name);
+void dsys_run_screen(struct demoscreen *scr);
+
+void dsys_run(void);
+void dsys_stop(void);
+void dsys_seek_abs(long tm);
+void dsys_seek_rel(long dt);
+void dsys_seek_norm(float t);
+
+int dsys_add_screen(struct demoscreen *scr);
+
+#endif /* DEMOSYS_H_ */
index cdff0e5..a21cbca 100644 (file)
@@ -7,7 +7,9 @@
 
 static void display(void);
 static void keypress(unsigned char key, int x, int y);
+static void skeypress(int key, int x, int y);
 static void mouse(int bn, int st, int x, int y);
+static int translate_key(int key);
 
 static long start_time;
 
@@ -23,6 +25,7 @@ int main(int argc, char **argv)
        glutIdleFunc(glutPostRedisplay);
        glutReshapeFunc(demo_reshape);
        glutKeyboardFunc(keypress);
+       glutSpecialFunc(skeypress);
        glutMouseFunc(mouse);
        glutMotionFunc(demo_motion);
 
@@ -36,9 +39,14 @@ int main(int argc, char **argv)
        return 0;
 }
 
+void swap_buffers(void)
+{
+       glutSwapBuffers();
+}
+
 static void display(void)
 {
-       demo_time_msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
+       time_msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
 
        demo_display();
 
@@ -53,6 +61,13 @@ static void keypress(unsigned char key, int x, int y)
        demo_keyboard(key, 1);
 }
 
+static void skeypress(int key, int x, int y)
+{
+       if((key = translate_key(key))) {
+               demo_keyboard(key, 1);
+       }
+}
+
 static void mouse(int bn, int st, int x, int y)
 {
        int bidx = bn - GLUT_LEFT_BUTTON;
@@ -60,3 +75,27 @@ static void mouse(int bn, int st, int x, int y)
 
        demo_mouse(bidx, press, x, y);
 }
+
+static int translate_key(int key)
+{
+       if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
+               return key - GLUT_KEY_F1 + KEY_F1;
+       }
+       switch(key) {
+       case GLUT_KEY_LEFT:
+               return KEY_LEFT;
+       case GLUT_KEY_RIGHT:
+               return KEY_RIGHT;
+       case GLUT_KEY_UP:
+               return KEY_UP;
+       case GLUT_KEY_DOWN:
+               return KEY_DOWN;
+       case GLUT_KEY_PAGE_UP:
+               return KEY_PGUP;
+       case GLUT_KEY_PAGE_DOWN:
+               return KEY_PGDOWN;
+       default:
+               break;
+       }
+       return 0;
+}
diff --git a/src/scr/testa.c b/src/scr/testa.c
new file mode 100644 (file)
index 0000000..35e95d9
--- /dev/null
@@ -0,0 +1,3 @@
+#include "demosys.h"
+#include "opengl.h"
+