#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;
static int width, height;
+static long start_time;
+
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;
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:
exit(1);
}
demo_reshape(width, height);
+ start_time = (long)get_time_msec();
init_done = 1;
+ dsys_run();
break;
case APP_CMD_TERM_WINDOW:
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;
+}
#include "opengl.h"
#include "sanegl.h"
#include "assman.h"
+#include "demosys.h"
static unsigned int sdr_foo;
static unsigned int tex_logo;
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);
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;
+ }
}
#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);
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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
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;
glutIdleFunc(glutPostRedisplay);
glutReshapeFunc(demo_reshape);
glutKeyboardFunc(keypress);
+ glutSpecialFunc(skeypress);
glutMouseFunc(mouse);
glutMotionFunc(demo_motion);
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();
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;
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;
+}
--- /dev/null
+#include "demosys.h"
+#include "opengl.h"
+